如何使用avconv/ffmpeg获取H264文件的时长/比特率

3

执行 avprobe test.h264 命令会输出以下结果:

Input #0, h264, from 'test.h264':
  Duration: N/A, bitrate: N/A
    Stream #0.0: Video: h264 (High), yuv420p, 720x480, 25 fps, 25 tbn, 50 tbc

执行file test.h264命令将输出:
test.h264: JVT NAL sequence, H.264 video @ L 30

请注意,该文件并未损坏或损坏,在VLC上我可以毫无问题地播放它。
有办法从原始H264文件中获取持续时间和比特率吗?我在某个地方读到,如果首先解码文件,则可能是可能的,但我不确定如何做到这一点。
编辑#1
我正在使用名为picamera的Python库创建H264文件。
编辑#2
运行avconv -i test.h264 -f null -时的控制台输出。
avconv version 11.7-6:11.7-1~deb8u1+rpi1, Copyright (c) 2000-2016 the Libav developers
  built on Jun 17 2016 02:13:49 with gcc 4.9.2 (Raspbian 4.9.2-10)
[h264 @ 0x1bcc200] Estimating duration from bitrate, this may be inaccurate
Input #0, h264, from 'test.h264':
  Duration: N/A, bitrate: N/A
    Stream #0.0: Video: h264 (High), yuv420p, 720x480, 25 fps, 25 tbn
 Output #0, null, to 'pipe:':
  Metadata:
    encoder         : Lavf56.1.0
    Stream #0.0: Video: rawvideo, yuv420p, 720x480, q=2-31, 200 kb/s, 25 tbn, 25 tbc
    Metadata:
      encoder         : Lavc56.1.0 rawvideo
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press ctrl-c to stop encoding
frame=  208 fps= 68 q=0.0 Lsize=       0kB time=10000000000.00 bitrate=   0.0kbits/s
video:13kB audio:0kB other streams:0kB global headers:0kB muxing overhead: unknown
3个回答

8
你可以将其混合到一个容器中,然后进行检查。
ffmpeg -i test.h264 -c copy test.mp4

ffprobe test.mp4

您可以通过计算H264中的帧数并除以帧速率来计算帧数。
ffprobe test.h264 -count_frames -show_entries stream=nb_read_frames,avg_frame_rate,r_frame_rate

Duration = nb_read_frames / avg_frame_rate


将文件“Muxing”到容器中似乎可以工作,但在运行命令时,它会输出“输出流0:0中的非单调DTS;之前:203,当前:0;更改为204。这可能导致输出文件中的时间戳不正确。”对于它正在尝试为MP4文件编码的每个帧。此外,它可靠吗?谢谢! - Maxime Dupré
1
原始比特流中没有时间戳,因此它会将“0”赋予每个传入的帧,这当然是错误的。但这不是问题。如果您的比特流中没有像@Ronald提到的帧速率存储,则应在'-i之前添加-framerate N,其中N是fps值,否则ffmpeg将假定为25 fps。 - Gyan
avconv -framerate 30 -i test.h264 -c copy test.mp4 运行得非常完美!谢谢! - Maxime Dupré

3

持续时间为N/A的原因是annexb(原始)H.264文件通常没有存储文件中的时间戳或帧率信息。帧速率可以选择性地存储在PPS的VUI中,但是这个文件显然没有这样做,所以它只知道帧计数(通过解析整个文件),而不知道任何与时间戳相关的信息。


我目前无法获取视频文件的持续时间,但有没有办法可以获取呢? - Maxime Dupré
正如@Mulvya所建议的那样,最简单的解决方案是将视频帧混合到容器格式中,例如mp4、mkv或类似的格式。这些容器格式包含时间戳和持续时间信息。使用您已经创建的文件,您可以通过重新混合它们(使用ffmpeg)到另一个容器中并告知ffmpeg源的帧速率(我相信是ffmpeg -r 30 -i file.h264 -c:v copy file.mp4)来手动重新添加此信息。 - Ronald S. Bultje

2

一种方法是使用ffmpeg解码文件以获取持续时间:

ffmpeg -framerate 24 -i input.h264 -f null -

然后请参考控制台输出的倒数第二行中的time=,以获取持续时间。例如,输入了5秒:

frame=  125 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed= 189x

我得到了 time=10000000000.00。我的视频只有6秒钟长,所以我怀疑这个信息是没有意义的。 - Maxime Dupré
@maximedupre 对我有用。请展示你的实际命令和完整的控制台输出。你真的在使用 ffmpeg 吗? - llogan
我正在使用avconvffmpeg的分支,几乎可以完成相同的任务)。我更新了我的问题,包括完整的控制台输出。 - Maxime Dupré
@maximedupre 我的回答是针对ffmpeg的,我假设这是可以接受的,因为问题标题中有"ffmpeg",并且使用了ffmpeg标签。请尝试使用ffmpeg。你可以下载一个静态构建版本,然后直接执行它。 - llogan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接