iOS设备公网视频可播放但局域网视频无法播放问题求助
解决局域网AVPlayer无法播放视频的问题
看起来你遇到了公网视频能正常播放,但局域网视频死活播不了的情况,结合你的代码,我整理了几个最可能的原因和对应的解决办法:
1. 修复URL的编码错误
你的局域网URL里用了&,这是HTML转义后的&符号,但NSURL解析时会把它当成URL路径的一部分,导致服务器无法正确识别请求参数。直接把&换成原始的&即可:
self.url = [NSURL URLWithString:@"http://192.168.43.1:6080/?methodType=download&path=/Download/hi.mp4"];
如果你的URL是从HTML页面获取的,记得先做转义还原,也可以用CFURLCreateStringByReplacingPercentEscapesUsingEncoding工具方法处理。
2. 配置ATS允许HTTP局域网请求
iOS默认的ATS(App Transport Security)会限制非HTTPS的网络请求,哪怕是局域网地址也不例外。你需要在Info.plist里添加例外配置:
- 右键打开Info.plist,选择「Add Row」
- 添加
NSAppTransportSecurity,类型设为Dictionary - 在它下面添加
NSAllowsLocalNetworking,类型设为Boolean,值改为YES - 若测试阶段需要更宽松的设置(不推荐生产环境),可以添加
NSAllowsArbitraryLoads并设为YES
3. 检查局域网服务器的响应能力
AVPlayer对视频服务器有两个关键要求,很多自定义局域网服务器容易忽略:
- 服务器必须返回正确的视频MIME类型(比如
video/mp4),MIME类型错误会直接导致AVPlayer拒绝加载 - 服务器需要支持Byte-Range请求(也就是HTTP的
Range头),AVPlayer依赖这个实现分段加载。你可以用curl命令测试:
curl -I "http://192.168.43.1:6080/?methodType=download&path=/Download/hi.mp4" | grep Accept-Ranges
如果返回Accept-Ranges: bytes说明支持;如果没有,就得修改服务器代码来实现这个响应头。
4. 确保AVPlayer对象被正确持有
你的代码里AVPlayer *player是局部变量,而AVPlayerViewController对player是弱引用,方法执行完毕后player会被ARC自动释放,自然无法播放。把player改成类的属性来持有:
// 在ViewController的.h或.m的@interface里添加 @property (nonatomic, strong) AVPlayer *player; // 然后在playAction里修改: self.player = [AVPlayer playerWithURL:self.url]; playerVC.player = self.player;
5. 添加错误监听排查具体问题
如果以上步骤都没用,给AVPlayer加个状态监听,看看具体的错误信息:
[self.player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; // 实现观察者方法 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { if ([keyPath isEqualToString:@"status"]) { AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue]; if (status == AVPlayerStatusFailed) { NSError *error = self.player.error; NSLog(@"播放错误:%@", error.localizedDescription); } else if (status == AVPlayerStatusReadyToPlay) { NSLog(@"视频已准备好播放"); } } }
记得在dealloc里移除观察者,避免内存泄漏:
- (void)dealloc { [self.player removeObserver:self forKeyPath:@"status"]; }
按这几步排查下来,应该能解决你的局域网视频播放问题。
内容的提问来源于stack exchange,提问作者Yt Lan




