ffmpeg转码会声会影编辑的视频失败问题解决

刚接触视频转码技术,老菜鸟上路,将问题和解决方案一一记录在案。


问题场景:

编辑人员上传了一个使用会声会影软件编辑过的视频,转码后出现部分视频丢失的问题。转码后的视频声音和片长与原视频一样,声音可以正常播放,但是视频损坏丢失了部分,播放到一半以后就只有声音,没有了画面。


排查过程:


1(此部分后来被证实猜测错误,急切希望解决问题的可以略过此部分) 

猜测mp4文件在编辑过程中被损坏,学习研究mp4视频容器,希望能定位出来文件异常的位置,搜集的一些有参考价值的资料:

MP4文件格式: http://www.52rd.com/Blog/wqyuwss/559/

MP4文件格式的解析: http://www.cnblogs.com/haibindev/archive/2011/10/17/2214518.html

MP4文件格式解析系列文章: http://blog.sina.com.cn/s/articlelist_1224293203_10_1.html

一个windows下直观好用的MP4文件解析器MP4Reader: http://www.thinmultimedia.com/products/MP4Reader_download.html

很悲剧的是,调研分析后发现从header里分析的信息里无法简单看出视频异常,当然也许是因为调研的还不够深入。通过这些调研,收获如下信息:

  • MP4文件帧可以不按时间轴顺序存储,需要通过header里的信息去定位chunk的偏移量,读出连续的sample进行播放。
  • MP4容器貌似可以通过直接修改header里的timescale、duration、rate参数实现视频的倍速播放,这个后续再研究一下,正好有这个需求。


2 从FFmpeg转码命令入手,特别是查看转码过程中是否有异常输出,看是否可以通过异常找到解决方案

调研了一下FFmpeg的使用,找到这个方式输出FFmpeg检查视频的debug信息:

ffmpeg -v debug -i 348.mp4 -f null - 2>error.log

打开error.log查看后发现中间输出了大段的drop信息:

Application provided invalid, non monotonically increasing dts to muxer in stream 1: -3600 >= -3600
*** drop!
    Last message repeated 189 times
frame= 7999 fps=529 q=0.0 size=N/A time=00:05:19.96 bitrate=N/A dup=0 drop=190    
*** drop!
    Last message repeated 239 times
frame= 7999 fps=512 q=0.0 size=N/A time=00:05:19.96 bitrate=N/A dup=0 drop=430    
*** drop!
    Last message repeated 263 times
frame= 7999 fps=496 q=0.0 size=N/A time=00:05:19.96 bitrate=N/A dup=0 drop=694    
*** drop!
    Last message repeated 263 times
frame= 7999 fps=480 q=0.0 size=N/A time=00:05:19.96 bitrate=N/A dup=0 drop=958    
*** drop!

google了一下“ bitrate=N/A dup=0 drop= ”,查到这篇文章:

 FFmpeg drops frames when encoding a png image sequence into an x264 mp4 video

看到这篇文章就感觉有谱了,因为我了解到视频里被插入了静态的图片作为画面,同是视频是多个视频剪辑拼接起来的,很可能导致视频申明的帧率和中间部分视频的实际帧率不同。

查看了error.log中原视频的帧率 :25 fps

Duration: 00:11:51.24, start: 0.040000, bitrate: 4708 kb/s
    Stream #0:0(eng), 125, 1/30000: Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1/50, 4576 kb/s, 25 fps, 25 tbr, 30k tbn, 50 tbc

按照文章中的方法测试一下,强制申明转码时读取原视频的时候以-r 25的方式进行读取,输出也是相同-r 25 


ffmpeg -r 25 -i 348.mp4 -vcodec libx264 -s 640x360 -aspect 640:360 -f mp4 -r 25 out.mp4


转码成功!问题解决,视频不再丢失,视频中间编辑插入的静态图片也可以正常显示。


事后推测了一下原因,有待进一步确认,欢迎大拿解惑:

1 视频中插入了静态图片,静态图片存储的帧率很可能是1,或者至少也是和原视频25帧是不相同的。

2 视频是多个视频拼接的,不同的视频之间也很可能存在帧率不相同,所以导致以一个动态的帧率去读取视频后按统一帧率输出的时候出现问题。

后续再继续深入研究MP4的视频格式,以及视频信息是如果存储的,这里面要学习的东西太多了。




你可能感兴趣的:(FFmpeg)