ISP摄像头RTPS协议以太网流传输问题:VLC无法观看,求管道排查
ISP摄像头RTPS流传输GStreamer管道问题排查
我需要实现ISP摄像头通过以太网以RTPS协议进行流传输,当前使用GStreamer搭建了处理管道,但客户端VLC应用无法正常观看流。请帮忙检查管道配置是否正确,我的目标是实现低延迟的摄像头流传输。
原代码
import sys import gi gi.require_version('Gst', '1.0') from gi.repository import Gst, GLib Gst.init(None) loop = GLib.MainLoop() camera_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0 port = int(sys.argv[3]) if len(sys.argv) > 3 else 5000 source = Gst.ElementFactory.make("qtiqmmfsrc", "qmmf-source") framefilter = Gst.ElementFactory.make("capsfilter", "frame-filter") decoder = Gst.ElementFactory.make("nvv4l2decoder", "nvv4l2-decoder") converter = Gst.ElementFactory.make("nvvidconv", "video-converter") encoder = Gst.ElementFactory.make("nvv4l2h264enc", "h264-encoder") muxer = Gst.ElementFactory.make("mpegtsmux", "mpegts-muxer") parse = Gst.ElementFactory.make("h264parse", "h264-parse") queue = Gst.ElementFactory.make("queue", "queue") sink = Gst.ElementFactory.make("udpsink", "udp-sink") # set properties to the elements source.set_property("camera", camera_id) if camera_id == 0: framefilter.set_property("caps", Gst.Caps.from_string( "video/x-h264,format=NV12 framerate=30/1,width=1920, height=1080")) else: framefilter.set_property("caps", Gst.Caps.from_string( "video/x-h264, framerate=30/1,width=1280, height=720")) sink.set_property("host", sys.argv[2]) sink.set_property("port", port) rtppay = Gst.ElementFactory.make("rtph264pay", "rtppay") # Build the pipeline pipeline = Gst.Pipeline.new("stream-pipeline") pipeline.add(source) pipeline.add(parse) pipeline.add(framefilter) pipeline.add(muxer) pipeline.add(queue) pipeline.add(sink) if not Gst.Element.link(source, parse): print("ERROR: Could not link source to h264parser") sys.exit(1) if not Gst.Element.link(parse, framefilter): print("ERROR: Could not link h264parser to decoder") sys.exit(1) if not Gst.Element.link(framefilter, muxer): print("ERROR: Could not link capsfilter to converter") sys.exit(1) if not Gst.Element.link(muxer, queue): print("ERROR: Could not link muxer to queue") sys.exit(1) if not Gst.Element.link(queue, sink): print("ERROR: Could not link queue to sink") sys.exit(1) try: print("Streaming started...") pipeline.set_state(Gst.State.PLAYING) print("vlc at ip:%s:%d" % (sys.argv[2], port)) print('Press Ctrl+C to stop') loop.run() except KeyboardInterrupt: print("Streaming stopped due to keyboard Interrupt") pipeline.set_state(Gst.State.NULL) sys.exit(0)
问题分析与修正
- 冗余元素无效:代码中创建了
decoder、converter、encoder但未添加到管道或链接,属于无效代码,直接删除即可。 - RTPS协议未正确实现:
- 原代码用
mpegtsmux封装成TS流通过UDP发送,这不是RTPS流。RTPS需要用rtph264pay将H264包封装为RTP包,因此要移除mpegtsmux,把rtppay加入管道并正确链接。
- 原代码用
- Caps配置错误:
video/x-h264是编码后的视频流,不存在format=NV12(NV12是原始视频格式),必须删除该参数。 - 低延迟配置缺失:需给相关元素添加低延迟参数,减少传输和处理延迟。
修正后的代码
import sys import gi gi.require_version('Gst', '1.0') from gi.repository import Gst, GLib Gst.init(None) loop = GLib.MainLoop() camera_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0 port = int(sys.argv[3]) if len(sys.argv) > 3 else 5000 # 仅保留必要元素 source = Gst.ElementFactory.make("qtiqmmfsrc", "qmmf-source") parse = Gst.ElementFactory.make("h264parse", "h264-parse") framefilter = Gst.ElementFactory.make("capsfilter", "frame-filter") rtppay = Gst.ElementFactory.make("rtph264pay", "rtppay") queue = Gst.ElementFactory.make("queue", "queue") sink = Gst.ElementFactory.make("udpsink", "udp-sink") # 配置摄像头源 source.set_property("camera", camera_id) # 修正Caps配置:移除H264流中错误的format参数 if camera_id == 0: framefilter.set_property("caps", Gst.Caps.from_string( "video/x-h264, framerate=30/1, width=1920, height=1080, stream-format=byte-stream")) else: framefilter.set_property("caps", Gst.Caps.from_string( "video/x-h264, framerate=30/1, width=1280, height=720, stream-format=byte-stream")) # 配置RTPS参数 rtppay.set_property("pt", 96) # 标准H264 RTP负载类型 rtppay.set_property("config-interval", 1) # 每秒发送一次SPS/PPS,确保客户端初始化 # 配置UDP低延迟 sink.set_property("host", sys.argv[2]) sink.set_property("port", port) sink.set_property("sync", False) # 关闭同步减少延迟 sink.set_property("async", False) sink.set_property("buffer-size", 0) # 禁用缓冲区降低延迟 # 构建管道并链接元素 pipeline = Gst.Pipeline.new("rtp-stream-pipeline") pipeline.add(source) pipeline.add(parse) pipeline.add(framefilter) pipeline.add(rtppay) pipeline.add(queue) pipeline.add(sink) # 按正确顺序链接 if not Gst.Element.link_many(source, parse, framefilter, rtppay, queue, sink): print("ERROR: Failed to link elements") sys.exit(1) try: print("Streaming started...") pipeline.set_state(Gst.State.PLAYING) print(f"VLC播放地址: rtp://{sys.argv[2]}:{port}") print('Press Ctrl+C to stop') loop.run() except KeyboardInterrupt: print("Streaming stopped due to keyboard Interrupt") pipeline.set_state(Gst.State.NULL) sys.exit(0)
VLC播放说明
客户端打开VLC后,通过「媒体→打开网络串流」,输入地址:rtp://<目标IP>:<端口>(例如rtp://192.168.1.100:5000),即可观看RTPS流。
内容的提问来源于stack exchange,提问作者user2046361
相关产品推荐
相关产品推荐

