0

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.

Thunderssucks
  • 29
  • 1
  • 8

3 Answers3

2

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

Guest
  • 21
  • 2
  • 1
    The linked page is not in English. Don't use a blanket `except`. Your indentation is clearly wrong; please [edit] to fix it. On the desktop version of this site, you can get code marked up for you by pasting your code, selecting the pasted block, and typing ctrl-K. – tripleee Feb 10 '22 at 11:52
1
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))
Thunderssucks
  • 29
  • 1
  • 8
  • Please show how to get the values `vid_size`, `mp3_size` and `duration`. – Rotem Jun 07 '21 at 09:04
  • It's a nice approach, but it's not working when the audio take large portion of the file size. I executed your code on the synthetic output of `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 test.mp4'))`, and the `bitrate` result is `-13`. – Rotem Jun 07 '21 at 12:38
  • I am sure vid_size would be enough and even more accurate. – Thunderssucks Jun 08 '21 at 12:32
  • This returns the value in MB, right? – Jana.k Jul 20 '22 at 19:18
0

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}')
Rotem
  • 30,366
  • 4
  • 32
  • 65
  • I've put path to my file and got: FileNotFoundError: [WinError 2] The system cannot find the file specified – Thunderssucks Jun 04 '21 at 08:53
  • Make sure that `ffmpeg.exe` and `ffprobe.exe` are in the execution path (or use full path). In Windows there is no specific place for `ffmpeg.exe` and `ffprobe.exe` . Copy them to the same folder as your Python script (just for testing). – Rotem Jun 04 '21 at 08:57
  • Did you solve the problem? You may follow the instruction: [How to Install FFmpeg on Windows](https://www.wikihow.com/Install-FFmpeg-on-Windows). If you don't add the folder to the system path, replace `ffmpeg` with `'C:\\ffmpeg\\bin\\ffmpeg` (assuming you placed ffmpeg.exe and ffprobe.exe in `C:\ffmpeg\bin`. I also updated the answer for formats that has no bitrate information. – Rotem Jun 04 '21 at 09:38
  • Thanks for the answer. But there is a much easier solution: bitrate = int((((vid_size - mp3_size)/duration)/1024*8)) – Thunderssucks Jun 07 '21 at 08:57