iOS AVPlayer无法播放H.263编码.mov文件及播放能力检测咨询
问题产生原因
AVFoundation公开框架中的AVPlayer对编码格式的支持范围,和系统内置相册应用不一致:iOS 相册内置了老旧编码的兼容解码逻辑,而AVPlayer原生仅支持苹果官方公开的主流编码规范,H.263 视频编码、AMR 窄带音频编码都不在AVPlayer的原生硬解码支持列表中,因此会出现初始化无报错、播放时无画面无声音的情况。AVAsset.isPlayable的判断逻辑仅校验文件容器结构合法性、基础元数据完整性,不会深度检测音视频轨道的编码格式是否匹配AVPlayer的实际解码能力,因此会出现返回true但实际无法播放的偏差。
不可播放文件检测方案
你可以通过两种方案实现更准确的播放能力校验:
方案1:预校验音视频轨道编码格式
在初始化 AVPlayer 相关实例前,先读取 AVAsset 的音视频轨道编码标识,通过白名单或者黑名单过滤不支持的格式,参考代码如下:
AVAsset *asset = [AVAsset assetWithURL:videoFileURL]; BOOL videoCodecSupported = NO; BOOL audioCodecSupported = NO; // 校验视频编码 NSArray *videoTracks = [asset tracksWithMediaType:AVMediaTypeVideo]; if (videoTracks.count > 0) { AVAssetTrack *track = videoTracks.firstObject; CMFormatDescriptionRef formatDesc = (__bridge CMFormatDescriptionRef)track.formatDescriptions.firstObject; FourCharCode videoCodec = CMFormatDescriptionGetMediaSubType(formatDesc); // 按需添加支持的视频编码,比如H.264、HEVC等 if (videoCodec == kCMVideoCodecType_H264 || videoCodec == kCMVideoCodecType_HEVC) { videoCodecSupported = YES; } // 可直接标记不支持的编码,比如H.263 if (videoCodec == kCMVideoCodecType_H263) { videoCodecSupported = NO; } } // 校验音频编码 NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio]; if (audioTracks.count > 0) { AVAssetTrack *track = audioTracks.firstObject; CMFormatDescriptionRef formatDesc = (__bridge CMFormatDescriptionRef)track.formatDescriptions.firstObject; FourCharCode audioCodec = CMFormatDescriptionGetMediaSubType(formatDesc); // 按需添加支持的音频编码,比如AAC if (audioCodec == kAudioFormatMPEG4AAC) { audioCodecSupported = YES; } // 可直接标记不支持的编码,比如AMR窄带 if (audioCodec == kAudioFormatAMR) { audioCodecSupported = NO; } } BOOL avPlayerCanPlay = videoCodecSupported && audioCodecSupported;
Swift 实现逻辑和上述代码完全一致,只需对应替换 API 写法即可。
方案2:预加载校验实际可渲染性
如果不想维护固定的编码黑白名单,可以通过预加载的方式校验实际播放能力:
- 初始化
AVPlayerItem后,添加对其status属性的 KVO 监听 - 当状态变为
AVPlayerItemStatusReadyToPlay后,调用AVPlayer的精准 seek 方法跳转到第0帧 - 通过
AVPlayerItemVideoOutput尝试获取首帧的像素缓冲区,或者尝试对AVPlayerLayer做截图,如果能正常拿到像素数据/截图则判定为可播放,否则判定为不可播放。
扩展说明
如果业务需要兼容 H.263 这类老旧编码的视频,可以选择集成 FFmpeg 软解码方案,替代原生 AVPlayer 实现播放。
内容的提问来源于stack exchange,提问作者A. Claesson
相关产品推荐
相关产品推荐

