一个音画不同步的问题分析
一、背景
某个视频播放过程中出现音频超前播放,而且越播放越不同步。视频文件的参数如下:
项目采用ffms2+avisynth的框架
二、分析过程(ffms2)
音频比视频短
1、 既然是音频播放超前,那么要么是画面播放太慢了,要么是音频播快了。首先分析了视频播放流程,确定了和视频丢帧没关系,即便丢帧再快,视频也都跟不上音频
2、接下来就重点分析音频了,用ffprobe从视频文件中抓取到音频包,大概内容如下
3、从2中可以看到,每个音频包的采样点个数,即nb_samples
都是1024,pkt_duration
也大部分都是1024,但是存在个别音频包未4016或者其他值
4、查阅资料,pkt_duration
为单帧音频播放的时间,单位是1/44100 s。所以这个文件的播放时间不能由采样点来决定,而应该结合pkt_duration
来决定
5、再分析解析文件时长的方式,在写index的过程找到了这行代码
stream.Write(f.SampleCount - prev.SampleCount);
其中,这里面的SampleCount
来自以下函数
uint32_t FFMS_Indexer::IndexAudioPacket
该函数返回一个SampleCount
供写入index文件,关键实现如下
Context.CurrentSample += DecodeFrame->nb_samples;
int64_t StartSample = Context.CurrentSample;
return static_cast<uint32_t>(Context.CurrentSample - StartSample);
6、于是,在FFaudiosource
插件中读取到音频总帧数为nb_samples
* 帧个数,算出来是1024 * 118856 = 121708544,这就是总采样点个数,再除以采样率44100,算出来结果是2759s,而视频的时长是2783s。这就是为什么把音频剥离出来比视频要短的原因
PTS设置逻辑中的问题
7、用雷晓华的ffplaymfc播放该视频,然后把音频的pts打印出来,中间有很多不是以1024为偏移的采样点,播放到结尾处,pts为122770244,换算到秒是2783s。而medialib里面播放到音频结尾,pts为121627800,换算到秒是2759s
8、为了跟踪ffmpeg自带的pts设置机制,网上找到read_packet调用流程如下
https://www.jianshu.com/p/f78defe0e485?utm_source=desktop&utm_medium=timeline
9、ffmpeg自带的read_packet
函数在MOV.c的mov_read_packet
中,音视频的pts逻辑是同一套。
10、medialib的read_packet
函数为avisynth_read_packet
,自己区分了音视频,然后分别从avisynth中获取数据。在音频的读取函数avisynth_read_packet_audio
中,pts设置的逻辑为:以1/framrate的时长对应的音频采样点个数为音频的pts,因为没有考虑单帧音频的pkt_duration
,所以这种设置逻辑肯定肯定会不准的
如何解决
11、从音频的包数据中可以发现有个参数为pkt_pts
,经过核对,这个pts时间就是音频准确的pts时间。在avisynth_read_packet_audio
函数中设置pts的语句为:pkt->pts = n;
如果能将这个n换成上面说的pkt_pts,那么就万事大吉了。所以,在这里有两个设想中的方案:
a.想办法在avisynth_read_packet_audio
中获取到pkt_pts
,然后设置到输出pkt的参数中,即pkt->pts = pkt_pts;
b.不改变pts,在avisynth_read_packet_audio
中获取数据的函数avs_get_audio
中将数据替换为指定pts附近的数据
12、方法a的实现看似简单,但是改动很大,因此决定从方案b的角度去摸索修复方法。通过调试发现,在写index的时候,index中的FrameInfo::PTS
就是pkt_pts
,然后把当前帧的PTS和上一帧做减法,得到差值写入index文件,在读index的时候,会把这个差值和累加,得到的PTS值相当于pkt_pts
三、结论
从步骤12中知道原始文件的正确pts值是可以获取到的,因此一定是有办法利用正确的pts值让输出数据正确,从而解决音画不同步的问题。只不过暂时没有时间去实施。
四、展望
----未完待续
一个音画不同步的问题分析相关推荐
- 记录一次Android视频播放音画不同步问题的定位及分析
1.何为音画不同步 音画不同步很简单就是视频播放过程中声音和画面出现的时间点不一致,滞后或者提前. 2.音画不同步问题分析思路 2.1.音画不同步问题的证明 对于滞后或者提前很多的音画不同步可以直接认 ...
- 斗鱼html5插件音画不同步,音画不同步在直播中怎么解决?看这篇文章就够了!...
原标题:音画不同步在直播中怎么解决?看这篇文章就够了! 什么是音画不同步? 很容易判断,就是画面和声音不匹配. 为什么会音画不同步? 首先我们要明白一个概念,虽然人的肉眼很容易辨别音画是否同步的,但是 ...
- 记一次奇怪的音画不同步问题(ts转mp4)
一.缘起 最近在网上下载了一个 ts 格式的视频文件,帧率模式为可变帧率,使用播放器播放没有任何问题,传到 bilibili 后出现音画不同步的现象,具体表现为声音比画面快几秒.起初以为是 ts 格式 ...
- 直播疑难杂症排查(5)— 音画不同步
本文是 <直播疑难杂症排查>系列的第五篇文章,我们重点来看看直播中常见的音画不同步问题. 1. 音画不同步的表现 很容易判断,就是画面和声音不匹配. 2. 音画同步的基础概念 首先我们要明 ...
- java MulticastSocket实现传输H.264+AAC的组播RTSP服务(音画不同步)
传输H.264+AAC的组播RTSP服务(音画不同步) 参考:从零开始写一个RTSP服务器(八)一个多播的RTSP服务器 h264文件:test.h264文件地址 aac文件:test.aac文件地址 ...
- 斗鱼html5插件音画不同步,直播开发完成后关于音画不同步的原因及办法
如果说直播过程中出现卡顿.延时是很正常的,那么唯有音画不同步是最令人难以忍受的.对于直播开发完成之后出现音画不同步的现象,也是非常令人头疼的.我们可以从以下几个方面来简单分析一下,音画不同步现象产生的 ...
- 如何解决在PotPlayer中看视频音画不同步的问题(C#视频可用)
今天在学习C#视频的过程总遇到了音画不同步的问题,我使用的播放器是PotPlayer(功能强大的播放器,没有用过的同学可以尝试使用一下).老师说话的声音与鼠标操作的画面相差了数秒之久,非常影响学习体验 ...
- PotPlayer中看视频音画不同步的问题
今天在学习C#视频的过程总遇到了音画不同步的问题,我使用的播放器是PotPlayer(功能强大的播放器,没有用过的同学可以尝试使用一下).老师说话的声音与鼠标操作的画面相差了数秒之久,非常影响学习体验 ...
- Bento4库使用(2):生成fmp4文件音画不同步
Bento4库使用(2):生成fmp4文件音画不同步 问题描述 原因 解决 问题描述 使用Bento4库生成的fmp4文件音画不同步. 原因 fmp4文件每一个moof仅存放一个关键帧,即moof的第 ...
最新文章
- 将 SqlDataReader 类用于快速只进数据游标
- excel增加上一列的数值(日期)
- 【赠书】21世纪科技竞争的核心是超级智能的控制权
- Office 365系列之四:添加自定义域
- rhel系统启动过程_Linux 的启动流程
- mysql 查询两表 两列 比较大小写_mysql 查询表中列的数据不区分大小写的解决
- 帧同步和状态同步(一)
- linux下日志晒选打包,Linux 文件日志筛选操作
- package.json说明
- js的tree数组对象扁平化思否_JS专题之数组展开
- 【NLP】文本情感分类
- ccboot最新服务器配置,使用CCBoot如何优化服务器和客户端网卡
- GC overhead limit exceeded
- RT-Thread ENV工具 pkgs --upgrade 报错:open .config failed
- nginx日志格式分析
- 台式计算机突然连接不到网络,电脑突然网络感叹号导致不能上网的解决方法
- Scala样例类(case class)
- react-redux——使用redux——使用react-redux这个扩展简化操作
- BUUCTF WEB [BSidesCF 2020]Had a bad day
- Scratch冰雹猜想