如何让 RTSP 流显示在多个设备上?

问题描述 投票:0回答:1

我有一个使用 gstreamer RTSP 服务器的代码,我正在尝试从图像/帧创建一些 rtsp 流。该实现工作正常并将图像转换为 RTSP 流。

过程是我运行脚本并且服务器现在处于活动状态,然后我可以在另一台具有我当前计算机 IP 的计算机上使用 RTSP 流。

问题:

  1. 我想知道如何更改 rtsp 端口并从 config.json 文件中获取它。由于某种原因,即使我没有明确声明使用该端口,使用的默认端口是 8554。
  2. 我可以在不同端口的帮助下通过一台 RTSP 服务器使用多个 rtsp 流吗?例如,如果我通过 VLC 流式传输相同的 RTSP URL,则当前的实现无法在多台计算机上运行。

这是我到目前为止的代码:

class TestRtspMediaFactory(GstRtspServer.RTSPMediaFactory):
    def __init__(self, source):
        GstRtspServer.RTSPMediaFactory.__init__(self)
        self.source = source

    def do_create_element(self, url):
        image_folder = self.source.get("image_folder", None)

        if image_folder:
            # print('Image folder paths:', image_folder)
            pipeline = f"multifilesrc location={image_folder}/%d.jpg index=1 caps=\"image/jpeg,framerate=30/1\" ! jpegdec ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay name=pay0 config-interval=1 pt=96"
        else:
            print("Invalid source. Specify 'image_folder' in the configuration.")
            return None
    
        print("Element created:", pipeline)
        return Gst.parse_launch(pipeline)

class GstreamerRtspServer():
    def __init__(self, sources):
        self.rtspServer = GstRtspServer.RTSPServer()
        self.mountPoints = self.rtspServer.get_mount_points()
        self.create_rtsp_streams(sources)

    def create_rtsp_streams(self, sources):
        for source in sources:
            rtsp_port = source["rtsp_port"]
            rtsp_mount_point = source["rtsp_mount_point"]
            print(rtsp_mount_point)
            print(rtsp_port)

            factory = TestRtspMediaFactory(source)
            factory.set_shared(True)
            self.mountPoints.add_factory(rtsp_mount_point, factory)

        self.rtspServer.attach(None)

def main(config_file):
    with open(config_file, 'r') as f:
        config = json.load(f)

    sources = config.get("sources", [])
    
    s = GstreamerRtspServer(sources)
    loop = GLib.MainLoop()
    loop.run()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Run RTSP server for multiple video sources.")
    parser.add_argument("--config", required=True, help="Path to the JSON configuration file.")
    args = parser.parse_args()
    
    main(args.config)

这是我的 config.json 文件:

{
    "sources": [
        {
            "image_folder": "/home/neville/Documents/convert_rtsp_video/frames",
            "rtsp_port": 4000,
            "rtsp_mount_point": "/stream1"
        },
        {
            "image_folder": "/path/to/another/image/folder",
            "rtsp_port": 8555,
            "rtsp_mount_point": "/stream2"
        }
    ]
}
gstreamer rtsp rtsp-server
1个回答
0
投票
  1. 要设置服务器使用的端口,您可以使用RtspServer的方法

    set_service

  2. 您不需要为不同的客户端指定不同的端口,RTSP 服务器将与客户端协商并管理实际的端口和传输协议。客户端可以仅通过 URI 使用stream1、stream2来选择流。

所以修改你的 json 配置文件后:

{
    "server": {
            "port": "68554"
    },
        
    "sources": [
        {
            "image_folder": "/home/neville/Documents/convert_rtsp_video/frames",
            "rtsp_mount_point": "/stream1"
        },
        {
            "image_folder": "/path/to/another/image/folder",
            "rtsp_mount_point": "/stream2"
        }
    ]
}

并将您的代码修改为:

#!/usr/bin/env python3

import argparse
import json
import gi
gi.require_version('Gst','1.0')
gi.require_version('GstVideo','1.0')
gi.require_version('GstRtspServer','1.0')
from gi.repository import GObject, GLib, Gst, GstVideo, GstRtspServer


class TestRtspMediaFactory(GstRtspServer.RTSPMediaFactory):
    def __init__(self, source):
        GstRtspServer.RTSPMediaFactory.__init__(self)
        self.source = source

    def do_create_element(self, url):
        image_folder = self.source.get("image_folder", None)

        if image_folder:
            # print('Image folder paths:', image_folder)
            pipeline = f"multifilesrc location={image_folder}/%d.jpg index=1 loop=1 caps=\"image/jpeg,framerate=30/1\" ! jpegdec ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast key-int-max=30 ! rtph264pay name=pay0 config-interval=1 pt=96"

        else:
            print("Invalid source. Specify 'image_folder' in the configuration.")
            return None
    
        print("Element created:", pipeline)
        return Gst.parse_launch(pipeline)
        

class GstreamerRtspServer():
    def __init__(self, server, sources):
        self.rtspServer = GstRtspServer.RTSPServer()
        self.rtspServer.set_service(server["port"])
        print("RTSP Server on port", server["port"]) 
        self.mountPoints = self.rtspServer.get_mount_points()
        self.create_rtsp_streams(sources)

    def create_rtsp_streams(self, sources):
        for source in sources:
            rtsp_mount_point = source["rtsp_mount_point"]
            print(rtsp_mount_point)

            factory = TestRtspMediaFactory(source)
            factory.set_shared(True)
            self.mountPoints.add_factory(rtsp_mount_point, factory)

        self.rtspServer.attach(None)

def main(config_file):
    with open(config_file, 'r') as f:
        config = json.load(f)

    server = config.get("server", [])
    sources = config.get("sources", [])
    
    s = GstreamerRtspServer(server,sources)
    loop = GLib.MainLoop()
    loop.run()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Run RTSP server for multiple video sources.")
    parser.add_argument("--config", required=True, help="Path to the JSON configuration file.")
    args = parser.parse_args()
    Gst.init(None)
    main(args.config)

它可以与本地主机上的 2 个客户端(每个流一个)和来自远程主机的其他 2 个客户端一起正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.