Aprende a obtener fácilmente información sobre el audio, las pistas de video y los metadatos de un archivo multimedia con ffprobe.

Al trabajar con FFMPEG desde la línea de comandos, siempre hemos soñado con algún tipo de característica que nos permitiera proceder con la ejecución de una instrucción que solo funciona si el archivo a usar cumple algunas características especiales como el número de streams, el codec, u otras cosas.

En caso de que estés trabajando con FFMPEG a través de la línea de comandos y manipulándolo con un lenguaje de programación como Python, JavaScript, PHP o cualquier otro lenguaje, puedes obtener una capa adicional condicional de información sobre los archivos de entrada usando FFPROBE antes de trabajar en el archivos con FFMPEG. FFPROBE recopila información de flujos multimedia y la imprime de manera legible por humanos y máquinas y también viene con FFMPEG. Por ejemplo, se puede utilizar para comprobar el formato del contenedor utilizado por un flujo multimedia y el formato y tipo de cada flujo multimedia contenido en él.

Esta información podría ser manejada por cualquier lenguaje de programación que sea capaz de analizar el formato JSON. En este artículo, le mostraré un comando muy básico para extraer información sobre los archivos multimedia antes de procesarlos usando FFPROBE (FFMPEG).

Extrayendo información

El comando para extraer la información de un archivo multimedia usando ffprobe en formato JSON es el siguiente y cada opción se describe a continuación:

  • -loglevel -8: No muestra nada absoluto de la salida de ffprobe. Si se produce algún error y no se puede extraer información, el proceso no fallará, pero devolverá un JSON vacío.
  • -print_format <format>: Establece el formato de impresión de salida en formato JSON, INI, XML o CSV.
  • -show_format: Esta opción muestra información sobre el formato contenedor del flujo multimedia de entrada. Toda la información del formato del contenedor se imprime dentro de una sección con el nombre "FORMATO".
  • -show_streams: Esta opción muestra información sobre cada flujo multimedia contenido en el flujo multimedia de entrada. La información de cada flujo de medios se imprime dentro de una sección dedicada (un elemento de matriz) con el nombre "STREAM".
ffprobe -loglevel 0 -print_format json -show_format -show_streams <input-file.{avi,mp3,mp4,mkv}>

Esto imprimirá una salida JSON similar a la siguiente en tu terminal (por supuesto, dependiendo del formato de entrada del archivo y el contenido, cambiará, en este caso, estamos ejecutando el comando con un archivo de audio MP3):

{
    "streams": [
        {
            "index": 0,
            "codec_name": "mp3",
            "codec_long_name": "MP3 (MPEG audio layer 3)",
            "codec_type": "audio",
            "codec_time_base": "1/44100",
            "codec_tag_string": "[0][0][0][0]",
            "codec_tag": "0x0000",
            "sample_fmt": "fltp",
            "sample_rate": "44100",
            "channels": 2,
            "channel_layout": "stereo",
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/14112000",
            "start_pts": 353600,
            "start_time": "0.025057",
            "duration_ts": 7566336000,
            "duration": "536.163265",
            "bit_rate": "192000",
            "disposition": {
                "default": 0,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "encoder": "Lavc57.64"
            }
        }
    ],
    "format": {
        "filename": "November Rain.mp3",
        "nb_streams": 1,
        "nb_programs": 0,
        "format_name": "mp3",
        "format_long_name": "MP2/3 (MPEG audio layer 2/3)",
        "start_time": "0.025057",
        "duration": "536.163265",
        "size": "12868682",
        "bit_rate": "192011",
        "probe_score": 51,
        "tags": {
            "major_brand": "dash",
            "minor_version": "0",
            "compatible_brands": "iso6mp41",
            "encoder": "Lavf57.56.101"
        }
    }
}

En caso de que no desees extraer esta información de la salida del comando, también puedes almacenar esa información dentro de un archivo que redirecciona la salida:

ffprobe -v quiet -print_format json -show_format -show_streams myinputfile.mp3 > output_file.json

Por supuesto, dependiendo de tus necesidades, es posible que también necesites registrar errores o mostrar más información sobre los archivos. Puedes consultar la documentación oficial de ffprobe para agregar nuevas opciones a tu comando para detectar errores o información que pueda aparecer con otras opciones adicionales. Por ejemplo:

ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams -show_programs -show_chapters -show_private_data -print_format json <input-file.{mp3,mp4,mkv,avi}>

Esto saldría, por ejemplo, de un video MP4:

{
    "programs": [

    ],
    "streams": [
        {
            "index": 0,
            "codec_name": "h264",
            "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
            "profile": "High",
            "codec_type": "video",
            "codec_time_base": "1001/120000",
            "codec_tag_string": "avc1",
            "codec_tag": "0x31637661",
            "width": 3840,
            "height": 2160,
            "coded_width": 3840,
            "coded_height": 2160,
            "closed_captions": 0,
            "has_b_frames": 0,
            "sample_aspect_ratio": "1:1",
            "display_aspect_ratio": "16:9",
            "pix_fmt": "yuv420p",
            "level": 52,
            "chroma_location": "left",
            "refs": 1,
            "is_avc": "true",
            "nal_length_size": "4",
            "r_frame_rate": "60000/1001",
            "avg_frame_rate": "60000/1001",
            "time_base": "1/60000",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 12018006,
            "duration": "200.300100",
            "bit_rate": "9024217",
            "bits_per_raw_sample": "8",
            "nb_frames": "12006",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "creation_time": "2021-01-01T18:10:32.000000Z",
                "language": "eng",
                "handler_name": "Mainconcept MP4 Video Media Handler",
                "encoder": "AVC Coding"
            }
        },
        {
            "index": 1,
            "codec_name": "aac",
            "codec_long_name": "AAC (Advanced Audio Coding)",
            "profile": "LC",
            "codec_type": "audio",
            "codec_time_base": "1/48000",
            "codec_tag_string": "mp4a",
            "codec_tag": "0x6134706d",
            "sample_fmt": "fltp",
            "sample_rate": "48000",
            "channels": 2,
            "channel_layout": "stereo",
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/48000",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 9614336,
            "duration": "200.298667",
            "bit_rate": "189465",
            "max_bit_rate": "340123",
            "nb_frames": "9389",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "creation_time": "2021-01-01T18:10:32.000000Z",
                "language": "eng",
                "handler_name": "Mainconcept MP4 Sound Media Handler"
            }
        }
    ],
    "chapters": [

    ],
    "format": {
        "filename": "how-to-fix-windows-10-issue-that-displays-internal-sata-connected-ssd-hdd-as-removable.mp4",
        "nb_streams": 2,
        "nb_programs": 0,
        "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
        "format_long_name": "QuickTime / MOV",
        "start_time": "0.000000",
        "duration": "200.300100",
        "size": "230790875",
        "bit_rate": "9217803",
        "probe_score": 100,
        "tags": {
            "major_brand": "mp42",
            "minor_version": "0",
            "compatible_brands": "isommp42",
            "creation_time": "2021-01-01T18:10:30.000000Z"
        }
    }
}

Que te diviertas ❤️!


Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores