我在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数据的rtph264depay
的sink
焊盘,并为其设置一个探针:
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时间戳。你可以自己做,或者更好,我更喜欢用这个神奇的图书馆来做。
然后,如果您还需要框架,请在fakesink
的sink
焊盘中设置另一个探针。同样,您的缓冲区map_info
现在有帧数据,您可以使用numpy
将其转换为帧,例如:
rgb_frame = np.ndarray(
shape=(height, width, 3),
dtype=np.uint8,
buffer=map_info.data,
)
对帧和时间戳做你想做的事。祝你好运