FFMPEG áudio fora de sincronia quando transcodificação (demuxing) de DV

2

Estou preso a esse problema há meses. Eu tenho mais de 50 fitas DV (de e antiga filmadora Sony) para ser convertido em um formato mais moderno e utilizável (provavelmente H264). Eu comecei com puxando os arquivos para o meu PC (via firewire) usando DVGRAB. Lá eu tive duas opções: puxar dados RAW da fita dv, resultando em um arquivo muxed OU demuxando-o e salvando em um arquivo DVI.

É aí que os problemas começaram. Salvá-lo em um arquivo DVI resultou na falta de sincronia do áudio. Eu pensei que é um problema com DVGRAB, então eu salvei os arquivos RAW (que são sincronizados corretamente) e queria processá-los com ffmpeg.

Acontece que não importa o quanto eu demute, o áudio está sempre fora de sincronia. ANTES de dizer qualquer coisa sobre a frequência de amostragem - as diferenças de áudio são de comprimento absolutamente aleatório. Uma fita de uma hora pode ter entre 0,1 e 4 segundos de atraso de áudio no final.

Veja um arquivo de exemplo que divido em arquivos de áudio e vídeo separados para verificar as diferenças.

# 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

Este em particular difere em 1.448 segundos. Como eu disse, as diferenças variam muito.

Quanto à solução. Eu poderia apenas esticar o áudio e combiná-lo com o vídeo (testei isso), mas não posso ter certeza se o áudio estará em sincronia em algum lugar no meio da gravação.

Acho que identifiquei a origem desse comportamento. Sempre que eu ligo ou desligo a câmera (como para iniciar e parar a gravação), o vídeo começa apenas um pouquinho mais rápido que o áudio. Então, quanto mais "fragmentos" estão na fita, mais essas diferenças se somam.

Como posso consertar isso? Existe uma maneira de demover o áudio e o vídeo com timestamps, para que após a conversão eles sejam adicionados corretamente? Ou existe alguma maneira de preencher essas lacunas no áudio, para que ambos os fluxos sejam do mesmo tamanho para começar?

    
por Wojciech 19.02.2016 / 16:16

3 respostas

0

Eu finalmente resolvi o problema - é um exagero, mas funciona.

Eu percebi que, se eu copiar o .dv para qualquer outro contêiner, o áudio e o vídeo estão obviamente fora de sincronia. Então eu queria cortar esse arquivo para um segmento de 1 minuto começando no 51º minuto (-ss 51:00 -t 60), obviamente estava fora de sincronia.

No entanto, quando usei o mesmo corte (-ss 51:00 -t 60) no arquivo .dv original, ele estava em sincronia! Então, o que acabei fazendo foi escrever um script que corta o arquivo .dv em um segundo segmento a cada segundo e o salva em arquivos separados (sim, mais de 3600 arquivos por .dv). Nenhuma codificação, apenas copie a cópia para um novo contêiner (avi). Então eu usei -f concat, para colocar os arquivos minúsculos em um arquivo avi, que estava em sincronia agora! Quaisquer lacunas são inaudíveis! Tudo o que restou foi codificando H264 e AAC em MP4.

Eu executei o script no meu servidor doméstico que estava retificando os 50 arquivos .dv por alguns dias, mas agora está pronto!

OBRIGADO POR VOCÊ PARA VOCÊ AJUDAR! Eu aprendi muito sobre ffmpeg e a / v em geral.

    
por 10.05.2016 / 19:28
6

Aqui estão três tentativas de curingas para resolver esse problema:

Método 1a Use a hora do sistema como data e hora

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

Método 1b Use o resampler com o sinalizador definido para injetar silêncio quando os timestamps de áudio de entrada tiverem intervalos

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

Método 2 Mesclar com áudio fictício

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

Método 3 Combinação do acima

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

Você pode testar cada um deles por um curto período, inserindo -t N , por exemplo. -t 20 para um teste de 20 segundos.

Se algum deles funcionar, podemos prosseguir para agrupar a saída como MP4.

    
por 18.03.2016 / 14:17
0

Eu tenho uma configuração semelhante com o mesmo problema de áudio fora de sincronia. Eu também consegui reproduzir um clipe com um áudio fora de sincronia. Se alguém quiser amostras, por favor, pergunte.

Eu posso ter encontrado uma solução para esse problema. O Kino é muito antigo e não mantém mais software que tem a capacidade de carregar um .dv do dvgrab (raw) e exportar novamente como um arquivo .dv ou dv1 / avi (ou dv2 / avi) com "re-sampling" do áudio. Bem, a saída é um arquivo corrigido que será bem sincronizado antes e depois de uma transcodificação 'ffmpeg'.

Existem algumas desvantagens. Kino pode parar o trabalho ou até mesmo não trabalhar, já que isso é antigo. Acabei de instalá-lo a partir do 'aur' (Arch linux) e pude usá-lo diretamente. Não há interface de linha de comando. Não consegui encontrar uma maneira de automatizar isso.

EDITAR:

Pode haver outra solução. Eu acho que o problema é que os bits de início e parada do fluxo de alguma forma são quebrados, e o timecode fica pior. Eu tenho alguns clipes que parecem ter uma data do ano '2068'. De qualquer forma, você pode usar o 'dvgrab' novamente para dividir os clipes toda vez que achar que há um novo fluxo de registro:

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

'- a' o auto split, '-srt' e '-t' ajuda a rastrear os arquivos (constrói um srt com as datas e acrescenta a data aos arquivos, respectivamente). Isso criará um novo arquivo para cada novo stream . Como o início de cada fluxo está em sincronia, você pode "ffmpeg" individualmente. Parece que cada arquivo contém o timecode da "sessão" original (como o dvgrab chama) então, se você concat todos os arquivos diretamente com o ffmpeg, você ainda obtém o mesmo fora de sincronia.

    
por 08.01.2018 / 18:28