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

如何用GStreamer读取Socket传来的H264帧并发布RTSP流?

解决方案:将Socket接收的H264帧发布到RTSP服务器

GStreamer 优化方案(优先推荐)

1. 命令行版本(简化高效)

当前命令的核心问题是做了不必要的解码-重编码流程,直接复用原始H264流推送到RTSP服务器即可,大幅降低CPU开销:

gst-launch-1.0 -e fdsrc fd=0 ! h264parse ! rtph264pay config-interval=1 pt=96 ! rtspclientsink location=rtsp://你的RTSP服务器地址:端口/流名称
  • 关键优化点:
    • 移除avdec_h264、videoconvert等解码/转换步骤,直接处理原始H264流
    • 使用rtph264pay将H264帧打包为RTP格式(RTSP标准传输格式)
    • 通过rtspclientsink直接推流到自有RTSP服务器

2. C#进程内嵌入方案(最佳实践)

如果需要在C#进程内处理(避免外部进程开销),推荐使用GStreamer Sharp绑定,通过appsrc元素直接将Socket接收的帧数据注入GStreamer管道,无需标准输入通信:

步骤:

  1. 通过NuGet安装GStreamerSharp包
  2. 编写核心代码示例:
using Gst;
using Gst.App;

// 初始化GStreamer
Application.Init();

// 创建管道
var pipeline = new Pipeline("h264-rtsp-pipeline");

// 创建元素
var appsrc = ElementFactory.Make("appsrc", "frame-source");
var h264parse = ElementFactory.Make("h264parse", "h264-parser");
var rtph264pay = ElementFactory.Make("rtph264pay", "rtp-payloader");
var rtspSink = ElementFactory.Make("rtspclientsink", "rtsp-sink");

// 配置RTSP服务器地址
rtspSink.SetProperty("location", "rtsp://你的RTSP服务器地址:554/stream-path");

// 配置appsrc的格式(根据实际H264流参数调整,比如分辨率、帧率)
var caps = Caps.FromString("video/x-h264, stream-format=byte-stream, width=1920, height=1080, framerate=25/1");
appsrc.SetProperty("caps", caps);
appsrc.SetProperty("format", Format.Time);

// 链接所有元素
pipeline.AddMany(appsrc, h264parse, rtph264pay, rtspSink);
Element.LinkMany(appsrc, h264parse, rtph264pay, rtspSink);

// 启动管道
pipeline.SetState(State.Playing);

// 模拟Socket接收帧并推送(替换为实际Socket读取逻辑)
long frameCount = 0;
var frameRate = 25;
while (true)
{
    byte[] h264Frame = ReceiveFrameFromSocket(); // 自定义Socket读取方法
    if (h264Frame == null || h264Frame.Length == 0) break;

    // 创建GStreamer缓冲区并写入帧数据
    using var buffer = new Buffer(h264Frame.Length);
    using var map = buffer.Map(MapFlags.Write);
    System.Buffer.BlockCopy(h264Frame, 0, map.Data, 0, h264Frame.Length);

    // 设置时间戳(保证RTSP流的时序正确)
    buffer.Pts = Clock.TimeFromFrames(frameCount, frameRate);
    buffer.Dts = buffer.Pts;
    buffer.Duration = Clock.TimeFromFrames(1, frameRate);

    // 推送缓冲区到appsrc
    var src = (AppSrc)appsrc;
    src.PushBuffer(buffer);

    frameCount++;
}

// 停止并清理管道
pipeline.SetState(State.Null);
Application.Deinit();
  • 优势:完全进程内处理,无跨进程通信开销,便于集成到C#项目中,可控性更强。

FFmpeg 备选方案

如果需要用FFmpeg命令行实现,同样可以直接复用原始H264流推流:

ffmpeg -f h264 -i pipe:0 -c:v copy -f rtsp rtsp://你的RTSP服务器地址:端口/流名称
  • -f h264:指定输入为H264原始流
  • -c:v copy:直接复制视频流,不重新编码
  • -f rtsp:输出RTSP流到目标服务器

内容的提问来源于stack exchange,提问作者Alvan Rahimli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 13:43:13