引用播放器专栏文章结合央视频播放器TVKplayer对常见播放问题分析
https://zhuanlan.zhihu.com/jhuster
播放失败
-
播放失败表现
- 界面一直显示加载中,或者提示播放失败的错误
- 播放画面卡死不动,但ui按钮可点击
- 有声音没画面,或有画面没有声音
-
常见原因
- 没有网络
- 一般会有网络异常提示
- 域名解析失败
- 遇到这类错误,一般可以通过 ping 一下域名试试,看看是否可以 ping 通,如果 ping 不通,则可能要检查下域名解析的配置了
- 服务器连接失败
- 可抓包看是否有播放器调度的请求
- 请求的资源不存在
- 一般会报错404
- 视频格式不支持
- 包含网络协议、编码格式、封装格式
- 不同的格式需要播放器专门添加支持
- 没有网络
-
央视频播放失败时会上报错误码,错误码可在tvkplayer公众号查询
只有音频没有视频,或只有视频没有音频
- 原因
- 音频/视频的编码格式不支持,导致解码失败
- 音频/视频的数据内容异常,导致解码失败
- 基于 ffmpeg 的播放器的 probesize 设置太小,导致解析码流信息不足
- 码流/文件本身的前半段只有音频没有视频,或者只有视频没有音频
播放卡顿
-
播放卡顿的表现-播放器渲染的帧率太低
- 频繁出现缓冲
- 播放不够流畅,画面一卡一卡的
-
常见原因
- 网络带宽不足
- 包含推流、cdn分发、拉流等端
- 播放设备性能不足
- 跟播放器类型、解码器类型有关
- 跟清晰度码率有关
- 目前央视频系统播放器会经常偶现卡顿,原因是有些视频源,系统播放器不兼容
- 视频流时间戳问题
- 推流或转码处理后,没有处理时间戳就会有该问题
- 由于音画同步的原理就是使用时间戳,因此有可能也会导致音画不同步问题
- 网络带宽不足
首开慢
-
首开是指从点击播放到视频第一帧渲染到端上的时间
-
表现
- 首次加载播放时视频需要过一会才能显示画面
-
原因
- 获取播放地址的时机太慢
- 央视频点播会预加载其他视频
- 时机是点击播放后,端上告诉播放器视频id,由播放器或下载组件,去播放调度接口进行加载
- dns解析慢
- 播放策略原因
- 播放缓冲等
- 播放参数配置
- 服务端线路问题
- 冷热流、边缘节点的TTL、服务器的响应速度等
- 例如央视频线上直播会先预热,能减少首开时间
- 获取播放地址的时机太慢
直播延时高
-
延时的测量
- 推流端和拉流端对着同一个时钟,用播放端显示的时间键入推流端显示的时间
-
延时高问题分析
- 网络传输延时
- 业务代码中的缓冲区
- 协议延时
音画不同步
- 播放器是根据音频文件和视频文件携带的时间戳信息实现音画同步,大部分音画不同步都是由生产端导致的
- 原因
- 采集源距离太远
- 声音和画面的时间戳不一致
- 采集设备内部问题
- 时间戳没有在采集的时候获取
- 时间戳出现回退或者絮乱
- 播放端性能问题
- 比如低端机型软解 1080P 的高清码流,会存在解码不够及时的问题,导致部分视频解码完成后,已经远慢于当前的音频时钟,只能丢弃,从而导致画面更新不及时,与正在播放的音频无法匹配上,从而产生音画不同步的现象。
- 解决方案:使用硬解,选择较低清的码流,增大播放缓冲,等等。
- 采集源距离太远
马赛克严重
- 马赛克主要指画面中出现多处类似小方块的图像,导致画面的局部或者整体看不清楚的情况
- 原因
- 视频编码参数配置问题
- 视频的画质,是由它的编码质量决定的,压缩得越 “厉害”,画质损失就越多,马赛克就越严重
- 编码器最重要的五个参数:画质级别、码率、帧率、GOP 大小、码控方式
- 画质级别:H.264 有四种画质级别,Baseline profile,Extended profile,Main profile,High profile,级别越高,压缩的效果越好,但算法复杂度更高,导致功耗也更高。
- 码率:决定了视频被压缩的程度,码率越低,丢失的信息也就越多,画质也就越差。但是,带来的好处是占用的网络带宽会比较小,容易在互联网上传输,不容易出现卡顿。
- 帧率:决定了视频的流畅性,帧率越高,视频越流畅,但每秒钟编码器要处理的数据量也就越大,同等码率下压缩出来的视频质量就越差。
- GOP 大小:决定了视频的延时,GOP 越小,延时就越小,但 GOP 小带来的问题是关键帧数量多,数据量变大,因此,同等码率下压缩出来的视频质量就会越差。
- 码控方式:一般编码器都有固定码率(CBR) 和 动态码率(VBR) 两种码控方式,前者是指码率优先,为了保证码率尽可能稳定,会主动降低画质,因此容易出现马赛克,后者是指画质优先,会优先保证画质,减少马赛克,但码率会浮动很大
- 还有一个重要的因素,就是编码器本身的实现质量,软编一般可以保证在不同手机上效果一致,而硬编则完全依赖手机所使用的硬件平台了。
- 推荐的编码器参数配置
- 一般直播场景中,考虑到手机性能和功耗,一般画质级别采用的是 Baseline profile,GOP 通常设置为 1~3s,帧率一般在 15~24 帧,而码率的配置,则需要根据推流的分辨率来决定,推荐的分辨率和码率配置关系如下图所示(来自:《Video Encoding Settings for H.264 Excellence》):
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x6wMtP0I-1691579860542)(evernotecid://0463BFB8-84EE-42E6-B8AA-9B86C239AA24/appyinxiangcom/18328752/ENResource/p265)]
- 关于视频编码与马赛克的关系,我们只需要记住一个原则:送入编码器的数据量越大,编码压缩得越 “厉害”,丢失的图像信息也就越多,数据解码后的产生马赛克也就越 “厉害”
- 图像尺寸问题
- 当摄像头采集的视频尺寸小于推流尺寸时,会进行“拉伸”处理,再送入编码器中编码压缩,很容易产生模糊和马赛克
- 关键帧丢失
- 由于视频流中丢失了关键帧,导致播放器解码后花屏
- 视频编码参数配置问题
黑屏、花屏、闪屏问题
-
这些问题有可能是推流端的问题,也有可能是播放器的问题,首先要先用别的播放器排查下,例如浏览器、VLC、ffplay等
-
黑屏原因
- 推流端摄像头采集问题
- 推流端编码失败
- 视频解码失败
- 视频编解码格式不支持
- 播放器硬解/软解失败
- 视频数据内容错误
- 由于央视频的端上播放器兜底图就是黑屏画面,所以当端上没有调起播放器、没有view、断流等情况时也会展示黑屏
-
播放花屏/绿屏原因
- 丢失参考帧导致的
- 一般 H.264 码流有 I、B、P 三种帧类型,I 帧是关键帧,B 帧是双向预测内插编码帧,P 帧是前向预测编码帧。
- I 帧由于是帧内压缩,因此可以独立解码播放,而 B 帧,一旦丢失了 I 帧或者后面的 P 帧,则会解码失败,而 P 帧一旦丢失了前面的 I/B/P 帧,也会导致解码失败。
- 对于丢失了参考帧而导致的解码失败,一般就会出现花屏的现象,花屏的严重程度依赖于丢失的参考帧对即将解码的帧的重要程度。
- 播放器没有从关键帧开始解码
- 原理依然如上面所述,如果不从关键帧开始解码,则必然会由于丢失了参考信息而导致解码花屏。
- 因此,播放器,无论是首播,还是断网重连后,都应该判断第一帧视频是否是关键帧,如果不是,则应该等到第一个关键帧到达之后再送入解码器。
- 基于 ffmpeg 的播放器,如何判断关键帧,可以参考我的这篇文章:《FFMPEG Tips (3) 如何读取每一帧的信息》
- 码率中视频尺寸发生变化
- 播放器需要实时监测,如果发现视频尺寸发生了变化,需要重置解码器及相关逻辑,否则容易出现解码花屏或者出现内存越界等异常
- 硬编硬解的兼容性问题
- 推流端图像尺寸和格式处理不当
- 丢失参考帧导致的
-
视频闪屏原因-播放过程中会闪现其他画面
- 播放器缓冲机制原因
- 推流端的原因
播放器杂音、噪音、回声问题
- 原因
- 参数配置问题
- 详见 Android音频开发基础知识
- 如 采样率、位宽、声道数等
- 代码层面的原因
- 网络波动
- 回声消除
- 混音越界
- 参数配置问题
拖动不准
- 拖动的原理
- 视频时由一系列图像帧组成的,每一帧都有对应的时间戳,拖动就是告诉播放器一个时间戳,有它直接跳转到指定的这一帧开始播放
- 拖动到的时间点 = (进度条的progress / 进度条最大值100)* 视频总时长
- seek不准原因
- 关键帧间隔太大
- 由于解码器必须从I帧开始解码,才不会出现花屏现象,因此播放器通常会寻找离seekTo视频帧最近的一个关键帧,从该关键帧开始解码播放
- 这也是央视频seek不准的最根本原因
- 直播丢帧
- 丢帧的请求多发生在直播场景,由于主播端的网络抖动或者内存不足,导致不得不被迫丢掉一些视频帧,而为了保证客户端解码后不出现花屏,丢帧往往伴随着一整个 GOP 的丢弃。
- 当 GOP 丢失后,部分关键帧的间隔时间点就会变得更大了,从而导致拖动不准。
- 为了避免这种情况,建议推流端开启动态码率,在网络不好的时候,主动降低码率,快速发送掉缓冲区中累积的视频帧,从而减少丢帧的情况发生。
- 关键帧间隔太大