Comandos útiles de FFmpeg

Listar los codecs y formatos disponibles (Un mismo codec puede tener varios formatos soportados).

ffmpeg -codecs
ffmpeg -formats

Conceptos básicos.

Un códec es un estándar de compresión. El video o audio sin procesar se comprime cuando se codifica y se descomprime (decodifica) en la reproducción.

Un formato es un contenedor que contiene uno o más codecs: vídeo, audio y también datos sobre sus pistas y subtítulos. Algunos contenedores multimedia son: AVI, MPG, MOV (Contenedor de QuickTime), ASF (Contenedor de WMV y WMA), Ogg, OGM, RMVB y MKV (Matroska). Las principales diferencias entre unos formatos contenedores y otros son:

Mostrar información de un fichero de vídeo / streaming (Resolución, fecha de creación, codec, bitrate, etc ).

ffmpeg -i video.flv
# Sin Información sobre el copyright
ffmpeg -i video.flv -hide_banner
# Información sobre el formato de un streaming (ùtil para grabar en un archivo).
ffmpeg -i "http://straming.tv.net:8080/videosz/6780"
 
# ffprobe permite obtener información de una forma más limpia y formateando la salida, como por ejemplo en json o xml.
ffprobe -i video.flv   # Equivale a ffmpeg -i
ffprobe -i video.flv -print_format json -hide_banner   # Formato json y sin mostrar información sobre las flags de compilación.
 
avconv -i # alternativa.
 
# Es posible que se quiera complementar con la información mostrada por otras herramientas como mplayer.
mplayer -vo null -ao null -identify -frames 0 fichero.avi

Obtener y editar metadatos de ficheros multimedia con ffmpeg .

Es muy útil editar metadatos de ficheros multimedia cuando los reproductores no aceptan un orden establecido por el usuario y se obliga a usar genero, artista, album, etc. Esto por ejemplo sucede con los reproductores y aparatos de Apple.

Información de metadatos.

# Obtener metadatos de un fichero, por ejemplo un MP3.
ffmpeg -i 02\ -\ Brimstone\ -\ Deafening.mp3 -f ffmetadata metadata.txt
cat metadata.txt 
;FFMETADATA1
album=Record in peace
artist=Brimstone
album_artist=Brimstone
comment=Free download on odgprod.com
disc=ODGP263
date=2019
genre=Dub
\oding_history=A\=PCM,F\=44100,W\=24,M\=stereo,T\=Samplitude software
 
title=Deafening
track=02
time_reference=51681492
encoder=Lavf58.45.100

Introducir / Editar metadatos a ficheros multimedia.

# Editamos la metainformación referente al disco. En este caso se crea un fichero resultante de la misma calidad pero con los metadatos editados.
ffmpeg -i fichero1.mp3 -metadata disc='XXXXX' -acodec copy -vcodec copy fichero_destino.mp3

Si se quieren editar varios ficheros a la vez se pueden ver los ejemplos de bucles que se encuentran en la sección “Cambiar de formato múltiples archivos usando ffmpeg”.

Dividir un vídeo en imágenes (frames).

# Extraer todos los frames de un vídeo.
ffmpeg -i video.flv -q:v 0 image%d.jpg
# Crear un vídeo a partir de imágenes (frames).
ffmpeg -i image%d.jpg video.avi
# Extraer frames / imágenes a partir de un momento en concreto (ej. segundo número 7).
ffmpeg -i video.flv -q:v 0 -ss 00:00:07.000 image%d.jpg
# Extraer frames / imágenes de una parte concreta del vídeo (ej. Los segundos 16 y 17).
ffmpeg -i video.flv -q:v 0 -ss 15 -t 2 image%d.jpg
# Extraer X número de frames / imágenes a partir de un momento en concreto (ej. Los 5 primeros frames a partir del segundo número 7 ).
ffmpeg -i video.flv -q:v 0 -ss 00:00:07.000 -vframes 5 image%d.jpg
# Extraer un frame cada 5 segundos de vídeo.
ffmpeg -i video.flv -q:v 0 -vf fps=1/5 image%d.jpg 
# Extraer únicamente los frames los keyframes.
ffmpeg -i video.avi -q:v 0 -vf "select=eq(pict_type\,I)" -vsync vfr image%d.jpg

Convertir un vídeo en imagen gif.

ffmpeg -i video.flv animated.gif.mp4

Transformar vídeo en fichero de audio / Extraer stream de audio / Eliminar streams de audio.

# Extraer el audio sin codificar, por lo tanto el fichero tendrá el formato original (mp3, ogg, etc) y la extensión no juega ningún papel relevante.
ffmpeg -i input-video.avi -vn -acodec copy solo_audio.ogg
# Extraer audio codificando para cambiarlo de formato, por ejemplo en mp3 sin perdidas de calidad con respecto al original.
ffmpeg -i sample.avi -q:a 0 -map a sample.mp3
 
# Eliminar todos los streams de audio.
ffmpeg -i input.avi -map 0 -map -0:a -c copy output_si_sonido.avi
 
