如何获得h264比特率

时间:2014-10-06 16:24:15

标签: video ffmpeg h.264 decoding x264

尝试了MediaInfo,尝试了ffprobe -show_streams -i "file.mkv"(或原始文件h264),它给了我bit_rate=N/A。 MediaInfo什么都没有。

我发现的唯一方法是创建.dga文件,方法是通过MegUI索引它并使用其比特率计算器工具并设置与源相同的确切大小,然后显示平均比特率,但这种方式很荒谬谁知道准确度如何。

3 个答案:

答案 0 :(得分:1)

嗯,H.264原始数据不包含任何时序信息。但是,您可以提取帧大小,并通过提供每秒帧数参数来计算比特率。 我为此编写了一个简单的bash脚本,它使用了awk和ffmpeg(ffprobe)。

#!/bin/bash

# Mimic the output of
# mplayer -lavdopts vstats FILE -fps 30 -vo null
# Example usage:
# ./vstats.sh file.hevc 30

FFPROBE=$HOME/src/ffmpeg/ffprobe

fps=$2
# default 30 fps
: ${fps:=30}

frames=$3
# Numper of frames to process
: ${frames:=65536}

awk -v FPS="${fps}" -v FRAMES="${frames}" '
BEGIN{
    FS="="
}
/pkt_size/ {
  br=$2/1000.0*8*FPS
  if (br > max_br)
      max_br=br
  acc_br+=br
  acc_bytes+=br
  i+=1
  printf("frame= %6d, f_size= %7d, s_size= %8dkB, br= %8.1fkbits/s, avg_br= %8.1fkbits/s\n",
      i, $2, int(acc_bytes/1024+0.5), br, acc_br/i)

  if (i >= FRAMES)
      exit 
}
END {
    print "----"
    printf("Peak BR: %.1fkbits/s", max_br)
}
' <(${FFPROBE} -show_frames $1 2>/dev/null)

示例输出:

frame=      1, f_size=   50805, s_size=       12kB, br=  12193.2kbits/s, avg_br=  12193.2kbits/s
frame=      2, f_size=    4749, s_size=       13kB, br=   1139.8kbits/s, avg_br=   6666.5kbits/s
frame=      3, f_size=    5781, s_size=       14kB, br=   1387.4kbits/s, avg_br=   4906.8kbits/s
frame=      4, f_size=    6135, s_size=       16kB, br=   1472.4kbits/s, avg_br=   4048.2kbits/s
frame=      5, f_size=    6239, s_size=       17kB, br=   1497.4kbits/s, avg_br=   3538.0kbits/s
frame=      6, f_size=    6487, s_size=       19kB, br=   1556.9kbits/s, avg_br=   3207.8kbits/s
frame=      7, f_size=    6550, s_size=       20kB, br=   1572.0kbits/s, avg_br=   2974.1kbits/s
frame=      8, f_size=    6567, s_size=       22kB, br=   1576.1kbits/s, avg_br=   2799.4kbits/s
frame=      9, f_size=    6390, s_size=       23kB, br=   1533.6kbits/s, avg_br=   2658.7kbits/s
frame=     10, f_size=    6540, s_size=       25kB, br=   1569.6kbits/s, avg_br=   2549.8kbits/s
frame=     11, f_size=    6929, s_size=       27kB, br=   1663.0kbits/s, avg_br=   2469.2kbits/s
frame=     12, f_size=    8037, s_size=       28kB, br=   1928.9kbits/s, avg_br=   2424.2kbits/s
frame=     13, f_size=    7965, s_size=       30kB, br=   1911.6kbits/s, avg_br=   2384.8kbits/s
frame=     14, f_size=    7833, s_size=       32kB, br=   1879.9kbits/s, avg_br=   2348.7kbits/s
frame=     15, f_size=    8281, s_size=       34kB, br=   1987.4kbits/s, avg_br=   2324.6kbits/s
frame=     16, f_size=    8235, s_size=       36kB, br=   1976.4kbits/s, avg_br=   2302.8kbits/s
frame=     17, f_size=    7969, s_size=       38kB, br=   1912.6kbits/s, avg_br=   2279.9kbits/s
frame=     18, f_size=    7953, s_size=       40kB, br=   1908.7kbits/s, avg_br=   2259.3kbits/s
frame=     19, f_size=    8867, s_size=       42kB, br=   2128.1kbits/s, avg_br=   2252.4kbits/s
frame=     20, f_size=    9686, s_size=       44kB, br=   2324.6kbits/s, avg_br=   2256.0kbits/s
----
Peak BR: 12193.2kbits/s

