Crea un screencast con ffmpeg: ¿cómo mantener sincronizados el vídeo y el audio?

Crea un screencast con ffmpeg: ¿cómo mantener sincronizados el vídeo y el audio?

Creé algunos screencasts con ffmpeg. La PC que uso tiene hardware capaz (Intel Core i7-4930K Six Core 3.40GHz 12MB Cache, 32 GB RAM), pero desafortunadamente ejecuta Windows 7. Como quiero hacer mi screencast en Linux, instalé Kubuntu en VMware. Asigné 4 núcleos de CPU y 4 GB de RAM a la VM.

Grabo mi screencast con el siguiente 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

Sin embargo, el vídeo se ejecuta mucho más rápido que el audio. Después de un par de minutos, el audio (grabado por micrófono) se retrasa varios segundos con respecto al vídeo. Intenté grabar el audio en el Host de Windows con audacity en paralelo y el audio de audacity y el audio capturado por ffmpeg en la VM parecen estar sincronizados. Sólo que el vídeo corre demasiado rápido.

¿Cuál es la razón para esto? ¿Podría tener que hacer VMware? ¿Hay alguna configuración que pueda modificar? ¿Existen opciones de ffmpeg que pueda usar para sincronizar? Por ejemplo, si pudiera forzar a ffmpeg a eliminar o duplicar fotogramas si el audio/video no está sincronizado, estaría totalmente bien para mí, pero hasta donde entiendo el manual de la opción -vsync de ffmpeg, esta ya es la opción predeterminada.

Compilé ffmpeg yo mismo siguiendo elGuía de compilación de Ubuntuy se me ocurrió la idea de usar ffmpeg deaquí.

EDITAR: salida ffmpeg según lo 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

Jugué un poco más y noté que si el archivo de salida ya existe, ffmpeg me pregunta si deseo anular el archivo. En este caso, la transmisión de audio ya contiene cosas que dije mientras existía la pregunta sobre sobrescribir el archivo. Sin embargo, el vídeo no comienza antes de que confirme la sobrescritura del archivo y, por lo tanto, el audio, naturalmente, va bastante por detrás del vídeo. Pero eso es fácil de afrontar. Simplemente no sobrescribas los archivos existentes.

Realmente no me importa el formato con el que termine, siempre y cuando el vídeo tenga algún formato sin pérdidas y pueda editarlo con Adobe Premiere (no es compatible con mkv).

EDIT2: Me acerqué un poco más al problema. Al observar detenidamente la transmisión de vídeo resultante, a veces se nota que faltan un par de fotogramas. Mayo porque abrí una ventana justo en este momento lo que hace que la compresión de video consuma más CPU (porque cambiaron muchos píxeles) o cosas similares. ¿Quizás haya algunos buffers que pueda asignar a ffmpeg para acelerar el procesamiento en esos momentos? Después de todo, mi máquina tiene 32 GB de RAM, debería servir para algo... ¿O hay otros códecs sin pérdidas que pueda usar o...? La próxima vez también intentaré establecer una prioridad de CPU más alta para ffmpeg.

Respuesta1

Esto funciona para mí en 2019. Probé con diferentes codificadores, pero cuando uso unos que no son nativeffmpeg, el audio y el video no están sincronizados. En concreto el vídeo se queda atrás. mpeg4y aacson 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

Respuesta2

Recibo un mensaje "[swscaler @ 0xa314080] Advertencia: ¡los datos no están alineados! Esto puede provocar una pérdida de velocidad", que parece ser el problema. Sin embargo, todavía no tengo una resolución.

información relacionada