GStreamer 完全可以在 单容器内实现多路(并发)推流
无论是多个输入视频源同时推送到不同 RTSP/RTMP/UDP 地址,还是同一输入多路输出,都是可行的。

但要注意:

  • 每一路推流必须使用独立的 pipeline(管线)实例

  • 要正确管理 线程端口同步

  • 某些插件(例如 rtspsrcrtspsink)在同进程多实例时需要小心配置。

🧱 一、典型应用场景

场景描述
多路本地文件转推一个容器读取多个本地视频文件并同时推送到多个 RTSP 地址
多摄像头采集容器中有多个 USB/IP 摄像头,分别推流
单视频多协议输出同一输入视频同时推到 RTSP + RTMP + HLS
云推流节点一个容器服务多个客户端推流请求(每个请求动态创建管线)

⚙️ 二、实现方式(核心思路)

GStreamer 本身是 线程安全、可并行运行多管线 的框架。
只要每个推流任务使用独立的 GstPipeline 对象,就能并发运行。

你可以用以下 3 种方式实现:


✅ 方式 1:使用命令行(多个进程并发)

这是最简单也最稳定的方案:

# 推流 A
gst-launch-1.0 filesrc location=a.mp4 ! decodebin ! x264enc ! rtspclientsink location=rtsp://server/a &

# 推流 B
gst-launch-1.0 filesrc location=b.mp4 ! decodebin ! x264enc ! rtspclientsink location=rtsp://server/b &

每条管线在独立的 shell 子进程中运行;互不干扰。
缺点是管理复杂(不易动态扩缩)。


✅ 方式 2:在同一进程中创建多个 GstPipeline 对象(C/C++ 或 Python)

这是容器内部服务化最常见的方式。

Python 示例(简化示意):
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib
import threading

Gst.init(None)

def start_stream(video_path, rtsp_url):
    pipeline_str = f"filesrc location={video_path} ! decodebin ! x264enc ! rtspclientsink location={rtsp_url}"
    pipeline = Gst.parse_launch(pipeline_str)
    pipeline.set_state(Gst.State.PLAYING)
    print(f"Started streaming {video_path} -> {rtsp_url}")

# 启动多路推流
threads = []
streams = [
    ("video1.mp4", "rtsp://server/stream1"),
    ("video2.mp4", "rtsp://server/stream2"),
]

for v, u in streams:
    t = threading.Thread(target=start_stream, args=(v, u))
    t.start()
    threads.append(t)

# 主循环
loop = GLib.MainLoop()
loop.run()

✅ 每个推流任务是独立的 pipeline。
✅ GLib 主循环可以调度所有 GStreamer 事件。
✅ 适合在单容器内运行一个“推流服务”。


✅ 方式 3:在服务端动态创建/销毁管线(例如 RTSP Server)

如果你使用 GStreamer 的 RTSP 服务器功能(gst-rtsp-server),
它本身可以在一个进程中动态创建多路流。

C 代码或 Python gi.repository.GstRtspServer 都支持这样:

server = GstRtspServer.RTSPServer()
factory1 = GstRtspServer.RTSPMediaFactory()
factory1.set_launch('( filesrc location=video1.mp4 ! decodebin ! x264enc ! rtph264pay name=pay0 pt=96 )')
server.get_mount_points().add_factory("/stream1", factory1)

factory2 = GstRtspServer.RTSPMediaFactory()
factory2.set_launch('( filesrc location=video2.mp4 ! decodebin ! x264enc ! rtph264pay name=pay0 pt=96 )')
server.get_mount_points().add_factory("/stream2", factory2)

server.attach(None)
loop = GLib.MainLoop()
loop.run()

✅ 单进程、单容器;
✅ 每一路 /streamX 独立推流;
✅ RTSP Server 自动管理线程。


⚠️ 三、注意事项

问题说明
🔹 线程每条管线内部是异步的,但不要复用同一个 GstPipeline 对象。
🔹 同步如果需要同帧同步推多路(例如多摄像头合并),应使用 input-selector / tee 元件。
🔹 资源占用每一路推流消耗独立的解码、编码线程。GPU 编码时尤其要留意。
🔹 端口冲突多个推流目标(RTSP、RTMP)时需保证端口不同。
🔹 生命周期管理可通过信号(Bus message)监听 EOSERROR 事件自动回收。
🔹 容器限制建议配置 --shm-size 足够大(GStreamer 常用共享内存)。

💡 四、最佳实践建议

场景推荐方式
每路视频固定、数量少(如2~5路)多线程 + 多 GstPipeline
动态创建销毁推流RTSP Server + 动态 factory
高并发(>50路)多容器 + 分布式调度(如每容器管理 5~10 路)
云原生部署通过 k8s sidecar 或 job 动态创建推流容器

✅ 结论总结

结论说明
✔️ GStreamer 支持单容器并发推流没有技术限制
✔️ 每一路推流需独立 pipeline不可共享管线对象
✔️ 推荐用 Python/C 多线程或 RTSP Server 实现更易维护与扩展
⚠️ 注意线程同步、资源占用特别是 GPU 编码和多核 CPU 环境

更多推荐