web-dev-qa-db-ja.com

DVからのトランスコーディング(デマルチプレクサ)時にFFMPEGオーディオが同期しない

私は何ヶ月もこの問題に悩まされてきました。 50を超えるDVテープ(古いソニーのカムコーダー)を使用して、よりモダンで使用可能なフォーマット(おそらくH264)に変換します。私は、DVGRABを使用してファイルを(firewire経由で)PCにプルすることから始めました。そこでは2つのオプションがありました。dvテープからRAWデータをプルして、多重化されたファイルを作成しましたORそれをデマルチプレクサしてDVIファイルに保存しました。

それが問題の始まりです。 DVIファイルに保存すると、オーディオが同期しなくなります。 DVGRABの問題だと思ったので、RAWファイル(正しく同期されている)を保存して、ffmpegで処理したいと思いました。

どんなにデマックス化しても、オーディオは常に同期していません。サンプリング周波数について何か言う前に-オーディオの違いは完全にランダムな長さです。 1時間のテープでは、最後に0.1〜4秒のオーディオラグが発生する可能性があります。

以下は、違いを確認するために個別のオーディオファイルとビデオファイルに分割したサンプルファイルです。

# ffprobe -i ./video_conversion/13.dv 
ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers
  built with gcc 5.3.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
[dv @ 0x864f2a0] Detected timecode is invalid
[dv @ 0x864f2a0] Estimating duration from bitrate, this may be inaccurate
Input #0, dv, from './video_conversion/13.dv':
  Duration: 01:00:45.80, start: 0.000000, bitrate: 28800 kb/s
    Stream #0:0: Video: dvvideo, yuv420p, 720x576 [SAR 16:15 DAR 4:3], 28800 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
    Stream #0:1: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s

# ffprobe -i ./video_conversion/tmp/13.mp4
ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers
  built with gcc 5.3.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from './video_conversion/tmp/13.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf56.40.101
  Duration: 01:00:45.80, start: 0.000000, bitrate: 5685 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 720x576 [SAR 16:15 DAR 4:3], 5683 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler

# ffprobe -i ./video_conversion/tmp/13.mp3
ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers
  built with gcc 5.3.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
[mp3 @ 0x954c2a0] Skipping 0 bytes of junk at 237.
Input #0, mp3, from './video_conversion/tmp/13.mp3':
  Metadata:
    encoder         : Lavf56.40.101
  Duration: 01:00:44.35, start: 0.023021, bitrate: 128 kb/s
    Stream #0:0: Audio: mp3, 48000 Hz, stereo, s16p, 128 kb/s
    Metadata:
      encoder         : Lavc56.60

この特定のものは1.448秒異なります。言ったように、違いは大きく異なります。

解決策は。オーディオをストレッチしてビデオと組み合わせるだけです(テストしました)が、オーディオが録音の途中のどこかで同期しているかどうかはわかりません。

私はこの行動の原因を特定したと思います。カメラのオン/オフを切り替えるたびに(録画の開始と停止に関して)、ビデオはオーディオよりもほんの少し速く開始されます。したがって、テープに含まれる「フラグメント」が多いほど、これらの違いが大きくなります。

どうすれば修正できますか?オーディオとビデオをタイムスタンプで逆多重化して、変換後に正しく加算されるようにする方法はありますか?それとも、オーディオのこれらのギャップを埋めて、両方のストリームが最初は同じサイズになるようにしていますか?

3
Wojciech

私はようやく問題を解決しました-やり過ぎですが、うまくいきます。

.dvを他のコンテナーにコピーすると、オーディオとビデオが明らかに同期していないことに気付きました。次に、そのファイルを51分目(-ss 51:00 -t 60)から始まる1分のセグメントにカットしたかったのですが、明らかに同期が取れていませんでした。

ただし、元の.dvで同じカット(-ss 51:00 -t 60)を使用すると、同期されました!つまり、.dvファイルを毎秒1秒のセグメントにカットし、それを個別のファイル(.dvあたり3600ファイル以上)に保存するスクリプトを書いたことになります。エンコーディングなし。コピーを新しいコンテナ(avi)にストリーミングするだけです。次に、-f concatを使用して、小さなファイルを1つのaviファイルに入れました。ギャップは聞こえません!残ったのは、H264とAACをMP4にエンコードすることだけでした。

