4

我有一个文件,其中只有 h264 帧以 NAL 单元的形式存在。那么现在有什么方法可以计算该文件的持续时间吗?

我不知道文件中有多少帧。我只有文件大小。

PS:我想做的只是在C语言和Linux平台上。

4

3 回答 3

7

你的问题毫无意义,这就是为什么有人反对你。

容器文件

首先,不存在H264 file. 可以有一个包含 H264 编码视频的容器文件(MP4、AVI、MKV)。该容器格式通常还包含数据,告诉您包含的视频持续时间。因此,您必须解析该文件,检查格式文档以查看持续时间的保存位置,然后将其提取。

最简单的方法是像 Augusto 建议的那样使用 FFMPEG。

NAL 字节流

如果您的文件只是一个接一个地保存的 NAL 单元,例如在 NAL 字节流中,则无法获得视频时长!由于 H264 编码的图片不包含时序信息。

如果是这种情况,如果您知道视频 FPS,您仍然可以进行近似计算...您需要计算文件中的所有帧,不包括:

  • 序列参数集
  • 图片参数集
  • 流结束
  • 序列结束
  • 过滤数据
  • 访问单元分隔符

然后做数学:NUMBER_OF_FRAMES / FPS = DURATION_IN_SECONDS

RTP 流

如果您错了,并且每个 NAL 单元顶部都有 RTP 标头,您可以通过检查每个 RTP 标头的 RTP 时间轻松获得视频时长。RTP Header 中的字节是什么意思,您可以在这里找到:http: //www.networksorcery.com/enp/protocol/rtp.htm。您想TIMESTAMP从每个中获取部分(4 字节整数)。代码应该这样做:

int last_timestamp = GetNextTimestamp();
double duration_in_ms = 0;

while(true)
{
    int next = GetNextTimestamp();
    duration_in_ms += (next - last_timestamp)/90000.0;
    last_timestamp = next;
}
于 2011-09-26T10:02:06.633 回答
3

h.264 确实包含时序信息。

某种形式(内存或文件)的原始附件 b h.264 数据将包含一些“序列参数集”或 SPS 帧。这些通常包含时间信息,特别是“time_scale”和“num_units_in_tick”。在大多数情况下,帧速率是固定的,由 SPS 中的“fixed_frame_rate_flag”指定。每帧的持续时间为 2 * num_units_in_tick / time_scale (2 == 1 + nuit_field_based_flag)。帧通常由“访问单元分隔符”分隔。

帧数乘以帧持续时间将为您提供总持续时间。

于 2017-07-12T15:02:36.927 回答
2

许多开发人员使用的获取持续时间的肮脏方法是运行 ffmpeg 以从文件中获取信息,并解析 ffmpeg 在 stdout 上打印的内容。我知道这并不理想,但它确实有效。

如果你运行(你可以从这里ffmpeg -i Sintel.2010.1080p.mkv下载 Sintel ),输出行之一是. 您可以解析行并提取持续时间。Duration: 00:14:48.03, start: 0.000000, bitrate: 640 kb/s

您可以通过直接从 ffmpeg 调用一些 C 函数来获得相同的信息,但这超出了我的知识范围。

于 2011-09-15T10:38:11.717 回答