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

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

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

身体
我正在尝试从 MP4 格式的电影中提取剪辑(使用手刹)。在尝试了 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

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

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

我得到的不是时长 5:59 的剪辑,而是整部电影。因此,为了测试这一点,我使用 运行了 ffmpeg 命令-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

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

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

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)

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

答案1

我遇到了同样的问题,我的解决方案如下:

        $ffmpegout = array();           
        //10 is the number of images you want from video
        $fracduration = ($info['duration']/10);             

exec('ffmpeg -y -i /testmedia/'.$info['filename'].'-vf fps=fps=1/'.$fracduration.'-f image2 /testmedia/images/output%03d.jpg 2>&1',$ffmpegout);//print_r($ffmpegout);

这样,无论视频长度如何,我都可以获得整个视频的 10 张图片

答案2

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

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -acodec copy -vcodec copy clip.mp4

使用当前的 ffmpeg,正确的语法是:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -c copy clip.mp4

相关内容