You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取视频每帧真实存储大小以计算每秒比特率?

问题原因及解决方案

你当前代码计算的是解码后原始像素帧的大小,而视频文件里存储的是经过编码压缩后的帧数据(比如H.264、AV1这类编码格式),两者完全不是一个概念——原始像素帧大小只和分辨率、位深有关,和视频的压缩率、编码格式无关,所以自然和文件实际总大小对不上。

要获取视频每帧的真实存储大小,推荐用以下方法:

方法一:用ffprobe直接获取(最简便可靠)

ffprobe是FFmpeg套件里的工具,能直接读取视频容器中的帧元数据,包括每帧的压缩后字节大小。

步骤:

  1. 先确保你的环境安装了FFmpeg(包含ffprobe工具)
  2. 用Python调用ffprobe命令解析帧大小,示例代码:
import subprocess
import os

def get_frame_sizes(video_path):
    # 调用ffprobe提取视频流每帧的字节大小
    cmd = [
        "ffprobe",
        "-select_streams", "v:0",  # 选择第一个视频流
        "-show_entries", "frame=pkt_size",  # 只获取帧的数据包大小
        "-of", "csv=p=0",  # 输出格式为纯文本每行一个数值
        "-hide_banner",
        "-loglevel", "error",
        video_path
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        raise RuntimeError(f"解析失败: {result.stderr}")
    # 转换为整数列表,每个元素对应一帧的字节数
    return [int(line) for line in result.stdout.strip().split("\n") if line]

def get_video_fps(video_path):
    # 获取视频帧率
    cmd = [
        "ffprobe",
        "-select_streams", "v:0",
        "-show_entries", "stream=r_frame_rate",
        "-of", "csv=p=0",
        "-hide_banner",
        "-loglevel", "error",
        video_path
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    fps_str = result.stdout.strip()
    num, den = map(int, fps_str.split("/"))
    return num / den

# 示例使用
video_file = "your_video.mp4"
frame_sizes = get_frame_sizes(video_file)
total_frame_size = sum(frame_sizes)
fps = get_video_fps(video_file)

print(f"所有帧总大小(字节): {total_frame_size}")
print(f"文件实际大小(字节): {os.stat(video_file).st_size}")
print(f"平均每帧大小(字节): {total_frame_size / len(frame_sizes):.2f}")

# 计算每秒比特率(bps):平均帧大小(字节)*8(转比特)*帧率
bitrate = (total_frame_size / len(frame_sizes)) * 8 * fps
print(f"视频每秒比特率(bps): {bitrate:.2f}")

说明:

  • pkt_size就是该帧在视频文件中实际占用的字节数,包含编码后的帧数据和少量容器头部信息
  • 总帧大小和文件实际大小会有小幅差异,因为文件还包含容器的元数据(比如索引、格式信息),但核心的视频数据都在帧里

方法二:手动解析视频容器格式(不推荐)

如果不想依赖FFmpeg,需要自己解析视频容器的结构(比如MP4的ISO BMFF格式、MKV的EBML格式),找到存储帧数据的区块(比如MP4的mdat盒子),再根据容器的帧索引分割每帧的大小。这种方法需要深入了解视频容器的规范,实现复杂且容易出错,仅适合有底层格式开发经验的场景。

内容的提问来源于stack exchange,提问作者tianlong yu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:27:25