基本知识
MediaCodec的相关数据时间单位为(纳秒/1000),类似610,729,613,772, 倒数第7位代表秒级
MediaMuxer.writeSampleData Failed
描述:写入数据失败
常见原因
这类错误基本和时间戳有关
时间戳倒退问题
现象 | 解决 |
---|---|
吐出时间戳倒退 | 丢弃异常帧(经测试无影响,且量级不大) |
吐出时间戳相等 | 丢弃异常帧(有些机器能接受相等的数据,为了通用性还是丢弃) |
此类问题出现一般在异常后的一帧写入报错
分析问题需要区分音频视频各自的时间戳查看
示例
代码语言:javascript复制第二行ts小于第一行的ts,第三行正常
writeSampleData size = 186, ts = 621441165854
writeSampleData size = 186, ts = 621441065854
writeSampleData size = 185, ts = 621441131957
这是错误的音频写入日志,writeSampleData Failed会在第三行写入时候才会爆出来。所以分析此类问题可能需要往前多找几帧,出现问题的帧数据不一定是当前的帧
音视频录制合成后音频速率加快
MediaCodec的工作原理
两个队列管理入队出队,原始数据给到input,通过output吐出来
问题原因
如果input和output在不同线程,因为两边处理速率不一致,会导致input数据来不及消费,导致部分原始数据被覆盖(丢弃),最终形成的现象就是音频会加快,鬼畜。视频丢弃就会卡顿。
解决方案
- 使用队列保存原始数据,一般使用HandlerThread的Looper机制保存消息
- 在同一个线程做input,output,每一次input等到output完成再进行下一次input,保证每一帧数据消费完
音视频录制后卡顿
这类问题一般两种情况,时间戳不对,部分数据帧被都丢弃
MediaMuxer.Start时机不对
解决方案
建议时机:dequeueOutputBuffer返回MediaCodec.INFO_OUTPUT_FORMAT_CHANGED更新MediaMuxer.addTrack, 所有的track完成之后再触发start。
音频:dequeueOutputBuffer返回MediaCodec.INFO_OUTPUT_FORMAT_CHANGED触发新MediaMuxer.addTrack 视频:dequeueOutputBuffer返回MediaCodec.INFO_OUTPUT_FORMAT_CHANGED触发新MediaMuxer.addTrack MediaMuxer:所有track add完成之后触发start
问题示例
- 如果提前start,在触发addTrack会爆addTrack ERROR
- 如果提前addTrack && start,录制视频会卡顿
兼容性问题导致数据被丢弃
问题现象
有些机型,音频 or 视频初始化很慢,时间错开,导致另一个通道数据到达之后,因为MediaMuxer没有start,所以这部分数据默认被丢弃了。
解决方案
- 添加队列保存提前到来的数据,当MediaMuxer.Start之后统一写进去
- 写入缓存时候需要加锁,防止新的数据进来导致时序不对,就会出现上面MediaMuxer.writeSampleData Failed
MediaMuxer.stop: Failed to stop the muxer
一般出现这类问题的场景如下,需要做逻辑保护
- 多track场景需要等多个MediaCodec都释放之后触发
- 多track场景某一个track一直不写数据
- 录制快速停止场景,某些track对应的MediaCodec还没初始化完成