Flutter iOS端video_player播放m3u8与mp4视频宽高比不一致
iOS端HLS视频宽高比异常排查解决思路
该异常是iOS端AVPlayer与Android端ExoPlayer对HLS流元数据解析逻辑差异导致的,和video_player插件版本无直接关联,升级插件版本无法修复,可按以下步骤排查:
- 先校验源m3u8流的元数据准确性
用ffprobe工具拉取出问题视频的m3u8地址元数据,执行命令:ffprobe -v error -show_streams -show_format 替换为出问题的m3u8播放地址
重点核对三个字段:width/height数值是否和原mp4文件分辨率一致,sample_aspect_ratio(采样宽高比)是否为1:1,rotation旋转角度是否和原视频一致。如果出现SAR非1:1、分辨率标注错误、旋转参数缺失的情况,就是转码环节写入HLS元数据出错——iOS端AVPlayer会严格按照清单里标注的元数据渲染画面,不会像Android端ExoPlayer那样自动根据实际视频帧修正参数偏差,就会出现宽高比错乱、画面放大裁切的问题。 - 排查Cloudflare Stream转码配置bug
Cloudflare Stream部分旧转码模板处理带旋转元数据的竖屏mp4时存在已知问题:原mp4的旋转参数写在文件moov原子中,转m3u8时没有把旋转参数正确应用到视频帧,反而在HLS清单里写入了错误的分辨率、SAR值。可以针对出问题的视频重新触发转码,转码时强制关闭自动裁剪、自动横竖屏适配开关,手动指定输出分辨率和原视频一致,转码完成后重新测试。 - 客户端侧临时适配方案(如果暂时无法调整源站转码配置)
video_player插件在iOS端会直接透传AVPlayer返回的错误宽高比,不要直接使用controller.value.aspectRatio做布局计算,可选择以下方案修复:- 业务侧提前存储所有视频的正确宽高比,iOS端渲染播放器时直接使用业务侧存储的固定值,跳过插件返回的错误参数
- 无法提前获取宽高比的场景,可在视频首帧渲染完成后,读取纹理实际输出的宽高比,手动覆写播放器布局的比例参数
- 简单临时规避:在iOS原生层调整AVPlayerLayer的渲染模式,强制将
videoGravity属性设为resizeAspect,避免默认值触发画面裁切放大
- 校验分片编码兼容性
检查出问题的m3u8分片编码参数:如果使用了H.264 High 5.0以上级别、或者开启了B帧,iOS14及以下版本的系统解析时会错误识别分辨率,转码时将H.264 profile调整为Main级别、关闭B帧即可修复。
之前查到的Flutter相关issue中提到的版本修复,仅针对本地视频文件的元数据读取偏差,对HLS网络流场景不生效——HLS流的元数据是由系统播放器直接读取解析的,插件层仅做参数透传,没有修正逻辑,因此升级插件版本无法解决这类问题。
内容的提问来源于stack exchange,提问作者user12051965
相关产品推荐
相关产品推荐

