FFmpeg抽出クリップ-ストリームのフレームレートがコンテナーのフレームレートと異なる(x264、aac)


8

まとめ
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

コピー中、次のものが表示されます。

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がまったく同じ機能を持っていることです(コピーされたビデオコーデックにより)。これからさらにクリップを取得するには、-tdurationオプションに同じスケーリングが必要です。したがって、これをチェックしてくれる人なら誰でも利用できるようにしました。

付録
自分のシステムでの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)

編集
バグかどうかはわかりませんが、少なくともこのビデオ(MacPortsのバージョン0.6.1)では、現在のバージョンのffmpegで修正されているようです。


再エンコードは解決策ではなく、5時間分のコンテンツに対して1時間分のデコードを行うのは不合理であり、根本的な問題に対処できない可能性があります。素晴らしい初期の研究です。おそらく、ffmpegが検出したfpsが問題の根源であると想定することは正しいでしょう。新しいバージョンのffmpegで問題が修正されたようですが、コメントします。-cを別のコンテナー形式にコピーすることをお勧めします。これはさまざまな効果をもたらす可能性がありますが、実験するための良い次のステップになるでしょう。
dstob

回答:


1

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

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枚の画像が得られます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.