50の.dvファイルを数日間削っていたホームサーバーでスクリプトを実行しましたが、これで完了です。

助けてくれてありがとう!私は一般にffmpegとa/vについて多くを学びました。

0
Wojciech

この問題を解決するための3つのワイルドカードの試みを次に示します。

方法1aシステム時間をタイムスタンプとして使用

ffmpeg -use_wallclock_as_timestamps 1 -i input.dv \
       -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -fflags +genpts method1.ts

方法1b入力オーディオのタイムスタンプにギャップがある場合、フラグを設定してリサンプラーを使用して無音を挿入します

ffmpeg -i input.dv -c:v libx264 -b:v 4000k \
       -af "aresample=async=1:first_pts=0" -c:a aac -b:a 128k -fflags +genpts method1.ts

方法2ダミーオーディオとマージ

ffmpeg -i input.dv -f lavfi -i "aevalsrc=0:c=2:s=48000" \
       -filter_complex "[0:a][1:a]amerge[a]" -map 0:v -map "[a]" -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -ac 2 -shortest method2.ts

方法上記の組み合わせ

ffmpeg -use_wallclock_as_timestamps 1 -i input.dv -f lavfi -use_wallclock_as_timestamps 1 -i "aevalsrc=0:c=2:s=48000" \
       -filter_complex "[0:a][1:a]amerge[a]" -map 0:v -map "[a]"  -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -ac 2 -shortest method3.ts

-t Nを挿入することで、それぞれを短時間テストできます。 -t 20 20秒のテスト。

それらのいずれかが機能する場合は、出力をMP4としてラップします。

11
Gyan

同様のセットアップで、オーディオが同期しない問題があります。また、オーディオが同期していないクリップを再生することもできました。サンプルをご希望の方はお問い合わせください。

この問題の解決策を見つけたかもしれません。 Kino は非常に古く、dvgrab(raw)から.dvをロードして.dvまたはdv1/avi(またはdv2/avi)ファイルとして「オーディオの再サンプリング」。さて、出力は修正されたファイルで、「ffmpeg」トランスコードの前後で十分に同期されます。

いくつかの欠点があります。これは古いため、Kinoが動作を停止するか、まったく動作しない場合もあります。 「aur」(Arch Linux)からインストールしただけで、簡単に使用できました。コマンドラインインターフェイスはありません。これを自動化する方法が見つかりませんでした。

編集:

別の解決策があるかもしれません。問題は、ストリームの開始ビットと停止ビットがどういうわけか壊れて、タイムコードが悪化することだと思います。 '2068'年の日付のように見えるクリップがいくつかあります。とにかく、新しいレコードストリームがあると考えるたびに、クリップを分割するために「dvgrab」を再び使用できます。

dvgrab -I input -size 0 -a -format=raw -showstatus -srt -t output

'-a'は自動分割を行い、 '-srt'および '-t'はファイルの追跡に役立ちます(日付を使用してsrtを構築し、ファイルに日付を追加します)。これにより、新しいstreamごとに新しいファイルが作成されます。各ストリームの先頭は同期しているため、個別に「ffmpeg」することができます。各ファイルには元の「セッション」のタイムコードが含まれているように見えるため(dvgrabがそれを呼び出すため)、ffmpegを使用してすべてのファイルを直接連結した場合でも、同期が取れなくなります。

0
Noeljunior

50個のDVファイルを修正し、次のbashスクリプトを使用してLinuxの同期の問題を修正できました。

SRC="/home/brian/Desktop/audio_shift"

set -f

for FILE in $(find "$SRC" -name *.dv); do
  echo "Konvertiere $FILE "
  dvgrab -input $FILE -f dv2 -s 0 -t
done

これにより、現在のフォルダー内の各DVファイルごとにAVIファイル(DV2形式)が生成されます。これは、オーディオ同期の問題なしに(たとえばMP4に)さらに変換できます。

0
Brian