PyAV:重串流时强制使用新的帧率吗?

时间:2019-06-07 00:01:33

标签: python ffmpeg pyav

我有一个Python程序,该程序通过网络接收一系列H264视频帧,我想显示这些视频帧,也可以选择进行记录。摄像机以30FPS的速度记录并尽可能快地发送帧,由于网络条件的变化,它并不能始终保持30FPS的速度。有时它会掉下来然后追上,而很少完全掉落帧。

“显示”部分很简单;我不需要担心时间安排或流元数据,只需要在帧到达时尽快显示它们即可:

input = av.open(get_video_stream())
for packet in input.demux(video=0):
  for frame in packet.decode():
    # A bunch of numpy and pygame code here to convert the frame to RGB
    # row-major and blit it to the screen

“记录”部分看起来像,这应该很容易:

input = av.open(get_video_stream())
output = av.open(filename, 'w')
output.add_stream(template=input.streams[0])
for packet in input.demux(video=0):
  for frame in packet.decode():
    # ...display code...
  packet.stream = output.streams[0]
  output.mux_one(packet)
output.close()

确实,这会产生一个包含所有帧的有效MP4文件,如果我用mplayer -fps 30播放它,则可以正常工作。但是,-fps 30是绝对必需的:

$ ffprobe output.mp4
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 960x720,
                  1277664 kb/s, 12800 fps, 12800 tbr, 12800 tbn, 25600 tbc (default)

请注意,每秒12,800帧。 应该看起来像这样(通过调用mencoder -fps 30并将框架插入其中来产生):

$ ffprobe mencoder_test.mp4
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 960x720,
                  2998 kb/s, 30 fps, 30 tbr, 90k tbn, 180k tbc (default)

检查从输入流中获得的数据包和帧,我看到:

stream: time_base=1/1200000
codec: framerate=25 time_base=1/50
packet: dts=None pts=None duration=48000 time_base=1/1200000
frame: dst=None pts=None time=None time_base=1/1200000

因此,数据包和帧根本没有时间戳;它们的time_base与最终文件中的时基或摄像机的实际帧频都不匹配;编解码器的帧率和时基与最终文件,摄像机帧率或其他视频流元数据不匹配!

关于时间和帧率问题,几乎完全没有PyAV文档,但是我尝试手动设置流,包和帧time_basedts和{ {1}}没有成功。我总是可以再次重新录制录像的视频 以获得正确的帧率,但是我宁愿首先写入正确的视频文件。

那么,如何让pyAV重新混合视频,使其产生正确标记为30fps的输出?

0 个答案:

没有答案