FFmpeg 提取剪辑 - 流帧速率与容器帧速率不同(x264,aac)

fid*_*eli 8 video h.264 ffmpeg macos

总结
H.264 视频似乎具有非常高的帧速率,需要一个缩放因子来应用于我试图提取的视频持续时间(低 900 倍)。

正文
我正在尝试从我拥有的 MP4 格式(使用Handbrake创建)的电影中提取剪辑。在尝试了 mencoder 和 VLC 之后,我决定试一试 FFmpeg,因为它在复制编解码器方面是最不麻烦的。也就是说,与 mencoder 和 VLC 相比,生成的文件仍然可以在 QuickTime 中播放(我知道 Perian 等,我只是想了解所有这些是如何工作的)。

无论如何,我的命令如下:

ffmpeg -ss 01:15:51 -t 00:05:59 -i outofsight.mp4 \ 
-acodec copy -vcodec copy clip.mp4
Run Code Online (Sandbox Code Playgroud)

在复制过程中,出现以下情况:

Seems stream 0 codec frame rate differs from container frame rate: 45000.00 (45000/1) -> 25.00 (25/1)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from outofsight.mp4':
  Duration: 01:57:42.10, start: 0.000000, bitrate: 830 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 720x384, 25 tbr, 22500 tbn, 45k tbc
    Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16
Output #0, mp4, to 'out.mp4':
    Stream #0.0(und): Video: libx264, yuv420p, 720x384, q=2-31, 90k tbn, 22500 tbc
    Stream #0.1(eng): Audio: libfaac, 48000 Hz, stereo, s16
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 2591 fps=2349 q=-1.0 size=    8144kB time=101.60 bitrate= 656.7kbits/s
…
Run Code Online (Sandbox Code Playgroud)

我得到了整部电影的其余部分,而不是 5:59 的持续时间剪辑。因此,为了测试这一点,我使用-t 00:00:01. 我得到的是一个 15:00 分钟的剪辑。所以我做了一些黑盒工程,并决定-t通过计算输入的值来扩展我的选项,因为 1 秒被解释为 900 秒。对于我想要的 359 秒剪辑,我计算了 0.399 秒,因此我的 ffmpeg 命令变为:

ffmpeg -ss 01:15.51 -t 00:00:00.399 -i outofsight.mp4 \ 
-acodec copy -vcodec copy clip.mp4
Run Code Online (Sandbox Code Playgroud)

这有效,但我不知道为什么持续时间按 900 缩放。进一步调查,每次 ffmpeg 运行都有以下行:

Seems stream 0 codec frame rate differs from container frame rate: 45000.00 (45000/1) -> 25.00 (25/1)
Run Code Online (Sandbox Code Playgroud)

45000/25 = 1800。一定是某个地方的关系。不知何故,令人讨厌的高帧率导致了时间问题。这帧率怎么这么高?最好的部分是生成的 clip.mp4 具有完全相同的功能(由于复制的视频编解码器),并且从中获取更多剪辑需要相同的-t持续时间选项缩放。因此,我已将其提供给愿意查看此内容的任何人。

附录
我系统上 ffmpeg 的序言(使用 MacPorts ffmpeg 端口构建):

FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --prefix=/opt/local --disable-vhook --enable-gpl --enable-postproc --enable-swscale --enable-avfilter --enable-avfilter-lavf --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libdirac --enable-libschroedinger --enable-libfaac --enable-libfaad --enable-libxvid --enable-libx264 --mandir=/opt/local/share/man --enable-shared --enable-pthreads --cc=/usr/bin/gcc-4.2 --arch=x86_64
  libavutil     49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 0
  libavformat   52.31. 0 / 52.31. 0
  libavdevice   52. 1. 0 / 52. 1. 0
  libavfilter    1. 4. 0 /  1. 4. 0
  libswscale     1. 7. 1 /  1. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Jan  4 2010 21:51:51, gcc: 4.2.1 (Apple Inc. build 5646) (dot 1)
Run Code Online (Sandbox Code Playgroud)

编辑
不确定它是否是一个错误,但它现在似乎在我当前版本的 ffmpeg 中得到修复,至少对于这个视频(来自 MacPorts 的 0.6.1 版)。

evi*_*oup 1

对于 ffmpeg,选项的定位很重要。在您的示例中,它尝试将 -ss 和 -t 应用于输入。像这样使用它会将选项应用到输出:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -acodec copy -vcodec copy clip.mp4
Run Code Online (Sandbox Code Playgroud)

对于当前的 ffmpeg,正确的语法是:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -c copy clip.mp4
Run Code Online (Sandbox Code Playgroud)