【问题标题】:Determine video bitrate Python [duplicate]确定视频比特率Python [重复]
【发布时间】:2021-06-04 08:08:40
【问题描述】:

我从 Telegram 下载了一个视频,我需要确定它的比特率。 我有moviepy(pip install moviepy,不是开发者版本)。 另外,我有ffmpeg,但我不知道如何在python中使用它。 此外,任何其他图书馆都可以为我工作。

【问题讨论】:

  • @AlokRaj 没有找到真正有效的示例。不知道ffmeg怎么用(console?+python?)

标签: python ffmpeg moviepy


【解决方案1】:

这是一个使用 FFprobe 的解决方案:

  • ffprobe(命令行工具)作为子进程执行,读取stdout的内容。
    使用参数 -print_format json 获取 JSON 格式的输出。
    要仅获取 bit_rate 条目,请添加参数 -show_entries stream=bit_rate
  • 使用dict = json.loads(data)将返回的字符串转换为字典。
  • 从字典中获取比特率并将其转换为int:bit_rate = int(dict['streams'][0]['bit_rate'])

代码示例创建一个示例视频文件进行测试(使用FFmpeg),并获取比特率(使用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}')

注意事项:

  • 对于某些视频容器,如 MKV,没有bit_rate 信息,因此需要不同的解决方案。
  • 代码示例假定 ffmpeg 和 ffprobe(命令行工具)在执行路径中。

没有bit_rate信息的容器的解决方案(如MKV):

基于以下post,我们可以将所有视频包的大小相加。
我们还可以总结所有数据包的持续时间。
平均比特率等于:total_size_in_bits / total_duration_in_seconds

这里是计算 MKV 视频文件平均比特率的代码示例:

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}')

【讨论】:

  • 我已经把路径放到我的文件中,得到:FileNotFoundError: [WinError 2] 系统找不到指定的文件
  • 确保ffmpeg.exeffprobe.exe 在执行路径中(或使用完整路径)。在 Windows 中,ffmpeg.exeffprobe.exe 没有特定的位置。将它们复制到与 Python 脚本相同的文件夹中(仅用于测试)。
  • 问题解决了吗?您可以按照以下说明操作:How to Install FFmpeg on Windows。如果您不将文件夹添加到系统路径,请将ffmpeg 替换为'C:\\ffmpeg\\bin\\ffmpeg(假设您将ffmpeg.exe 和ffprobe.exe 放在C:\ffmpeg\bin 中。我还更新了没有比特率信息的格式的答案。
  • 感谢您的回答。但是有一个更简单的解决方案:bitrate = int((((vid_size - mp3_size)/duration)/1024*8))
【解决方案2】:
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))

【讨论】:

  • 请说明如何获取值vid_sizemp3_sizeduration
  • 这是一个不错的方法,但是当音频占据文件大小的大部分时,它就不起作用了。我在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')) 的合成输出上执行了你的代码,bitrate 结果是-13
  • 我相信 vid_size 就足够了,甚至更准确。
【解决方案3】:

http://timivanov.ru/kak-uznat-bitrate-i-fps-video-ispolzuya-python-i-ffmpeg/ 试试这个:

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

例外为 er: 返回 er

【讨论】:

  • 链接页面不是英文的。不要使用毯子except。您的缩进显然是错误的;请edit 修复它。在本网站的桌面版本中,您可以通过粘贴代码、选择粘贴的块并输入 ctrl-K 来为您标记代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多