Crie um screencast com ffmpeg: como manter vídeo + áudio sincronizados?

Crie um screencast com ffmpeg: como manter vídeo + áudio sincronizados?

Criei alguns screencasts com ffmpeg. O PC que uso tem hardware compatível (Intel Core i7-4930K Six Core 3,40 GHz 12 MB Cache, 32 GB de RAM), mas infelizmente roda Windows 7. Como quero fazer meu screencast no Linux, instalei o Kubuntu no VMware. Atribuí 4 núcleos de CPU e 4 GB de RAM à VM.

Eu gravo meu screencast com o seguinte comando:

ffmpeg -f alsa -ac 1 -i pulse -f x11grab -r 30 -s 1920x1080 -i :0.0 -acodec mp3 -vcodec libx264 -preset ultrafast -crf 0 -threads 0 output.mp4

No entanto, o vídeo é executado muito mais rápido que o áudio. Depois de alguns minutos, o áudio (gravado pelo microfone) fica vários segundos atrás do vídeo. Tentei gravar o áudio no Windows Host com o audacity em paralelo e o áudio do audacity e o áudio capturado pelo ffmpeg na VM parecem estar sincronizados. Apenas o vídeo é executado muito rápido.

Qual é a razão para isto? Poderia ter que fazer VMware? Há alguma configuração que eu possa ajustar? Existem opções de ffmpeg que eu poderia usar para sincronização? Por exemplo, se eu pudesse forçar o ffmpeg a descartar ou duplicar quadros se o áudio/vídeo não estiver sincronizado, isso seria totalmente aceitável para mim, mas pelo que entendi o manual da opção -vsync do ffmpeg, esse já é o padrão.

Eu mesmo compilei o ffmpeg seguindo oGuia de compilação do Ubuntue tive a ideia de usar o ffmpeg deaqui.

EDIT: saída ffmpeg conforme solicitado:

$ /home/yankee/bin/ffmpeg -f alsa -ac 1 -i pulse -f x11grab -r 30 -s 1920x1080 -i :0.0 -acodec mp3 -vcodec libx264 -preset ultrafast -crf 0 -threads 0 05-visitor.mp4
ffmpeg version 2.1.git Copyright (c) 2000-2014 the FFmpeg developers
  built on Feb 24 2014 08:38:08 with gcc 4.8 (Ubuntu/Linaro 4.8.1-10ubuntu9)
  configuration: --prefix=/home/yankee/ffmpeg_build --extra-cflags=-I/home/yankee/ffmpeg_build/include --extra-ldflags=-L/home/yankee/ffmpeg_build/lib --bindir=/home/yankee/bin --extra-libs=-ldl --enable-gpl --enable-libass --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab
  libavutil      52. 65.100 / 52. 65.100
  libavcodec     55. 52.102 / 55. 52.102
  libavformat    55. 33.100 / 55. 33.100
  libavdevice    55. 10.100 / 55. 10.100
  libavfilter     4.  1.103 /  4.  1.103
  libswscale      2.  5.101 /  2.  5.101
  libswresample   0. 17.104 /  0. 17.104
  libpostproc    52.  3.100 / 52.  3.100
Guessed Channel Layout for  Input Stream #0.0 : mono
Input #0, alsa, from 'pulse':
  Duration: N/A, start: 1394106509.365291, bitrate: 768 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, mono, s16, 768 kb/s
[x11grab @ 0x2551e40] device: :0.0 -> display: :0.0 x: 0 y: 0 width: 1920 height: 1080
[x11grab @ 0x2551e40] shared memory extension found
Input #1, x11grab, from ':0.0':
  Duration: N/A, start: 1394106509.415547, bitrate: 1990656 kb/s
    Stream #1:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 1990656 kb/s, 30 tbr, 1000k tbn, 30 tbc
No pixel format specified, yuv444p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.                                                                                                                                                                                                            
[libx264 @ 0x256db60] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x256db60] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264 @ 0x256db60] 64 - core 142 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, mp4, to '05-visitor.mp4':
  Metadata:
    encoder         : Lavf55.33.100
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv444p, 1920x1080, q=-1--1, 15360 tbn, 30 tbc
    Stream #0:1: Audio: mp3 (libmp3lame) (i[0][0][0] / 0x0069), 48000 Hz, mono, s16p
Stream mapping:
  Stream #1:0 -> #0:0 (rawvideo -> libx264)
  Stream #0:0 -> #0:1 (pcm_s16le -> libmp3lame)
Press [q] to stop, [?] for help
frame=19011 fps= 30 q=-1.0 Lsize=  186418kB time=00:10:34.84 bitrate=2405.5kbits/s    
video:180861kB audio:4960kB subtitle:0 data:0 global headers:0kB muxing overhead 0.321432%
[libx264 @ 0x256db60] frame I:77    Avg QP: 0.00  size:451985
[libx264 @ 0x256db60] frame P:18934 Avg QP: 0.00  size:  7943
[libx264 @ 0x256db60] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 0x256db60] mb P  I16..4: 59.7%  0.0%  0.0%  P16..4:  0.0%  0.0%  0.0%  0.0%  0.0%    skip:40.3%
[libx264 @ 0x256db60] coded y,u,v intra: 0.2% 0.2% 0.2% inter: 0.0% 0.0% 0.0%
[libx264 @ 0x256db60] i16 v,h,dc,p: 100%  0%  0%  0%
[libx264 @ 0x256db60] kb/s:2338.03

Brinquei um pouco mais e percebi que se o arquivo de saída já existir, o ffmpeg me pergunta se eu gostaria de substituir o arquivo. Neste caso, o fluxo de áudio já contém coisas que eu disse enquanto existe a questão do arquivo de substituição. No entanto, o vídeo não inicia antes de eu confirmar a substituição do arquivo e, portanto, o áudio naturalmente fica bastante atrás do vídeo. Mas isso é fácil de lidar. Apenas não substitua os arquivos existentes.

Eu realmente não me importo com o formato que terei, desde que o vídeo tenha algum formato sem perdas e eu possa editá-lo com o Adobe Premiere (ele não suporta mkv).

EDIT2: Cheguei um pouco mais perto do problema. Ao observar atentamente o fluxo de vídeo resultante, às vezes é perceptível que alguns quadros estão faltando. Pode ser porque abri uma janela neste exato momento que faz com que a compactação de vídeo consuma mais CPU (porque muitos pixels foram alterados) ou algo parecido. Talvez existam alguns buffers que eu possa atribuir ao ffmpeg para acelerar o processamento nesses momentos? Afinal minha máquina tem 32 GB de RAM, ela deve servir para alguma coisa... Ou há algum outro codec sem perdas que eu possa usar ou...? Da próxima vez, também tentarei definir uma prioridade de CPU mais alta para o ffmpeg.

Responder1

Isso funcionou para mim em 2019. Tentei com codificadores diferentes, mas ao usar aqueles que não são nativeffmpeg, o áudio e o vídeo ficam fora de sincronia. Especificamente, o vídeo está atrasado. mpeg4e aacsão native.

ffmpeg -f alsa -ac 1 -i pulse -f x11grab -r 30 -s 1920x1080  -i :0.0 -acodec aac -vcodec mpeg4 -preset medium -qscale:v 5 rec.mkv

Responder2

Recebo um "[swscaler @ 0xa314080] Aviso: os dados não estão alinhados! Isso pode levar a uma perda de velocidade" que parece ser o problema. No entanto, ainda não tenho uma resolução.

informação relacionada