You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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是局部变量,而AVPlayerViewControllerplayer是弱引用,方法执行完毕后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

火山引擎 最新活动