Звук FFMPEG не синхронізований під час перекодування (демонтаж) з DV


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 секунд. Як я вже сказав, відмінності сильно різняться.

Щодо рішення. Я міг би просто розтягнути аудіо та поєднати його з відео (я тестував це), але я не можу бути впевнений, чи буде звук синхронізований десь посередині запису.

Я думаю, я визначив джерело такої поведінки. Щоразу, коли я вмикаю або вимикаю камеру (як для запуску і припинення запису), відео починається трохи менше, ніж звук. Отже, чим більше "фрагментів" на стрічці, тим більше цих відмінностей додається.

Як я можу це виправити? Чи є спосіб знімати звук та відео за допомогою часових позначок, щоб після перетворення вони склалися правильно? Або все-таки є заповнити ці прогалини в аудіо, щоб обидва потоки були однакового розміру для початку?


Яка команда демонтажу необроблених файлів?
Gyan

Сирий .dv-файл мультиплексований за своєю природою. FFMPEG демуфікує його за замовчуванням при перетворенні в будь-який контейнер.
Войцех

Гаразд, яка ваша команда перетворення? Я забув, що ти перекодуєш.
Gyan

Я спробував десяток комбінацій. Нічого особливого, хоча: avconv -f dv -i ./46raw.dv -f mp4 -acodec libvo_aacenc -b: 256k -vcodec libx264 -b: v 4000k -y ./46raw.aac.mp4
Войцех

1
avconv! = ffmpeg. Якщо це лише проблема зсуву, ви можете використовувати -af adelay=1000|1000там, де 1000 затримка в мс.
Gyan

Відповіді:


10

Ось три спроби вирішити цю проблему:

Спосіб 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 Використовуйте resampler із встановленим прапором для введення тиші, коли вхідні звукові часові позначки мають прогалини

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

Спосіб 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.


Варіант 2: Простий фільтрувальний фільм "amerge" повинен був мати рівно 1 вхід і 1 вихід. Однак він мав> 1 вхід (и) та 1 вихід (и). Відрегулюйте або використовуйте натомість складний фільтр (-filter_complex). Варіант 1. Подає чимало помилок: [aac @ 0x9160040] Введення черги у зворотному часі [mp4 @ 0x915e1c0] Немонотонне DTS у вихідному потоці 0: 1; попередній: 70000289337917, поточний: 70000289337250; зміна до 70000289337918. Це може призвести до неправильних часових позначок у вихідному файлі. І зупиняється приблизно через 90 Мб невідтворюваного вихідного файлу.
Войцех

Тепер спробуйте 3 команди. Також тестуйте програвання з ffplay, тобтоffplay method1.ts
Gyan

Варіанти 1a та 3 створюють файли 90MB та 20MB відповідно, майже без відео. Варіанти 1b та ​​2 створюють ціле відео, але не допомагають щодо затримки :(
Войцех

Робити це сліпо - марно. Чи можете ви надіслати трохи необробленого файлу, скажімо, 20 секунд або достатньо, щоб спостерігати втрату синхронізації з початковою командою?
Gyan

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 взагалі.


Це вдале вирішення, але насправді не вирішує проблему синхронізації, оскільки кожне обговорення DV в AVI зазнає тієї самої помилки, що і при копіюванні всього .dv в .avi. Це рішення дозволяє запобігти невеликим розбіжностям, якщо такі є, у кожному сегменті на 1 секунду від каскаду та накопичення, оскільки кожна секунда є окремим файлом. У вас залишиться декілька AVI, де є помітна асинхроніка, але вони не впливають на решта сегментів AVI. Якщо ви можете, я все ще готовий працювати над коротким сегментом сировини .dv, щоб побачити, чи можна це точно вирішити, і за один крок.
Gyan

Я усвідомлюю, що прогалини все ще є, але розтягнути аудіо було б досить придумати таке ж рішення. Це досить добре для мене. Щодо вибірки - мало сенсу надсилати невеликий зразок, оскільки помилка становить максимум 3 секунди за 1 год, і це менше 0,1%. Я не можу надіслати вам цілий файл, оскільки це сімейні відео моєї сестри (вона не схвалює). Якщо мені вдасться отримати порожню стрічку, я можу зробити новий зразок для роботи з вами (зйомка фільму на телевізорі дала б хороші посилання на синхронізацію).
Войцех

Моє бажане рішення не передбачає розтягування звуку. Сирий DV не має часових позначок, але звук переплетений синхронізовано, тому моє майстерність буде спрямована на збереження хронологічного відношення. Якщо ви коли-небудь знайдете час, я готовий працювати з зразком.
Gyan

0

У мене є аналогічна установка з тим самим звуком із проблеми синхронізації. Мені також вдалося відтворити кліп із аудіосинхронізованим аудіо. Якщо хто хоче зразки, будь ласка, запитайте.

Можливо, я знайшов рішення для цієї проблеми. Kino - це дуже давнє і більше не підтримуване програмне забезпечення, яке має можливість завантажувати. . Ну, вихід - це виправлений файл, який буде добре синхронізований до та після коду '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, ви все одно отримаєте той самий синхронізацію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.