# Eliminar todos los streams de audio excepto algunos (el número 3 y 6 para el ejemplo).
ffmpeg -i input.avi -map 0 -map -0:a:3 -map -0:a:6 -c copy output_con_dos_streams.avi
 
# Dejar solo el stream número 10. (-map 0 -map -0:a:9 Selecciona todos y luego habilita el stream de audio número 9).
ffmpeg -i input.avi -map 0 -map -0:a:9 -c copy output_sonido_concreto.avi

Cambiar entre formatos de vídeo sin perder calidad.

# -q:a 0 -q:v 0        # Permite obtener la mejor calidad a cambiar de formato de vídeo.
# -c:v copy -c:a copy  # Permite obtener la calidad pero manteniendo los formatos originales.
 
ffmpeg -y -i video.avi -q:a 0 -q:v 0 1080_video.flv

Compatibilidad de ficheros MKV creados von ffmpeg y los televisores.

Muchas televisiones, sobre todo LG, no soportan ficheros MKV si no se aporta la siguiente opción “-pix_fmt yuv420p”. También muchas televisiones tienen problemas con codecs de sonidos, siendo el mp3 uno bien soportado por casi todas. Por lo tanto si se quiere hacer un fichero mkv compatible con la mayoría de dispositivos, se recomienda este comando para usar libmp3lame y yuv420.

ffmpeg -i video_nocompatible.mkv -c:a libmp3lame -pix_fmt yuv420 video_compatible.mkv

Solucionar cuando la resolución del vídeo resultante no es la misma que la del origen.

En algunas raras ocasiones los ficheros resultantes parecen tener otra resolución, como si hubieran sido estirados. Veamos una forma de corregirlo.

Se crea un fichero_salida.avi copiando la configuración de codecs al 100%.

ffmpeg -i fichero_entrada.avi -c:v copy -q:v 0 -c:a copy fichero_salida.avi

Al reproducir “fichero_salida.avi” vemos que la resolución no es correcta.

Se ejecuta “ffmpeg -i” sobre los dos ficheros para ver las diferencias.

# fichero_entrada.avi
Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (MP4V / 0x5634504D), yuv420p, 720x404 [SAR 1:1 DAR 180:101], 1598 kb/s, SAR 180:101 DAR 32400:10201, 25 fps, 25 tbr, 25 tbn, 25 tbc
 
# fichero_salida.avi
Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (MP4V / 0x5634504D), yuv420p, 720x404 [SAR 1:1 DAR 180:101], SAR 180:101 DAR 32400:10201, 25 fps, 25 tbr, 25 tbn, 25 tbc

Problema de resolución localizado: “SAR 180:101 DAR 32400:10201” vs “SAR 1:1 DAR 180:101”.

Solución: Establecer valores SAR y DAR: https://ffmpeg.org/ffmpeg-all.html#setdar_002c-setsar

ffmpeg -i fichero_entrada.avi -vf "setdar=180:101,setsar=1:1" -q:v 0 -c:a copy fichero_salida.avi
 
# Así se muestra la salida de "ffmpeg -i" del nuevo fichero_salida.avi.
Stream #0:0: Video: mpeg4 (Simple Profile) (FMP4 / 0x34504D46), yuv420p, 720x404 [SAR 1:1 DAR 180:101], 2023 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc

Descargar / grabar streaming sin perdida de calidad.

# Ejemplo empaquetando el streaming en un contenedor MKV.
ffmpeg -i "http://straming.tv.net:8080/videosz/6780" -c:v copy -c:a copy grabacion_1.mkv
 
## Empaquetando el streaming en un contenedor MKV intentando solventar problemas con las marcas de tiempo. (Opción 1)
# Error: Non-monotonous DTS in output stream 0:1; previous: 1530923, current: 1530900; changing to 1530923. This may result in incorrect timestamps in the output file.
ffmpeg -i "http://straming.tv.net:8080/videosz/6780" -fflags +igndts -copytb 1 -timeout 50000 -c:v copy -c:a copy output.mkv
 
# Error: Non-monotonous DTS in output stream 0:1; previous: 1530923, current: 1530900; changing to 1530923. This may result in incorrect timestamps in the output file. (Opción 2).
ffmpeg -i "http://straming.tv.net:8080/videosz/6780" -vsync 1 -async -1 output.mkv

Reducir tamaño de ficheros (y resolución) de vídeo controlando la calidad (bitrate).

El bitrate de un vídeo es el flujo o la tasa de datos, o lo que es lo mismo, la cantidad de información que reproduce tu ordenador por segundo. Cuanto más bitrate tiene un vídeo, más calidad de imagen suele tener y por lo tanto más tamaño suele ocupar en disco.

La forma más básica de poder transformar un vídeo de manera que tenga menor tamaño, es modificando el bitrate. La armonía entre tamaño de archivo y calidad de imagen es algo muy subjetivo, pero estos valores pueden servir de referencia para formatos 16:9 (panorámicos).

Disminuir calidad de un vídeo para reducir tu tamaño. Para el ejemplo partimos de un fichero con un bitare original de 16500k, el fichero resultante tendrá un bitrate de 3000k. Su tamaño posiblemente será la quinta parte del fichero original y tendrá una calidad más que aceptable.

