来自RTSP视频流的发送方报告(SR)的绝对时间戳



我在python中使用rtsp从ip摄像机获取视频流,并希望在发送方报告中获得每个帧的绝对时间戳。如果我读一个流,camtime显然从零开始:ret,image_np=cap.read((camtime=cap.get(cv2.cap_PROP_POS_MSEC(/1000。我需要知道帧是什么时候录制的,因为相机位于不同的时区,并且帧是以不同的延迟接收的。有人能建议使用什么库以及python代码应该是什么样子吗?谢谢附言:我可以从SDP中的ffmpeg获得相机流开始时间(选项"o"(。

经过三周的实验,我终于用GStreamer做到了这一点。

GStreamer应用程序由元素管道组成,其中每个元素都有不同的用途,并以不同的方式处理数据流。阅读文档以了解正在发生的事情和本教程。简而言之,数据在缓冲区内从一个元素传递到另一个元素,并在传递到下一个元素之前进行相应的处理。

当你了解了GStreamer的工作原理后,设置一个类似这样的管道:

rtspsrc -> rtph264depay -> h264parse -> avdec_h264 -> videoconvert -> capsfilter -> videoconvert -> fakesink

正确设置管道需要学习每个元素的属性,但这里最重要的是正确设置rtspsrc

rtsp_source = Gst.ElementFactory.make("rtsprc", "rtsp_source")
rtsp_source.set_property("location", RTSP_URL)

然后获取具有RTP数据的rtph264depaysink焊盘,并为其设置一个探针:

pad = element.get_static_pad("sink")
pad.add_probe(Gst.PadProbeType.BUFFER, callback_func, None)

这意味着,每当数据通过该焊盘时,都会调用一个回调函数,该函数接收buffer中的数据。访问缓冲区:

r, map_info = buffer.map(Gst.MapFlags.READ)
raw_data = map_info.data
buffer.unmap(map_info)

现在您有了RTP数据包,它的头和有效载荷在raw_data中。从中,您现在可以提取回调中的RTP时间戳。你可以自己做,或者更好,我更喜欢用这个神奇的图书馆来做。

然后,如果您还需要框架,请在fakesinksink焊盘中设置另一个探针。同样,您的缓冲区map_info现在有帧数据,您可以使用numpy将其转换为帧,例如:

rgb_frame = np.ndarray(
shape=(height, width, 3),
dtype=np.uint8,
buffer=map_info.data,
)

对帧和时间戳做你想做的事。祝你好运

最新更新