0

重複の可能性:
ffmpeg:変換前後の動画の長さが同じではありません

最近、私は時間パラメーター(ミリ秒の解像度)に関して非常に正確な操作を必要とするアプリケーションにFFmpegを使用しようとしています。残念ながら、FFmpegの操作機能が不正確な結果を返すことに驚いた。

'ffmpeg'の出力は次のとおりです。

ffmpeg version 0.11.1 Copyright (c) 2000-2012 the FFmpeg developers
  built on Jul 25 2012 19:55:05 with gcc 4.2.1 (Apple Inc. build 5664)
  configuration: --enable-gpl --enable-shared --enable-pthreads --enable-libx264 --enable-libmp3lame
  libavutil      51. 54.100 / 51. 54.100
  libavcodec     54. 23.100 / 54. 23.100
  libavformat    54.  6.100 / 54.  6.100
  libavdevice    54.  0.100 / 54.  0.100
  libavfilter     2. 77.100 /  2. 77.100
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0. 15.100 /  0. 15.100
  libpostproc    52.  0.100 / 52.  0.100

ここで、「foo.mov」のオーディオトラックをリッピングしたいとします。'ffmpeg-ifoo.mov'の関連する出力は次のとおりです。

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'foo.mov':
  Metadata:
    major_brand     : qt  
    minor_version   : 0
    compatible_brands: qt  
    creation_time   : 2012-07-24 23:16:08
  Duration: 00:00:40.38, start: 0.000000, bitrate: 805 kb/s
    Stream #0:0(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 480x360, 733 kb/s, 24.46 fps, 29.97 tbr, 600 tbn, 1200 tbc
    Metadata:
      rotate          : 90
      creation_time   : 2012-07-24 23:16:08
      handler_name    : Core Media Data Handler
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, s16, 63 kb/s
    Metadata:
      creation_time   : 2012-07-24 23:16:08
      handler_name    : Core Media Data Handler

お気づきかもしれませんが、ビデオファイルの長さは00:00:40.38です。次のコマンドを使用して、オーディオトラックをリッピングしました。

'ffmpeg -i foo.mov foo.wav'

出力:

Output #0, wav, to 'foo.wav':
  Metadata:
    major_brand     : qt  
    minor_version   : 0
    compatible_brands: qt  
    creation_time   : 2012-07-24 23:16:08
    encoder         : Lavf54.6.100
    Stream #0:0(und): Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
    Metadata:
      creation_time   : 2012-07-24 23:16:08
      handler_name    : Core Media Data Handler
Stream mapping:
  Stream #0:1 -> #0:0 (aac -> pcm_s16le)
Press [q] to stop, [?] for help
size=3482kB time=00:00:40.42 bitrate= 705.6kbits/s    
video:0kB audio:3482kB global headers:0kB muxing overhead 0.001290%

ご覧のとおり、出力ファイルは入力のファイルよりも長くなっています。

もう1つの例は、オーディオ(およびビデオ)ファイルのトリミングです。オーディオファイルのトリミングにffmpegを使用したいとします。次のコマンドを使用しました:

'ffmpeg -t 00:00:10.000 -i foo.wav Trimmed_foo.wav -ss 00:00:25.000'

出力:

[wav @ 0x10180e800] max_analyze_duration 5000000 reached at 5015510
Guessed Channel Layout for  Input Stream #0.0 : mono
Input #0, wav, from 'foo.wav':
  Duration: 00:00:40.42, bitrate: 705 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
Output #0, wav, to 'trimmed_foo.wav':
  Metadata:
    encoder         : Lavf54.6.100
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le -> pcm_s16le)
    Press [q] to stop, [?] for help
size=864kB time=00:00:10.03 bitrate= 705.6kbits/s    
video:0kB audio:864kB global headers:0kB muxing overhead 0.005199%

繰り返しますが、出力ファイルは予想より30ミリ秒長くなっています。