ffmpeg -i video_16500k.mkv -b:v 3000k video_3000k.mkv

Si también se quiere cambiar la resolución, cosa habitual a la hora de querer bajar la calidad (bitrate). Sobre todo cuando hablamos de dispositivos móviles o tablets, se debe escalar (cambiar la resolución) el video también.

# Transformar un video FullHD (1920x1080) de 16500k de bitrate a un vídeo HD (1280x720) con 2000k de bitrate.
ffmpeg -i video_fullhd_16500k.mkv -vf scale=1280:720 -b:v 2000k video_HD_2000k.mkv

Diferencias de tamaño de los ficheros después de sus conversiones para usar como referencia.

Video Full HD: 4,2 Gb / bitrate: 6335 kb/s / 1920x1080 / Video: h264
Video Full HD: 1,1 Gb / bitrate: 1576 kb/s / 1920x1080 / Video: h264
Video HD(720): 760 Mb / bitrate: 1124 kb/s / 1280x720 / Video: h264

NOTA: Recordar que si se quiere cambiar también de formato se debe simplemente cambiar la extensión del fichero. La opción de escalar también es compatible con imágenes, si se cambia la extensión ffmpeg también cambiará el formato de la imagen.

Averiguar la resolución y el bitrate de un fichero de vídeo.

ffmpeg -i fichero.mkv 2>&1 | grep -i bitrate
  Duration: 01:15:06.54, start: 0.000000, bitrate: 30009 kb/s
    Stream #0:0(eng): Video: h264 (High), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1k tbn, 50 tbc
    Stream #0:1(eng): Audio: vorbis, 48000 Hz, 5.1, fltp (default)

Con la información que da ffmpeg se puede deducir el tamaño del fichero. El bitrate resultante que muestra ffmpeg no es fijo y tiene pequeñas variaciones a cada segundo, pero al tener la media aproximada se puede presuponer también el tamaño de un archivo de vídeo. Esto es algo que también puede ayudar a hacer los cálculos cuando debemos transformar vídeos a un tamaño lo más concreto posible sin perder tiempo.

Para tener una aproximación del tamaño de un fichero de vídeo simplemente se multiplica el bitrate por los segundos de duración del vídeo.

Duration: 01:15:06.54, start: 0.000000, bitrate: 30009 kb/s

01:15:06.54 = 81 minutos = 4860 segundos.
30009 kb/s = 3752 kbytes
4860*3752 = 18234720 kbytes
18234720/1024 = 17807 Mbytes.

# Mbytes reales del fichero en disco.
du -m fichero
16922

Convertir vídeo de 4K a FullHD (1920×1080).

# Cambiando el formato (mkv > avi) manteniendo la mejor calidad posible.
ffmpeg -y -i 4k_video.mkv -vf scale=1920:1080 -q:a 0 -q:v 0 1080_video.avi
# Sin cambiar el formato.
ffmpeg -y -i 4k_video.mkv -vf scale=1920:1080 -c:a copy 1080_video.mkv

Convertir vídeo de FullHD a 4K (3840×2160).

# Cambiando el formato (mkv > avi) manteniendo la mejor calidad posible.
ffmpeg -y -i 1080_video.mkv -vf scale=3840:-1 -q:a 0 -q:v 0 4k_video.avi
# Sin cambiar el formato.
ffmpeg -y -i 1080_video.mkv -vf scale=3840:-1 -c:a copy 4k_video.mkv

Convertir Videos / películas de DVD, Bluray o imagenes ISO a un solo fichero de vídeo.

Los discos DVD o Bluray tienen el vídeo dividido en ficheros más pequeños, por ejemplo DVD usa de vídeo “.VOB” y los Bluray “.m2ts”, pero el funcionamiento es el mismo. Se puede usar cat una vez identificados los ficheros que contienen el vídeo para concatenerlos y luego dejar que ffmpeg lo combierta en un fichero de vídeo en e formato que queramos.

# Se monta una imagen de DVD en el directorio /mnt/test/ y se identifican qué ficheros contienen la película, que normalmente son los que más tamaño tienen.
mount -o loop Evangelion.iso  /mnt/test/
 
