我如何知道任何 h264 文件的持续时间?

发布于 2024-12-04 14:18:48 字数 127 浏览 1 评论 0原文

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

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

PS:我想做的就是用C语言和Linux平台。

I have one file in which only h264 frames are there in form of NAL unit.
So now is there any method so i can count the duration of that file?

I dont know how many frames are there in file.
I have only file size.

PS: All i want to do is in C language and on Linux platform.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟雨凡馨 2024-12-11 14:18:48

容器文件

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

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

NAL 字节流

如果您的文件只是一个接一个保存的 NAL 单元,就像在 NAL 字节流中一样,那么您不可能获得视频时长!由于 H264 编码的图片不保存时序信息。

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

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

和然后进行数学计算: NUMBER_OF_FRAMES / FPS = DURATION_IN_SECONDS

RTP 流

如果你错了并且顶部有 RTP 标头每个NAL单元,您可以通过检查每个RTP标头的RTP时间轻松获得视频持续时间。 RTP 标头中的字节含义,您可以在这里找到: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;
}

Container file

First, there is no such a thing as H264 file. There can be a container file (MP4, AVI, MKV) that holds the H264 encoded video. That container format usually also holds the data telling you the contained video duration. So you have to parse that file, check the format documentation to see where the duration is saved, and then extract it.

Easiest way is to use FFMPEG like Augusto suggested.

NAL Byte Stream

If your file is only NAL units saved one after another, like in a NAL byte stream, there IS NO WAY that you can get the video duration! Since H264 encoded picture doesn't hold timing information.

If that is the case, you still can make an approximation if you know the video FPS... You need to count all frames in the file excluding:

  • Sequence Parameter Sets
  • Picture Parameter Sets
  • End Of Stream
  • End Of Sequence
  • Filter Data
  • Access Unit Delimiter

And then do the math: NUMBER_OF_FRAMES / FPS = DURATION_IN_SECONDS

RTP stream

If you are wrong and there is RTP header on top of each NAL unit, you can easily get the video duration by checking the RTP time of each RTP header. What the bytes in RTP Header mean, you can find out here: http://www.networksorcery.com/enp/protocol/rtp.htm. You want to get the TIMESTAMP part (4 bytes integer) from each one. The code should do this:

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;
}
雾里花 2024-12-11 14:18:48

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)。帧通常由“访问单元定界符”分隔。

帧数乘以帧持续时间即可得出总持续时间。

h.264 does contain timing information.

Raw annexb h.264 data in some form (memory or file) will contain some "Sequence Parameter Sets" or SPS frames. These will typically contain timing information, specifically "time_scale" and "num_units_in_tick". In most scenarios the frame rate is fixed which is specified by "fixed_frame_rate_flag" in the SPS. Duration for each frame will be 2 * num_units_in_tick / time_scale (2 == 1 + nuit_field_based_flag). Frames are typically separated by a "Access unit delimiter".

Number of frames times the frame duration will give you the total duration.

云柯 2024-12-11 14:18:48

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

如果您运行 ffmpeg -i Sintel.2010.1080p.mkv(您可以从 此处下载 Sintel ),输出行之一是Duration:00:14:48.03,start:0.000000,bitrate:640千字节/秒。您可以解析该行并提取持续时间。

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

The dirty way of getting the duration, which many, many devs use, is to run ffmpeg to get the information from the file, and parse what ffmpeg prints on stdout. I know it's not ideal, but it works.

If you run ffmpeg -i Sintel.2010.1080p.mkv (you can download Sintel from here), one of the output lines is Duration: 00:14:48.03, start: 0.000000, bitrate: 640 kb/s. You can parse the line and extract the duration.

You might be able to get the same information by calling some C function from ffmpeg directly, but that's outside of my knowledge.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文