为啥 .ts 格式的 ffmpeg 开始时间非零?

Posted

技术标签:

【中文标题】为啥 .ts 格式的 ffmpeg 开始时间非零?【英文标题】:Why is ffmpeg start time non-zero in .ts format?为什么 .ts 格式的 ffmpeg 开始时间非零? 【发布时间】:2014-02-12 12:04:12 【问题描述】:

我正在使用 ffmpeg 将视频转码为 .ts 格式,并且在输出文件中出现意外的开始时间。

为了简化事情,我从一个不错的简单 AVI 文件(无音频)开始:

ffmpeg -i in.avi 
...
Input #0, avi, from 'in.avi':
  Metadata:
    encoder         : Lavf55.25.100
  Duration: 00:00:05.00, start: 0.000000, bitrate: 448 kb/s
    Stream #0:0: Video: mpeg4 (Simple Profile) (FMP4 / 0x34504D46), yuv420p, 480x270 [SAR 1:1 DAR 16:9], 24 tbr, 24 tbn, 24 tbc

Duration=5s,startTime=0s,符合预期。

但是,如果我转码为 .ts 文件,无需自定义:

ffmpeg -i in.avi -y out.ts
...
Input #0, avi, from 'in.avi':
  Metadata:
    encoder         : Lavf55.25.100
  Duration: 00:00:05.00, start: 0.000000, bitrate: 448 kb/s
    Stream #0:0: Video: mpeg4 (Simple Profile) (FMP4 / 0x34504D46), yuv420p, 480x270 [SAR 1:1 DAR 16:9], 24 tbr, 24 tbn, 24 tbc
Output #0, mpegts, to 'out.ts':
  Metadata:
    encoder         : Lavf55.25.100
    Stream #0:0: Video: mpeg2video, yuv420p, 480x270 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 90k tbn, 24 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg4 -> mpeg2video)
Press [q] to stop, [?] for help
frame=  120 fps=0.0 q=31.0 Lsize=     315kB time=00:00:04.95 bitrate= 519.9kbits/s dup=1 drop=0    
video:277kB audio:0kB subtitle:0 global headers:0kB muxing overhead 13.491544%

然后我得到一个很奇怪的参数(Duration=4:96s,startTime=1.441667):

ffmpeg -i out.ts
...
Input #0, mpegts, from 'out.ts':
  Duration: 00:00:04.96, start: 1.441667, bitrate: 519 kb/s
  Program 1 
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 480x270 [SAR 1:1 DAR 16:9], max. 104857 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc

现在,我几乎可以理解为什么转码可能会丢失几帧,这解释了持续时间,但我不明白为什么开始时间应该与 AVI 文件的开始时间有任何不同。

我尝试过转码为 .mp4、.webm 和 .mov,在每种情况下我们都得到了 0.0 秒的“正确”开始时间。任何人都可以帮助解释为什么 .ts 文件的行为不同吗?

提前致谢!

(ffmpeg版本信息:)

ffmpeg version N-60031-ga459891 Copyright (c) 2000-2014 the FFmpeg developers
  built on Jan 21 2014 05:31:54 with gcc 4.6 (Debian 4.6.3-1)
  configuration: --prefix=/root/ffmpeg-static/64bit --extra-cflags='-I/root/ffmpeg-static/64bit/include -static' --extra-ldflags='-L/root/ffmpeg-static/64bit/lib -static' --extra-libs='-lxml2 -lexpat -lfreetype' --enable-static --disable-shared --disable-ffserver --disable-doc --enable-bzlib --enable-zlib --enable-postproc --enable-runtime-cpudetect --enable-libx264 --enable-gpl --enable-libtheora --enable-libvorbis --enable-libmp3lame --enable-gray --enable-libass --enable-libfreetype --enable-libopenjpeg --enable-libspeex --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-version3 --enable-libvpx
  libavutil      52. 63.100 / 52. 63.100
  libavcodec     55. 48.102 / 55. 48.102
  libavformat    55. 25.100 / 55. 25.100
  libavdevice    55.  5.102 / 55.  5.102
  libavfilter     4.  1.100 /  4.  1.100
  libswscale      2.  5.101 /  2.  5.101
  libswresample   0. 17.104 /  0. 17.104
  libpostproc    52.  3.100 / 52.  3.100

【问题讨论】:

【参考方案1】:

当复用到mpegts 时,ffmpeg 会对生成的时间戳应用默认延迟。我认为这是为了处理现场情况,确保生成的视频具有准确的时间戳很重要。

默认延迟为 0.7 秒(您可以在 ffmpeg_opt.c 中看到),但对于 mpegts,它会乘以 2。为什么?我不完全确定。我已经将此追溯到大约 8 年前与添加对 VBR 多路复用的支持有关的提交,但我无法确定根本原因是什么。

无论如何,您最可能想要做的是通过在命令行中添加-muxdelay 0 将多路复用器延迟设置为0。这样,您在 .ts 文件中的开始时间与在 .mp4、.webm 或 .mov 文件中的开始时间相同。

【讨论】:

以上是关于为啥 .ts 格式的 ffmpeg 开始时间非零?的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg解析TS流(转)

FFmpeg 细碎知识整理

使用 FFMPEG 高效连接和交叉淡化 .ts 文件

ffmpeg 合并文件

FFmpeg音视频拼接命令

ffmpeg转码重置文件的开始时间