私は長い間、この問題を調査しようとしましたが、成功しませんでした。同じ機能に大胆さを使うと、それは非常に正確になります!

誰かがこの問題を解決する方法を知っていますか?

4

1 に答える 1

12

TL; DR : FFmpeg と iOS デバイスは、ニーズに合わないツールです。

カバーすべき問題はたくさんあるので、順不同で以下に示します。

  • 使用している FFmpeg も基礎となるコーデックも、必要な種類の時間解像度用に設計されていません。40 ミリ秒は 25 fps で 1 フレームに相当しますが、これはほとんどのビデオおよびオーディオ ファイルのコンテキストではあまり多くありません。超正確なタイミングは、ソース AAC データのような一般的なオーディオ コーデックの設計機能ではなく、FFmpeg もこれに従います。

  • トランスコーディングを行わないでください。データをできるだけ変更したくない場合は、変更しないでください。ffmpeg -i in.mov -c:a copy out.m4awav 形式にトランスコードする代わりに、オーディオ ストリームを正確に抽出するために使用できます。

  • ファイル情報を取得するには、FFmpeg の代わりに FFprobe を使用します。FFmpeg は、デフォルトのロギングが非常に冗長であるため、入力ファイルと出力ファイルに関する大まかな情報を提供するだけです。FFprobe は通常 FFmpeg にバンドルされており、便利な形式で情報を抽出するように特別に設計されています。情報を取得するために使用ffprobe -show_streams -show_format in.movします。

  • あなたの-analyzedurationmax_analyze_duration reached出力にあるメモについて気づいたかもしれません。ドキュメントから、FFmpegが合計の長さを推定する前に、実際にファイルから読み取られるマイクロ秒数です。繰り返しになりますが、ほとんどの場合、ファイルの長さをマイクロ秒単位の精度で知ることは実現不可能であり、望ましくなく、費用かかります。超高精度が必要な場合は、そのパラメーターが実際の入力よりもはるかに高く設定されていることを確認してください。

  • オプションの配置にはもう少し注意してください。これはかなりマイナーですが、あなたが気付いていない場合に備えて、取り上げるべきだと思いました. FFmpeg のオプションの多くは、入力と出力に関して与えられた順序に応じて異なる動作をします。特に-ssあなたが使用していること。入力の後に必要な場所にありますが-t、最初に出力のみのオプションもあります...奇妙です。そのコマンドを注文するより自然な方法は次のようになります。

    ffmpeg -i foo.wav -ss 00:00:25.000 -t 00:00:10.000 trimmed_foo.wav
    
  • すべてのタイミング コマンドは秒単位の入力を受け入れるため (小数秒を含む)、すべての前に を付ける必要はありません00:00:

  • コンテナの長さと実際のストリームの長さを区別します。私は Audacity を使用していませんが、それが何をしているのかについてあなたに嘘をついていたので、極端な精度を示したとしても驚かないでしょう. 実際にオーディオまたはビデオ データをミリ秒の精度でトリミングするには、入力から出力に含めるフレームを選択するだけでなく (25 fps で 40 ミリ秒の精度です)、最後に無音を挿入するようにフレーム データを変更する必要があります。フレームのインクルードに基づいてトリミングし、コンテナ ファイルのメタデータに非常に正確な長さを入れる方がはるかに簡単です。一部の再生ソフトウェアは、実際にはその数に基づいてカットオフする場合がありますが、繰り返しになりますが、ほとんどの AV ソフトウェアは、そのレベルの精度のために設計されていません。Audacity によってトリミングされたファイルの長さとして FFmpeg が示す内容を知りたいです。

今思いつくのはこれだけですが、上記のいくつかを組み込む機会があれば、さらにフィードバックをいただければ幸いです。私の推測では、この種の正確性は研究目的に必要であり、その場合は研究を楽しんでください!

于 2012-07-27T19:33:36.687 に答える