如何用Python实现同一端口下多视频RTSP流发布?
同一端口下创建多个RTSP流的解决方案
首先明确:完全可以在同一个端口下运行多个RTSP流,每个流通过不同的挂载路径区分(比如你提到的rtsp://12.0.0.1:8554/test和rtsp://12.0.0.1:8554/test2)。你的代码问题出在创建了两个独立的RTSP服务器实例,它们都试图绑定同一个端口,导致端口冲突,第二个服务器根本启动不起来,所以只有第一个流能工作。
问题分析
你的代码里,每个线程都实例化了一个GstServer(继承自RTSPServer),并且都设置了同一个端口8012。当第一个服务器绑定端口后,第二个服务器尝试绑定同一个端口时会失败(系统会返回"地址已在使用"的错误,只是你的代码没做错误处理所以没看到)。这就是第二个流无法生成的核心原因。
正确的做法是:只创建一个RTSP服务器实例,然后给它添加多个不同挂载路径的媒体工厂(MediaFactory),每个工厂对应一个视频流。
修复后的代码
import cv2 import gi gi.require_version('Gst', '1.0') gi.require_version('GstRtspServer', '1.0') from gi.repository import Gst, GstRtspServer, GObject class SensorFactory(GstRtspServer.RTSPMediaFactory): def __init__(self, video, **properties): super(SensorFactory, self).__init__(**properties) self.cap = cv2.VideoCapture(video) self.number_frames = 0 self.fps = 30 self.duration = 1 / self.fps * Gst.SECOND # 帧的持续时间(纳秒) self.launch_string = 'appsrc name=source block=true format=GST_FORMAT_TIME ' \ 'caps=video/x-raw,format=BGR,width=600,height=600,framerate={}/1 ' \ '! videoconvert ! video/x-raw,format=I420 ' \ '! x264enc speed-preset=ultrafast tune=zerolatency ' \ '! rtph264pay config-interval=1 name=pay0 pt=96'.format(self.fps) def on_need_data(self, src, length): if self.cap.isOpened(): ret, frame = self.cap.read() if not ret: # 视频读取完毕后重置到开头循环播放(可选逻辑,可根据需求删除) self.cap.set(cv2.CAP_PROP_POS_FRAMES, 0) return frame = cv2.resize(frame, (600, 600)) data = frame.tobytes() # 替换tostring(),符合Python3规范 buf = Gst.Buffer.new_allocate(None, len(data), None) buf.fill(0, data) buf.duration = self.duration timestamp = self.number_frames * self.duration buf.pts = buf.dts = int(timestamp) buf.offset = timestamp self.number_frames += 1 retval = src.emit('push-buffer', buf) if retval != Gst.FlowReturn.OK: print(f"推送帧失败: {retval}") def do_create_element(self, url): return Gst.parse_launch(self.launch_string) def do_configure(self, rtsp_media): self.number_frames = 0 appsrc = rtsp_media.get_element().get_child_by_name('source') appsrc.connect('need-data', self.on_need_data) class GstServer(GstRtspServer.RTSPServer): def __init__(self, port="8012", **properties): super(GstServer, self).__init__(**properties) self.set_service(port) self.mount_points = self.get_mount_points() def add_stream(self, video_path, stream_name): # 为每个流创建独立的工厂实例 factory = SensorFactory(video_path) factory.set_shared(True) # 允许多个客户端同时连接同一个流 self.mount_points.add_factory(f"/{stream_name}", factory) if __name__ == "__main__": video_path = '/home/root1/Documents/test_videos/videoplayback.mp4' stream1_name = 'test' stream2_name = 'test1' GObject.threads_init() Gst.init(None) # 只创建一个服务器实例,避免端口冲突 server = GstServer(port="8012") # 向服务器添加两个不同的流 server.add_stream(video_path, stream1_name) server.add_stream(video_path, stream2_name) # 启动服务器 server.attach(None) print(f"RTSP服务器启动,端口8012,可用流地址:") print(f"rtsp://12.0.0.1:8012/{stream1_name}") print(f"rtsp://12.0.0.1:8012/{stream2_name}") # 启动主循环处理事件 loop = GObject.MainLoop() loop.run()
关键修改说明
- 单服务器实例:只初始化一个
GstServer绑定目标端口,彻底避免端口冲突问题。 - 多流挂载机制:通过
add_stream方法为服务器添加多个独立的SensorFactory,每个工厂对应一个唯一的流路径。 - 优化细节:添加视频循环播放逻辑、替换Python3过时API、增加错误提示,提升代码健壮性。
现在你可以通过rtsp://12.0.0.1:8012/test和rtsp://12.0.0.1:8012/test1访问两个独立的RTSP流,它们共用同一个端口正常工作。
内容的提问来源于stack exchange,提问作者belgin vinoj
相关产品推荐
相关产品推荐

