How to detect video bitrate from HLS/M3U8 file using ffprobe

14,354

Solution 1

the best way to detect the average bandwidth is combine ffmpeg and pv command like this:

ffmpeg  -re -i input.m3u8 -f flv - 2>/dev/null|pv -a >/dev/null

You may have to install pv apt-get install pv Hope it helped you.

Solution 2

For the video bitrate you can do:

ffprobe -select_streams v:0 -show_entries frame=pkt_size,pkt_duration_time <input>

to get the compressed packet sizes and durations (in bytes and respectively seconds) for a series of frames. Run it for a while then calculate the average bitrate for the total duration.

Solution 3

In this sample above, I know that video is around 520Kbps, but need to find a way to read that programatically with either ffprobe or any other way.

The text in your shown HLS file has an entry: AVERAGE-BANDWIDTH : 599686
FFProbe says AAC audio bitrate is : 79 kb/s

To get the video bitrate you can do this formula:

HLS Average-Bandwidth minus FFProbe Audio-Bitrate = estimated video bitrate

With your numbers... (599686 - 79000) = 520686.

This actually confirms your "I know that video is around 520Kbps". Simply get the HLS text file into a String and use some String functions (or even Regular Expressions) to extract the first number.

Hope it helps.

Share:
14,354
Guillermo
Author by

Guillermo

Updated on August 10, 2022

Comments

  • Guillermo
    Guillermo over 1 year

    We need to detect the video bitrate of a HLS stream with ffprobe by using the m3u8 file of the .ts.

    If I use the m3u8, I can get the duration, dimensions, codecs used, audio bitrate, but no video bitrate is available in the response provided by ffprobe.

    ffprobe -print_format json -show_format -show_streams -show_error http://gfrmedia-video-platform.s3.amazonaws.com/bumbia/2014/06/06/158217_20160126214307_bumbia-hls/hls1056k/158217_640x360-with-mp4-hls_bumbia-hls.m3u8
    
    ffprobe version 2.8.3 Copyright (c) 2007-2015 the FFmpeg developers
      built with Apple LLVM version 7.0.0 (clang-700.1.76)
      configuration: --prefix=/usr/local/Cellar/ffmpeg/2.8.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libvo-aacenc --enable-libxvid --enable-vda
      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
    {
    [http @ 0x7fcf09e19420] No trailing CRLF found in HTTP header.
    Input #0, hls,applehttp, from 'http://gfrmedia-video-platform.s3.amazonaws.com/bumbia/2014/06/06/158217_20160126214307_bumbia-hls/hls1056k/158217_640x360-with-mp4-hls_bumbia-hls.m3u8':
      Duration: 00:00:11.00, start: 9.940500, bitrate: 0 kb/s
      Program 0
        Metadata:
          variant_bitrate : 0
        Stream #0:0: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
        Stream #0:1: Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 79 kb/s
        "streams": [
            {
                "index": 0,
                "codec_name": "h264",
                "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
                "profile": "Constrained Baseline",
                "codec_type": "video",
                "codec_time_base": "1001/60000",
                "codec_tag_string": "[27][0][0][0]",
                "codec_tag": "0x001b",
                "width": 640,
                "height": 360,
                "coded_width": 640,
                "coded_height": 368,
                "has_b_frames": 0,
                "sample_aspect_ratio": "1:1",
                "display_aspect_ratio": "16:9",
                "pix_fmt": "yuv420p",
                "level": 30,
                "chroma_location": "left",
                "refs": 1,
                "is_avc": "0",
                "nal_length_size": "0",
                "r_frame_rate": "30000/1001",
                "avg_frame_rate": "30000/1001",
                "time_base": "1/90000",
                "start_pts": 900000,
                "start_time": "10.000000",
                "bits_per_raw_sample": "8",
                "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
                }
            },
            {
                "index": 1,
                "codec_name": "aac",
                "codec_long_name": "AAC (Advanced Audio Coding)",
                "profile": "LC",
                "codec_type": "audio",
                "codec_time_base": "1/44100",
                "codec_tag_string": "[15][0][0][0]",
                "codec_tag": "0x000f",
                "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/90000",
                "start_pts": 894645,
                "start_time": "9.940500",
                "bit_rate": "79931",
                "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
                }
            }
        ],
        "format": {
            "filename": "http://gfrmedia-video-platform.s3.amazonaws.com/bumbia/2014/06/06/158217_20160126214307_bumbia-hls/hls1056k/158217_640x360-with-mp4-hls_bumbia-hls.m3u8",
            "nb_streams": 2,
            "nb_programs": 1,
            "format_name": "hls,applehttp",
            "format_long_name": "Apple HTTP Live Streaming",
            "start_time": "9.940500",
            "duration": "11.000000",
            "size": "281",
            "bit_rate": "204",
            "probe_score": 100
        }
    }
    

    In this sample above, I know that video is around 520Kbps, but need to find a way to read that programatically with either ffprobe or any other way. With what I currently have I can get most of the information needed, but I'm missing one important value that is the video bitrate.

    What other options could I try?

    Thanks!

  • danday74
    danday74 over 2 years
    where do you get 599686 from? thx
  • VC.One
    VC.One over 2 years
    @danday74 It was from the text of m3u8 file provided by Asker.