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.
Asked
Active
Viewed 4,633 times
0
-
@AlokRaj Didn't find a really working example. Don't know how to use ffmeg (console? +python?) – Thunderssucks Jun 04 '21 at 08:34
3 Answers
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
-
1The 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
-
-
0
Here is a solution using FFprobe:
- Execute
ffprobe
(command line tool) as sub-process and read the content ofstdout
.
Use the argument-print_format json
for getting the output in JSON format.
For getting only thebit_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