答案 1 :(得分:1)

不幸的是,Mpeg System和AVC / HEVC都没有指定如何计算瞬时比特率。例如,根据Mpeg System规范。 maximum_bitrate描述符包含最大峰值比特率,“表示比特率的上限,包括将在此程序元素或程序中遇到的传输开销。” 但是,如何计算这个比特率?什么窗口(例如1s)?是这个窗口滑动(重叠),如果是这样,什么是跳距离?

DVB进行了一些标准化比特率计算的工作。在文件“DVB系统的测量指南”(旧版本:ETSI TR 101 290 V1.2.1(2001-05),最新版本:ETSI TR 101 290 V1.3.1(2014-07))几种测量比特率的方法传输流已指定。值得一提的只有两个--MGB1和MGB2:

* MGB1 窗口(或门)大小为1秒 滑动:不重叠,窗口“每秒跳”

MGB2 窗口(或门)大小为1秒 滑动:重叠,窗口“跳”每100ms *

在我自己的网站http://ramugedia.com/hls--how-determine-peak-bitrate中,我提供了一些如何衡量比特率的解释

答案 2 :(得分:1)

我通过Google发现了这个老问题,并通过增加一些速度,可用性和正确性来建立在@Fredrik的有用回复上。

基于弗雷德里克·皮尔(Fredrik Pihl)的答案

#!/bin/bash

# Determine the peak bitrate and average bit rate for a video file.
#
# Counts video stream packets directly so can be used when
# video bitrate metadata is incorrect or missing. Very fast.
#
# Usage:
# ./vbit.sh <file> <optional: frames to count> <optional: fps (detected automatically if excluded)> 
#
# Examples:
# ./vbit.sh input.mkv 
# ./vbit.sh input.mkv  10000



frames=$2
# Numper of frames to process
: ${frames:=65536}

fps=$3
# defaults to detecting tbr with ffmpeg
: ${fps:=$(ffmpeg -i $1 2>&1 | sed -n "s/.*, \(.*\) tbr.*/\1/p")}

echo "FPS=$fps"

awk -v FPS="${fps}" -v FRAMES="${frames}" '
BEGIN{
    FS="="
}
/size/ {
  br=$2/1000.0*8*FPS
  if (br > max_br)
      max_br=br
  acc_br+=br
  acc_bytes+=br
  i+=1

  if (i % 2000 == 0)
    printf("frame= %6d, f_size= %7d, s_size= %8dkB, br= %8.1fkbits/s, avg_br= %8.1fkbits/s\n",
        i, $2, int(acc_bytes/1024+0.5), br, acc_br/i)

  if (i >= FRAMES)
      exit 
}
END {
    print "----"
    printf("Average BR: %.1fkbits/s\n", acc_br/i)
    printf("Peak BR: %.1fkbits/s\n", max_br)
}
' <(ffprobe -select_streams v -show_entries packet=size $1 2>/dev/null)


主要改进

    通过按顺序读取数据包并输出除大小以外的任何内容,可将
  • 速度提高约100倍。 (密钥更改:ffprobe -select_streams v -show_entries packet=size
  • 这使我能够在2秒内对60分钟的视频中的每一帧进行计数。
  • 如果音频/字幕流存在,则不进行计数(否则将其包括在内,从而使avg_br错误)
  • 自动检测帧频