使用GStreamer同步两个RTSP/RTP H264视频流捕获
我有两个轴IP摄像机,通过RTSP/RTP传输H264流。两个摄像头都设置为与同一个NTP服务器同步,因此我假设两个摄像头都具有相同的精确时钟(可能是毫秒内的微小差异) 在我的应用程序中,两个摄像头都指向同一个视图,需要同时处理两个摄像头图像。因此,我想使用GStreamer同步图像捕获 我曾尝试在不同的cmd提示下分别调用两个管道,但视频间隔为2-3秒使用GStreamer同步两个RTSP/RTP H264视频流捕获,gstreamer,h.264,rtsp,Gstreamer,H.264,Rtsp,我有两个轴IP摄像机,通过RTSP/RTP传输H264流。两个摄像头都设置为与同一个NTP服务器同步,因此我假设两个摄像头都具有相同的精确时钟(可能是毫秒内的微小差异) 在我的应用程序中,两个摄像头都指向同一个视图,需要同时处理两个摄像头图像。因此,我想使用GStreamer同步图像捕获 我曾尝试在不同的cmd提示下分别调用两个管道,但视频间隔为2-3秒 gst启动rtspsrc位置=rtsp://192.168.16.136:554/live ! rtph264depay!h264parse!
ARM同步是什么意思?如果录制到单独的视频文件,则不需要任何同步。。因为这将把他们完全分开。。每个RT(S)P流将包含不同的时间戳,如果您希望以某种方式将它们与同一时间对齐(我指的是实时..如“两者都应该从15:00开始”),那么您必须以某种方式配置它们(这只是想法) 您也没有告诉我们那些rtp/rtsp流中的内容(是MPEG ts还是纯IP..等等)。因此,我将给出mpeg ts封装rtp流的示例。 我们将逐步: 假设这是一个摄像头,只是为了演示它的外观:
gst-launch-1.0 -v videotestsrc ! videoconvert ! x264enc ! mpegtsmux ! rtpmp2tpay ! udpsink host=127.0.0.1 port=8888
然后这将是Receiver(它必须使用rtmp2tdepay。我们将元数据封装在MPEG容器中):
如果你用你的相机测试这个。。autovideosink意味着新窗口将弹出,显示您的相机
然后您可以尝试将其存储在文件中。。我们将使用mp4mux。。
因此,对于相同的摄像头输入,我们会:
gst-launch-1.0 -e udpsrc port=8888 caps=application/x-rtp\,\ media\=\(string\)video\,\ encoding-name\=\(string\)MP2T ! rtpmp2tdepay ! tsdemux ! h264parse ! mp4mux ! filesink location=test.mp4
说明:我们不解码和重新编码(浪费处理能力),因此我将只解复用MPEG ts流,然后不解码H264,而是将其解析为接受视频/x-H264的mp4mux
现在,您可以为每个摄像头使用相同的管道。。或者您可以将所有元素复制粘贴到同一管道中
现在,由于您没有提供任何(至少是部分)试图弄清楚的东西,这将是您的家庭作业:)或者让自己更清楚地了解同步,因为我不理解它
更新
在你的问题更新后,这个答案不是很有用,但我会把它保存在这里作为参考。我不知道如何同步那个
另一个建议。。尝试查看udpsrc之后的时间戳。。也许它们已经同步了。。在这种情况下,您可以使用streamsynchronizer同步两个流。。或者视频/音频混音器:
gst-launch-1.0 udpsrc -v port=8888 ! identity silent=false ! fakesink
这应打印时间戳(PTS、DTS、持续时间..):
比较每个流的PTS。。也许您可以将两个udpsrc组合在一个管道中,并在每个udpsrc之后放入标识(使用不同的name=something1
)以使它们一起开始接收
HTH我可以使用gst启动启动管道,如下所示。与使用两条管道相比,它在捕获帧同步方面有很好的改进。大多数情况下,它们相差0-500毫秒。尽管如此,我仍然希望同步精度低于150毫秒
rtspsrc location=rtsp://192.168.16.136:554/axis-media/media.amp?videocodec=h264 \
! rtph264depay ! h264parse \
! splitmuxsink max-size-time=10000000000 location=axis/video_136_%d.mp4 \
rtspsrc location=rtsp://192.168.16.186:554/axis-media/media.amp?videocodec=h264 \
! rtph264depay ! h264parse \
! splitmuxsink max-size-time=10000000000 location=axis/video_186_%d.mp4
如果有人能提出其他想法,我们将不胜感激
~Arm我所知道的是,它们都是通过RTP/RTSP传输H.264视频流的同一个AXIS摄像头。我假设RTP数据包将有一些时间戳,表示摄像机准备包含H.264编码视频帧的RTP数据包的时间。在我的应用程序中,两台摄像机指向同一场景,需要处理两台摄像机的相同ts帧。请检查此图像:![有效的XHTML]()据我所知,这些轴凸轮通过RTP/RTSP传输H.264。尝试在2个cmd提示下执行管道,录制的视频间隔2-3秒。1.gst启动rtspsrc位置=rtsp://192.168.16.136:554/live ! rtph264depay!h264parse!splitmuxsink最大大小时间=100000000位置=v0_%d.mp4 2。gst启动rtspsrc位置=rtsp://192.168.16.186:554/live ! rtph264depay!h264parse!splitmuxsink最大大小时间=100000000位置=v1_u%d。mp4@arm请将此作为更新写入您的问题中。。嗯,我不知道。。也许没有办法同步这个。。如果摄像头连接到ntp服务器,则可能会发生这种情况。。或者我不知道。。同时打开两个摄像头的电源。。如果流具有相同的时间戳,对应于相同的实时性(这很重要),那么可能有某种方式来同步这一点。。你知道一件事是相同的流时间戳,另一件事是这与“真实世界时间”有什么关系。谢谢otopolsky!我已经更新了这个问题,希望有人知道怎么做。嘿@arm,你找到解决这个问题的方法了吗?@ShivamMangla你找到解决方法了吗?:)嘿@cyberjoac,我不再处理它了,我继续进行一个解决方案,这对于我的目的来说已经足够了-我使用opencv从两个摄像头捕获最新的帧,并在处理旧帧时丢弃新帧,直到我准备好新帧集。500毫秒的错误对我的申请来说是可以接受的。
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (1328 bytes, dts: 0:00:02.707033598, pts:0:00:02.707033598, duration: none, offset: -1, offset_end: -1, flags: 00004000 tag-memory ) 0x7f57dc016400
rtspsrc location=rtsp://192.168.16.136:554/axis-media/media.amp?videocodec=h264 \
! rtph264depay ! h264parse \
! splitmuxsink max-size-time=10000000000 location=axis/video_136_%d.mp4 \
rtspsrc location=rtsp://192.168.16.186:554/axis-media/media.amp?videocodec=h264 \
! rtph264depay ! h264parse \
! splitmuxsink max-size-time=10000000000 location=axis/video_186_%d.mp4