du -h /mnt/test/VIDEO_TS/*
10K	/mnt/test/VIDEO_TS/VIDEO_TS.BUP
10K	/mnt/test/VIDEO_TS/VIDEO_TS.IFO
90K	/mnt/test/VIDEO_TS/VTS_01_0.BUP
90K	/mnt/test/VIDEO_TS/VTS_01_0.IFO
159M	/mnt/test/VIDEO_TS/VTS_01_0.VOB
1,0G	/mnt/test/VIDEO_TS/VTS_01_1.VOB <--
1,0G	/mnt/test/VIDEO_TS/VTS_01_2.VOB <--
1,0G	/mnt/test/VIDEO_TS/VTS_01_3.VOB <--
1,0G	/mnt/test/VIDEO_TS/VTS_01_4.VOB <--
195M	/mnt/test/VIDEO_TS/VTS_01_5.VOB <-- # Contiene en este caso los créditos del final.
18K	/mnt/test/VIDEO_TS/VTS_02_0.BUP
18K	/mnt/test/VIDEO_TS/VTS_02_0.IFO
100K	/mnt/test/VIDEO_TS/VTS_02_0.VOB
15M	/mnt/test/VIDEO_TS/VTS_02_1.VOB
 
cat /mnt/test/VIDEO_TS/VTS_01_1.VOB /mnt/test/VIDEO_TS/VTS_01_2.VOB  /mnt/test/VIDEO_TS/VTS_01_3.VOB /mnt/test/VIDEO_TS/VTS_01_4.VOB /mnt/test/VIDEO_TS/VTS_01_5.VOB > $HOME/evangelion.vob
 
 
# Mostrar la información sobre los Streams que componen el fichero. En este caso interesa el  Stream 0:1 (Vídeo de la película) y el 0:2 (idioma castellano).
# Se usa "-probesize 4G -analyzeduration 4G" para que ffmpeg busque bien todos los streams.
ffmpeg -probesize 4G -analyzeduration 4G  -i $HOME/evangelion.vob
...
  Stream #0:0[0x1bf]: Data: dvd_nav_packet
  Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 7000 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Side data:
      cpb: bitrate max/min/avg: 7000000/0/0 buffer size: 1835008 vbv_delay: N/A
  Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s
  Stream #0:3[0x83]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s
  Stream #0:4[0x21]: Subtitle: dvd_subtitle
  Stream #0:5[0x22]: Subtitle: dvd_subtitle
  Stream #0:6[0x20]: Subtitle: dvd_subtitle
  Stream #0:7[0x23]: Subtitle: dvd_subtitle
 
 
# Se genera el fichero mkv dependiendo del idioma que queramos.
ffmpeg -i $HOME/evangelion.vob  -q:a 0 -q:v 0  -map 0:1 -map 0:2  Evangelion_es.mkv # Castellano
ffmpeg -i $HOME/evangelion.vob  -q:a 0 -q:v 0  -map 0:1 -map 0:3  Evangelion_jp.mkv # Japones.

Se podrían incluir subtitulos si se quisiera también usando las opciones de mapeo. En este caso no se conoce qué idioma tienen los subtitulos o los streams de audio, por lo que lo mejor es hacer un par de pruebas hasta que sean identificados y podamos crear el fichero como se crea conveniente, por ejemplo idioma japones pero subtítulos en español.

Cambiar de formato múltiples archivos usando ffmpeg.

Para cambiar múltiples ficheros de una carpeta o punto de montaje (DVD / CD Audio, / etc.) lo más simple es utilizar un bucle. Para el ejemplo propuesto “XXX” sería el formato origen, el formato final al que se quiere transformar los ficheros únicamente hay que indicarlo como extensión. Si no se desea usar las opciones por defecto de cada formato simplemente se debe completar con las opciones ffmpeg pertinentes.

El prompt tiene que estar en el lugar de origen, es decir en el directorio donde se encuentran los ficheros que se quieren transformar.

IFS=$'\n'; for i in *XXX; do ffmpeg -i "${i}" "${i/%.XXX/.mp3}"; done; unset $IFS
 
# Ejemplo webm > mp3
IFS=$'\n'; for i in *webm; do ffmpeg -i "${i}" "${i/%.webm/.mp3}"; done; unset $IFS
 
# Ejemplo flv > ogg
IFS=$'\n'; for i in *flv; do ffmpeg -i "${i}" "${i/%.flv/.ogg}"; done; unset $IFS
 
# Ejemplo con CD de audio: Como en los CDs no se puede escribir, se debe indicar una ruta para el destino.
cd /run/user/1000/gvfs/cdda:host=sr0   # Dirigir el prompt al punto de montaje del CD de audio.
mkdir $HOME/MP3s/   # Se crea el directorio donde se guardarán los ficheros mp3 resultantes.
IFS=$'\n'; for i in *.wav; do ffmpeg -i $i $HOME/MP3s/${i/%.wav/.mp3}; done; unset $IFS

NOTA:Nombres con espacios en blanco soportado mediante el uso de “IFS”.

Transformar cualquier fichero de audio a mp3 (Calidad de 0 a 9, para el ejemplo 4, 0 sería la máxima calidad).

ffmpeg -i fichero.m2a -codec:a libmp3lame -q:a 4 fichero_salida.mp3

Transformar flv a mpg / Transformar mpg a flv.

ffmpeg -i video.flv video.mpg
ffmpeg -i video.mpg -ab 26k -f flv video1.flv

Transformar ficheros avi en mpeg y limitar el fichero resultante a un tamaño determinado (2 Gbytes).

ffmpeg -i video.avi -target pal-dvd -ps 2000000000 -aspect 16:9 video.mpeg

Unir / Fusionar fichero de video con fichero de audio.

ffmpeg -i audio.mp3 -i video.avi video_audio_mix.mpg

Partir / cortar / recortar un vídeo sin pérdida (ej. Los primeros 159 segundos: Desde el segundo 1 se le suman 158).

# Estos cinco comandos deberían tener un fichero resultante prácticamente idéntico. (-t indica duración, -to posición)
ffmpeg -ss 1 -t 158 -i fichero_original -c:v copy -c:a copy fichero_recortado
ffmpeg -ss 0 -t 159 -i fichero_original -c:v copy -c:a copy fichero_recortado
ffmpeg -t 159 -i fichero_original -c:v copy -c:a copy fichero_recortado
ffmpeg -ss 00:00:00.0 -to 00:02:39.0 -i fichero_original -c:v copy -c:a copy fichero_recortado
ffmpeg -to 00:02:39.0 -i fichero_original -c:v copy -c:a copy fichero_recortado
 
# Diferencia entre -t (tiempo) y -to (posición) en ffmpeg.
ffmpeg -i Jazz.webm -ss 01:40:45.0 -to 01:44:34.0 autor_desconocido.mp3 # Corta desde el minuto 01:40:45.0 al 01:44:34.0
ffmpeg -i Jazz.webm -ss 01:40:45.0 -t 00:03:49.0 autor_desconocido.mp3  # Corta desde el minuto 01:40:45.0 al 01:44:34.0
ffmpeg -i Jazz.webm -ss 01:40:45.0 -t 01:44:34.0 autor_desconocido.mp3  # NO es lo mismo que los anteriores comandos. Se cortaría a partir del minuto 01:40:45, una hora, 44 mínutos y 23 segundos.
 
# Ejemplo 2: Cortar VIDEO0118.mp4 desde el principio hasta el minuto 01:36. No es necesario indicar el comienzo.
# ffmpeg -t 00:01:36 -i VIDEO0118.mp4 -c:v copy -c:a copy VIDEO0118_cortado.mp4

Reducir / Aumentar la velocidad de un vídeo.

ffmpeg -i video.mpg -vf "setpts=0.5*PTS" highspeed.mpg
ffmpeg -i video.mpg -vf "setpts=4.0*PTS" lowerspeed.mpg -hide_banner

Agregar banner o imagen a ficheros de audio (convirtiéndolo en formato de vídeo).

ffmpeg -loop 1 -i imagen.jpg -i fichero.mp3 -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4

Agregar subtítulos mediante un fichero srt a un vídeo.

ffmpeg -i video.mp4 -i subtitles.srt -map 0 -map 1 -c copy -c:v libx264 -crf 23 -preset veryfast video-output.mkv

Eliminar subtitulos y cualquier otra cosa que no sea audio y vídeo.

ffmpeg -i input -map 0:v -map 0:a -c copy output

Estabilizar videos grabados con temblores (dos pasos). Adaptar valor de “shakiness” según necesidad.

# Paso 1.
ffmpeg -i VIDEO_TEBLOROSO.avi -vf vidstabdetect=stepsize=6:shakiness=3:accuracy=9:result=vectors.trf -f null -
# Paso 2.
ffmpeg -i VIDEO_TEBLOROSO.avi -vf vidstabtransform=input=vectors.trf:zoom=1:smoothing=30,unsharp=5:5:0.8:3:3:0.4 -vcodec libx264 -preset slow -tune film -crf 18 -acodec copy VIDEO_CORREGIDO.avi

Convertir video 3D en 2D / Elegir idioma.

Los ficheros que contienen varios idiomas y/o subtítulos ocupan más espacio. Si se quiere eliminar todo lo que no es de interés, se puede usar la opción map de ffmpeg par aincluir en el fichero resultanto únicamente los “streams” deseados.

# Mostrar streams de un fichero con ffmpeg.
ffmpeg -i film.mkv 2>&1 | grep Stream
    Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
    Stream #0:1(spa): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:2(jpn): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s (default) (forced)
    Stream #0:3(spa): Subtitle: ass (default) (forced)
    Stream #0:4: Attachment: ttf
    Stream #0:5: Attachment: ttf
    Stream #0:6: Attachment: ttf
 
# Eliminar los subtítulos y el idioma japones, dejando unicamente dos Streams, el vídeo y el idioma español.
ffmpeg -i film.mkv -map 0:0 -map 0:1 -q:v copy -c:a copy film.mkv_only_spa_audio.mkv
# Si se quisiera codificar en mp3 el Stream del audio se ejecutaría el siguiente comando.
# ffmpeg -i film.mkv -map 0:0 -map 0:1 -q:v copy -c:a libmp3lame film_only_spa_audio_mp3.mkv

Los videos en 3D al reproducirlos de manera estándar, sin implementar el 3D, muestran dos “reproducciones” de la película. Esta puede ser dos emisiones en horizontal o bien en vertical donde se reproduce la película, las cuales son superpuestas por los dispositivos compatibles para crear el efecto 3D con ayuda de unas gafas especiales. Para pasar una película 3D a 2D con ffmpeg, simplemente se debe recortar (dividir entre dos horizontal o verticalmente) el ancho (horizontal) o el alto (vertical) del vídeo.

# Lo primero es obtener información del fichero a convertir.
ffmpeg -i fichero3D.mkv
  Metadata:
    encoder         : libebml v1.2.3 + libmatroska v1.3.0
    creation_time   : 2012-11-16 01:32:58
    Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709), 1920x802, SAR 1:1 DAR 960:401, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
    Stream #0:1(spa): Audio: ac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (forced)
    Stream #0:2(eng): Audio: truehd, 48000 Hz, 7.1, s32 (24 bit)
    Stream #0:3(eng): Audio: ac3, 48000 Hz, stereo, fltp, 320 kb/s
    Stream #0:4(spa): Subtitle: subrip
    Stream #0:5(eng): Subtitle: subrip
 
 
# Cuando el vídeo 3D usa dos vídeos en vertical (izquierda / derecha).
ffmpeg -i fichero3D.mkv -map 0:0 -map 0:1 -vf crop=960:802:0:0 -s 1920x802 -b:v 13371k -aspect 1.7777 fichero2D.mkv
 
# Cuando el vídeo 3D usa dos vídeos en horizontal (arriba / abajo).
ffmpeg -i fichero3D.mkv -map 0:0 -map 0:1 -vf crop=960:401:0:0 -s 1920x802 -b:v 13371k -aspect 1.7777 fichero2D.mkv
 
 
# Resolución original del video en 3D: 1920x802. 
# Video 3D vertical: Se divide el primer valor entre dos y el resultado es "960:802".
# Video 3D horizontal: Se divide el primer valor entre dos y el resultado es "1920:401".
# 13371k Es el bitrate del video original en 3D.
# El aspecto puede ser definido como 4:3 (1.3333) o 16:9 (1.7777), que es el formato panorámico.
# "-map 0:0 -map 0:1" Video y audio en castellano, si se quisiera en inglés "-map 0:0 -map 0:2" o "-map 0:0 -map 0:3".
 
######### Especificando un codec de audio y vídeo.
 
# ffmpeg -i fichero3D.mkv -map 0:0 -map 0:1 -vcodec h264 -acodec ac3 -vf crop=960:802:0:0 -s 1920x802 -b:v 13371k -aspect 1.7777 fochero2D.mkv
 
# Si queremos utilizar el mismo formato de audio y vídeo que el original se debe que especificar. (en este caso el tamaño del fichero resultante aumentaría y habría muy poca ganancia de calidad). 
# En este caso la opción "-map" no especifica el formato ya que no se toma el fichero origen como un todo, si no que estamos recortando el mismo para crear otro fichero. 
# Por ese mismo motivo especificar la opción de "copy" para codecs de vídeo y audio no es funcional y entra en conflicto con "-vf crop=960:802:0:0". 
# Si no se especifica un codec utilizará para el vídeo "mpeg4" y para el audio "mp3" (más compatibles con televisores antiguos).
 
# Formatos ffmpeg: https://www.ffmpeg.org/ffmpeg-formats.html

Subir el volumen de un vídeo.

Indicar el formato de audio puede ser necesario si intenta usar de manera predeterminado un formato diferente al del fichero original. Conocer el formato actual de audio de un vídeo se puede hacer mediante “ffmpeg -i”.

ffmpeg -i  fichero.mkv
...
    Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
    Stream #0:1(eng): Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s (default)   # <------ Formato mp3.
 
# Se sube el volumen un 350% con respecto al volumen original. Se mantiene la calidad de vídeo.
ffmpeg -i fichero.mkv -filter:a "volume=3.5" -c:v copy -acodec mp3 test.mkv

Más información sobre conversiones de volumen con ffmpeg: https://trac.ffmpeg.org/wiki/AudioVolume

Quitar ruido de fondo a un vídeo o fichero de audio

Depende del microfono y la configuración del mismo, puede que un determinado audio muestre un ruido de fondo. Este puede ser eliminado con la aplicación sox de manera fácil.

# Cortar un fragmento donde esté el ruido de fondo sin ningún otro ruido más (música, diálogos, etc). 
# Por norma ese ruido de fondo estará al principio o al final del fichero.
# En el ejemplo extraemos el primer segundo, pero podrían usarse centésimas de segundo si se necesita.
ffmpeg -i fichero.mp3 -ss 00:00:00.0 -t 00:00:1 fichero_ruido.mp3
 
# Se genera el fichero noise.prof
sox fichero_ruido.mp3 -n noiseprof noise.prof
 
# Se elimina el ruido, valores que suelen funcionar bien son 0.21 - 0.30.
sox fichero.mp3 fichero_limpio.mp3 noisered noise.prof 0.21

En el ejemplo se ha visto el proceso con un fichero mp3. Si el fichero es un vídeo, habría que extraer primero el audio, limpiarlo y luego fusionarlo von el vídeo.

Concatenar / Unir varios ficheros de vídeo en uno solo.

cd /ruta/
for f in ./*.AVI; do echo "file '$f'" >> mylist.txt; done   # Se genera un fichero con los ficheros de la carpeta.
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.avi   # Se concatenan los ficheros.

Sincronizar audio / video con ffmpeg.

Cuando los vídeos tienen la imagen y el audio descompasados encontramos dos supuestos.

  1. El audio está retrasado / El vídeo esta adelantado.
  2. El audio está adelantado / El vídeo esta retrasado.

Con ffmpeg podemos siempre retrasar el audio y/o el vídeo y es en lo que basaremos esta solución cuando nos enfrentemos a vídeos no correctamente sincronizados. Lo primero que se debe hacer es conocer cuantos milisegundos de desincronización hay que corregir. Se puede usar mplayer para reproducir el vídeo y con el símbolo + / - se va sincronizando fácilmente hasta encontrar el valor perfecto, cada vez que pulsemos se mostrará en la pantalla los milisegundos aplicados. Supongamos para el ejemplo que hay un retardo en el vídeo de 1.7s, es decir el audio está adelantado 1.7 segundos.

# Se le asigna un retardo de 1.7 segundos al video.
ffmpeg -i video1.webm -af "adelay=1700|1700" -vcodec copy "video_sincornizado"

Esta solución es útil únicamente cuando el audio debe ser retrasado, pero no sirve cuando el audio está ya retrasado (vídeo adelantado) y debería adelantarse. A continuación se propone una opción que funciona en ambas direcciones. El proceso se basa en indicar a ffmpeg que utilice como fichero entrada dos veces el mismo fichero que se quiere reparar. De esta manera se podrá identificar como ffmpeg numera “Streams” de audio y vídeo para cada uno de ellos, es decir mínimo se dispondrá de 4 Streams. Los cuales podrán se retrasados como queramos a la hora de crear un fichero bien sicronizado.

ffmpeg -i XXX.mkv -i XXX.mkv 2>&1 | grep Stream
    Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p, 720x384 [SAR 1:1 DAR 15:8], 2097 kb/s, 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
    Stream #0:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), fltp, 448 kb/s
 
    Stream #1:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p, 720x384 [SAR 1:1 DAR 15:8], 2097 kb/s, 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
    Stream #1:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), fltp, 448 kb/s

Se le aplica el delay a uno de las dos entradas (-i), como siempre se trabaja sobre el mismo fichero dará igual cual seleccionemos, pero en el ejemplo usaremos el primero para aplicarle ese retardo de 1.7 segundos con la opción “-itsoffset”. Por lo tanto el primera archivo (0:0 y 0:1) tendrá el retraso indicado. Al fichero salida se le debe indicar que combine un stream de audio o vídeo (dependiendo de lo que esté descompasado) de la primera entrada con ese retardo de 1.7 segundos con unos de los dos streams de la segunda. Veamos un ejemplo para entenderlo mejor.

# El audio está retrasado / El vídeo esta adelantado: La solución es retrasar el vídeo.
# -map 0:0 -map 1:1 Vídeo del primer archivo (con retraso) + Audio del segundo fichero.
ffmpeg -itsoffset 1.7 -i "XXX.mkv" -i "XXX.mkv" -map 0:0 -map 1:1 -acodec copy -vcodec copy "XXX_sync.mkv"
 
# El audio está adelantado / El vídeo esta retrasado: La solución es retrasar el audio. (Se podría usar también la solución propuesta anteriormente con "adelay", la cual necesita menos parámetros).
# -map 0:1 -map 1:0 Audio del primer archivo (con retraso) + Vídeo del segundo fichero.
ffmpeg -itsoffset 1.7 -i "XXX.mkv" -i "XXX.mkv" -map 0:1 -map 1:0 -acodec copy -vcodec copy "XXX_sync.mkv"

Error al querer sincronizar audio / video.

Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly

Si el archivo no tiene información de tiempos, la única solución en este caso pasa por convertir el fichero de formato y luego realizar el ajuste con el nuevo fichero. Hay algoritmos de compresión sin pérdida pero se debe tener en cuenta que estos ocuparan demasiado espacio en disco, como son HuffYuv (en ffmpeg denominado ffvhuff). Veamos un ejemplo pasando de AVI a MPEG intentando perder el mínimo posible de calidad.

ffmpeg -i Fichero_sin_timestamp.avi -q:v 0 nuevo_fichero.mpeg
# Ahora ya se podría intentar de nuevo la sincronización pero usando como fuente el nuevo archivo "nuevo_fichero.mpeg".

NOTA: Hay archivos que tienen múltiples partes desincronizadas y a diferentes tiempos, por lo que este método no ayudaría a resolver el problema en este tipo de casos.

Reparar ficheros multimedia con ffmpeg.

Cuando un vídeo se reproduce bien en el sistema operativo con aplicaciones tipo mplayer, VLC, etc pero este tiene problemas al reproducirse en un dispositivo supuestamente compatible con el formato, como una smart TV. Una posible solución es que ffmpeg genere un nuevo fichero a partir del original (en el ejemplo se respeta la calidad de audio y vídeo).

ffmpeg -i fichero_problemático.avi -c:v copy -c:a copy fichero.avi

Girar / Rotar un vídeo

Depende del dispositivo de grabación y su uso los vídeos pueden ser grabados en vertical (90° o 270°) u horizontal (0° o 270°). Los 0° se considera cuando se filma en horizontal, teniendo la parte del micrófono a la derecha y la parte del altavoz en la izquierda. Los valores de rotación son incluidos como metadatos en los vídeos.

Si simplemente se ha grabado un vídeo con un dispositivo móvil y el giroscopio ha provocado que la filmacion incluya información sobre rotación que dificulta su visualización. La solución es borrar el metadato concreto para que pueda reproducirse en el dispositivo. En casos donde hay un vídeo horizontal grabado desde un celular y debe verse en horizontal en otro dispositivo, por ejemplo un laptop, se debe tener en cuenta otros factores.

Para transformar un vídeo de horizontal a vertical (o al contrario) se deben modificar los valores de rotación y luego cambiar el alto y ancho del vídeo. Lo primero que debe hacerse es obteber información sobre la rotación del vídeo y su resolución.

# Rotación de 90.00 y resolución 1280x720.
ffmpeg -i fichero.MOV 2>&1 | grep "displaymatrix\|Video:"
 
  Stream #0:0[0x1](und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1280x720, 10548 kb/s, 23.99 fps, 23.98 tbr, 600 tbn (default)
      displaymatrix: rotation of -90.00 degrees

Eliminar rotación.

ffmpeg -i fichero.mov -c copy -metadata:s:v:0 rotate=0 fichero_sin_rotacion.mov

Rotar el vídeo usando la opción transpose. Se pueden usar números o bien los nombres cclock_flip, clock_flip, clock y cclock. Esto obliga a una recodificación del vídeo por lo que puede jugarse con valores que definan la calidad del fichero resultante.

# Parámetro -vf "transpose=0"

0 cclock_flip En sentido contrario a las agujas del reloj y en sentido vertical (por defecto).
3 clock_flip  En el sentido de las agujas del reloj y en sentido vertical.
1 clock       En el sentido de las agujas del reloj.
2 cclock      En sentido contrario a las agujas del reloj.
 # Rotación de 90° a la derecha.
ffmpeg -i fichero_sin_rotacion.mov -vf "transpose=clock" -c:a copy fichero_rotacion_ok.mov
# Rotación de 180° a la izquierda.
ffmpeg -i fichero_sin_rotacion.mov -vf "transpose=2,transpose=2" -c:a copy fichero_rotacion_ok.mov
# Rotación de 180° a la derecha.
ffmpeg -i fichero_sin_rotacion.mov -vf "transpose=1,transpose=1" -c:a copy fichero_rotacion_ok.mov

Si ahora se usa “ffmpeg -i” para obtener información sobre el vídeo no debería existir rotación y la resolución debería haber sido invertida.

Streaming básico con ffmpeg / mplayer: https://trac.ffmpeg.org/wiki/StreamingGuide

# Dejamos a mplayer escuchando en un puerto, en este caso el 4444.
mplayer ffmpeg://tcp://0.0.0.0:4444?listen
 
# Desde una ubicación remota emitimos la reproducción de un fichero mkv a la IP y puerto donde mplayer escucha.
ffmpeg -i file.mkv -preset ultrafast -vcodec libx264 -tune zerolatency -f mpegts tcp://X.X.X.X:4444
 
# Transmitir por streaming el escritorio (FullHD).
ffmpeg -f alsa -i default -f x11grab -s 1920x1080 -r 30 -i :0.0 -preset ultrafast -vcodec libx264 -tune zerolatency -f mpegts tcp://X.X.X.X:4444

Playlist de audio / vídeo para emitir en streaming.

# Crear una playlist, por ejemplo de películas mkv.
find /home/busi/ -type f -iname "*.mkv" > playlist.m3u
 
# Editamos la lista para que tega este formato: "file ruta".
 
file '/home/user/Peliculas/Documentales/video1.mkv'
file /home/user/Pelicula/Musical/L’Entourloop\ -\ 2017\ -\ Le\ Savoir\ Faire\ \[FLAC\]/18\ -\ Le\ bonheur\ feat\ Panda\ Dub.mkv
...
 
# Dejamos por ejemplo a mplayer escuchando, aunque podría ser VLC y a la vez servir ese streaming a múltiples clientes.
mplayer -cache 4096 ffmpeg://tcp://0.0.0.0:4444?listen
 
# Usamos la lista de reproducción concatenando un vídeo con otro.
ffmpeg -f concat -safe 0 -i playlist.m3u -preset ultrafast -vcodec libx264 -tune zerolatency -f mpegts  tcp://X.X.X.X:4444
 
# Si fuera música, simplemente necesitaríamos ejecutar este comando.
ffmpeg -f concat -safe 0 -i playlist.m3u -f mpegts  tcp://X.X.X.X:4444
 
# NOTA: Se recomienda usar videos / audios con similares características y formatos (o bién enviarlos por streaming mientras son transformados).

Hacer un vídeo del escritorio con ffmpeg en GNU/Linux: https://www.busindre.com/grabar_el_escritorio_con_ffmpeg