skip to Main Content

I have a video downloaded from Telegram and I need to determine its bitrate.
I have moviepy (pip install moviepy, not the developer version).
Also, I have ffmpeg, but I don’t know how to use it in python.
Also, any other library would work for me.

3

Answers


  1. Chosen as BEST ANSWER
    import moviepy.editor as mp
    
    video = mp.VideoFileClip('vid.mp4')
    mp3 = video.audio
    if mp3 is not None:
        mp3.write_audiofile("vid_audio.mp3")
    mp3_size =  os.path.getsize("vid_audio.mp3")
    vid_size = os.path.getsize('vid.mp4')
    duration = video.duration
    
    
    bitrate = int((((vid_size - mp3_size)/duration)/1024*8))
    

  2. Here is a solution using FFprobe:

    • Execute ffprobe (command line tool) as sub-process and read the content of stdout.
      Use the argument -print_format json for getting the output in JSON format.
      For getting only the bit_rate entry, add argument -show_entries stream=bit_rate.
    • Convert the returned string to dictionary using dict = json.loads(data).
    • Get the bitrate from the dictionary and convert it to int: bit_rate = int(dict['streams'][0]['bit_rate']).

    The code sample creates a sample video file for testing (using FFmpeg), and get the bitrate (using FFprobe):

    import subprocess as sp
    import shlex
    import json
    
    input_file_name = 'test.mp4'
    
    # Build synthetic video for testing:
    ################################################################################
    sp.run(shlex.split(f'ffmpeg -y -f lavfi -i testsrc=size=320x240:rate=30 -f lavfi -i sine=frequency=400 -f lavfi -i sine=frequency=1000 -filter_complex amerge -vcodec libx264 -crf 17 -pix_fmt yuv420p -acodec aac -ar 22050 -t 10 {input_file_name}'))
    ################################################################################
    
    # Use FFprobe for 
    # Execute ffprobe (to get specific stream entries), and get the output in JSON format
    data = sp.run(shlex.split(f'ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -print_format json {input_file_name}'), stdout=sp.PIPE).stdout
    dict = json.loads(data)  # Convert data from JSON string to dictionary
    bit_rate = int(dict['streams'][0]['bit_rate'])  # Get the bitrate.
    
    print(f'bit_rate = {bit_rate}')
    

    Notes:

    • For some video containers like MKV, there is no bit_rate information so different solution is needed.
    • The code sample assumes that ffmpeg and ffprobe (command line tools) are in the execution path.

    Solution for containers that has no bit_rate information (like MKV):

    Based on the following post, we can sum the size of all the video packets.
    We can also sum all the packets durations.
    The average bitrate equals: total_size_in_bits / total_duration_in_seconds.

    Here is a code sample for computing average bitrate for MKV video file:

    import subprocess as sp
    import shlex
    import json
    
    input_file_name = 'test.mkv'
    
    # Build synthetic video for testing (MKV video container):
    ################################################################################
    sp.run(shlex.split(f'ffmpeg -y -f lavfi -i testsrc=size=320x240:rate=30 -f lavfi -i sine=frequency=400 -f lavfi -i sine=frequency=1000 -filter_complex amerge -vcodec libx264 -crf 17 -pix_fmt yuv420p -acodec aac -ar 22050 -t 10 {input_file_name}'))
    ################################################################################
    
    # https://superuser.com/questions/1106343/determine-video-bitrate-using-ffmpeg
    # Calculating the bitrate by summing all lines except the last one, and dividing by the value in the last line.
    data = sp.run(shlex.split(f'ffprobe -select_streams v:0 -show_entries packet=size,duration -of compact=p=0:nk=1 -print_format json {input_file_name}'), stdout=sp.PIPE).stdout
    dict = json.loads(data)  # Convert data from JSON string to dictionary
    
    # Sum total packets size and total packets duration.
    sum_packets_size = 0
    sum_packets_duration = 0
    for p in dict['packets']:
        sum_packets_size += float(p['size'])  # Sum all the packets sizes (in bytes)
        sum_packets_duration += float(p['duration'])  # Sum all the packets durations (in mili-seconds).
    
    # bitrate is the total_size / total_duration (multiply by 1000 because duration is in msec units, and by 8 for converting from bytes to bits).
    bit_rate = (sum_packets_size / sum_packets_duration) * 8*1000
    
    print(f'bit_rate = {bit_rate}')
    
    Login or Signup to reply.
  3. http://timivanov.ru/kak-uznat-bitrate-i-fps-video-ispolzuya-python-i-ffmpeg/
    try this:

    def get_bitrate(file):
    try:
       probe = ffmpeg.probe(file)
       video_bitrate = next(s for s in probe['streams'] if s['codec_type'] == 'video')
       bitrate = int(int(video_bitrate['bit_rate']) / 1000)
       return bitrate
    

    except Exception as er:
    return er

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search