You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

问题分析与修正

  1. 冗余元素无效:代码中创建了decoder、converter、encoder但未添加到管道或链接,属于无效代码,直接删除即可。
  2. RTPS协议未正确实现:
    • 原代码用mpegtsmux封装成TS流通过UDP发送,这不是RTPS流。RTPS需要用rtph264pay将H264包封装为RTP包,因此要移除mpegtsmux,把rtppay加入管道并正确链接。
  3. Caps配置错误:video/x-h264是编码后的视频流,不存在format=NV12(NV12是原始视频格式),必须删除该参数。
  4. 低延迟配置缺失:需给相关元素添加低延迟参数,减少传输和处理延迟。

修正后的代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:30:24