3

Я застрял с этой проблемой в течение нескольких месяцев. У меня есть более 50 DV-кассет (от старой видеокамеры Sony), которые необходимо преобразовать в более современный и удобный формат (скорее всего, H264). Я начал с вытягивания файлов на свой компьютер (через FireWire) с помощью DVGRAB. Там у меня было два варианта: извлечение RAW-данных с DVD-ленты, в результате чего был получен мультиплексированный файл ИЛИ демультиплексировать его и сохранить в DVI-файл.

Вот где начались проблемы. Сохранение его в файл DVI привело к несинхронизации звука. Я думал, что это проблема с DVGRAB, поэтому я сохранил файлы RAW (которые синхронизируются правильно) и хотел обработать их с помощью ffmpeg.

Оказывается, что независимо от того, как я это делюкс, звук всегда не синхронизирован. ДО того, как вы скажете что-нибудь о частоте дискретизации - аудио различия имеют абсолютно случайную длину. Часовая лента может иметь задержку звука от 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 ответа3

9

Вот три попытки подстановки для решения этой проблемы:

Метод 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 из 3: Слияние с фиктивным звуком

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

Метод 3 из 3: Сочетание вышеуказанного

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.

0

У меня есть аналогичная установка с той же проблемой аудио из синхронизации. Мне также удалось воспроизвести клип с несинхронизированным звуком. Если кто-то хочет образцы, пожалуйста, спросите.

Возможно, я нашел решение этой проблемы. Kino - очень старое и более не обслуживаемое программное обеспечение, которое может загружать .dv из dvgrab (raw) и снова экспортировать как файл .dv или dv1/avi (или dv2/avi) с «повторной выборкой» аудио , Что ж, на выходе получается исправленный файл, который будет хорошо синхронизирован до и после транскодирования ffmpeg.

Есть некоторые недостатки. Кино может прекратить работу или даже вообще не работать, так как она старая. Я только что установил его из 'aur' (Arch linux), и я смог использовать его прямо. Нет интерфейса командной строки. Я не мог найти способ автоматизировать это.

РЕДАКТИРОВАТЬ:

Там может быть другое решение. Я думаю, что проблема в том, что начальные и конечные биты потока каким-то образом нарушаются, а временной код ухудшается. У меня есть несколько клипов с датой 2068 года. В любом случае, вы можете снова использовать 'dvgrab' для разделения клипов каждый раз, когда он думает, что есть новый поток записей:

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

'-a' выполняет автоматическое разделение, '-srt' и '-t' помогают отслеживать файлы (создает srt с датами и добавляет дату к файлам соответственно). Это создаст новый файл для каждого нового потока. Поскольку начало каждого потока синхронизировано, вы можете "ffmpeg" их по отдельности. Похоже, что каждый файл содержит временный код исходного "сеанса" (как его называет dvgrab), поэтому, если вы объедините все файлы напрямую с помощью ffmpeg, вы все равно не получите синхронизацию.

0

Я наконец решил проблему - это излишество, но оно работает.

Я понял, что если я скопирую .dv в любой другой контейнер, аудио и видео явно не синхронизированы. Затем я захотел разрезать этот файл до 1-минутного сегмента, начиная с 51-й минуты (-ss 51:00 -t 60), очевидно, что он все еще не синхронизирован.

Однако, когда я использовал тот же вырез (-ss 51:00 -t 60) на оригинальном .dv, он был синхронизирован! В итоге я написал скрипт, который каждую секунду разрезал файл .dv на 1-секундный сегмент и сохранял его в отдельных файлах (да, более 3600 файлов на .dv). Без кодирования, просто потоковое копирование в новый контейнер (avi). Затем я использовал -f concat, чтобы поместить крошечные файлы в один avi-файл, который теперь был синхронизирован! Любые пробелы не слышны! Осталось только кодировать H264 и AAC в MP4.

Я запустил скрипт на своем домашнем сервере, который пару дней перемалывал 50 файлов .dv, но теперь все готово!

СПАСИБО ВСЕМ ЗА ПОМОЩЬ! Я многое узнал о ffmpeg и a/v в целом.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .