如何用单RTSP服务器处理多路摄像头流并转成HLS(m3u8)?
单服务器处理多路RTSP流转HLS方案
先修正你之前的错误
你用udpsrc是完全错的——你推送的是RTSP封装的流,不是裸UDP数据包,所以不能直接抓UDP端口。而且不需要给每个流单独搭服务器,单服务器通过不同的路径(比如/cam1、/cam2)就能区分多路流,下面给你两种可行方案:
方案1:用FFmpeg直接拉流转码(简单易上手)
这是最直接的方式,在云端服务器上对每一路RTSP流单独启动FFmpeg进程,转成HLS后用HTTP服务器对外提供访问。
步骤1:准备HTTP服务
先装个nginx(或其他HTTP服务器),创建HLS存储目录:
sudo apt install nginx -y sudo mkdir -p /var/www/html/hls sudo chmod 755 /var/www/html/hls
修改nginx配置(比如/etc/nginx/sites-available/default),把根目录指向/var/www/html,确保HLS的.m3u8和.ts文件能被访问。
步骤2:启动转码进程
对每一路摄像头流,运行以下FFmpeg命令(后台运行,避免断开终端后进程终止):
# 处理cam1 nohup ffmpeg -i rtsp://localhost:10000/cam1 -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k -f hls -hls_time 2 -hls_list_size 3 -hls_segment_filename "/var/www/html/hls/cam1_%05d.ts" "/var/www/html/hls/cam1.m3u8" > /dev/null 2>&1 & # 处理cam2 nohup ffmpeg -i rtsp://localhost:10000/cam2 -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k -f hls -hls_time 2 -hls_list_size 3 -hls_segment_filename "/var/www/html/hls/cam2_%05d.ts" "/var/www/html/hls/cam2.m3u8" > /dev/null 2>&1 & # 以此类推到cam5
参数说明:
-hls_time 2:每个TS切片2秒-hls_list_size 3:只保留最新3个切片- 编码参数可以根据服务器性能调整,
preset fast平衡速度和质量
步骤3:网页访问
在HTML播放器里直接用地址:http://你的云端服务器IP/hls/cam1.m3u8,就能播放对应摄像头的流。
方案2:用GStreamer RTSP服务器统一管理(适合复杂场景)
如果你想用GStreamer搭建统一的RTSP接收+转码服务,需要用gst-rtsp-server框架(不是简单的gst-launch),以下是一个Python脚本实现:
步骤1:安装依赖
sudo apt install python3-gi gstreamer1.0-rtsp-server gstreamer1.0-plugins-good gstreamer1.0-plugins-bad -y
步骤2:编写RTSP+HLS转换脚本
创建rtsp_hls_server.py:
import gi import os gi.require_version('Gst', '1.0') gi.require_version('GstRtspServer', '1.0') from gi.repository import Gst, GstRtspServer, GLib Gst.init(None) class HLSStreamFactory(GstRtspServer.RTSPMediaFactory): def __init__(self, output_dir, cam_name): super().__init__() self.output_dir = output_dir self.cam_name = cam_name self.set_shared(True) # 允许多客户端拉流 def do_create_element(self, url): # 构建转码流水线:拉RTSP流 -> 解封装 -> 转码 -> 生成HLS pipeline_str = f""" rtspsrc location={url.get_request_uri()} ! rtph264depay ! h264parse ! video/x-h264,stream-format=avc ! mpegtsmux ! hlssink target-duration=2 location="{self.output_dir}/%05d.ts" playlist-root="http://你的云端服务器IP/hls/" playlists-max=3 playlist-location="{self.output_dir}/{self.cam_name}.m3u8" """ return Gst.parse_launch(pipeline_str.replace('\n', '')) class RTSPHLSBridge(GstRtspServer.RTSPServer): def __init__(self): super().__init__() self.set_service("10000") # 监听RTSP的10000端口 mount_points = self.get_mount_points() # 为5个摄像头创建流处理实例 for cam_idx in range(1, 6): cam_name = f"cam{cam_idx}" output_dir = f"/var/www/html/hls/{cam_name}" os.makedirs(output_dir, exist_ok=True) factory = HLSStreamFactory(output_dir, cam_name) mount_points.add_factory(f"/{cam_name}", factory) self.attach(None) if __name__ == "__main__": server = RTSPHLSBridge() loop = GLib.MainLoop() print("RTSP-HLS服务器启动,监听端口10000...") loop.run()
步骤3:启动服务器
nohup python3 rtsp_hls_server.py > /dev/null 2>&1 &
同样用nginx提供HTTP访问,每个摄像头的HLS地址是http://你的云端服务器IP/hls/cam1/cam1.m3u8。
关键注意事项
- 端口开放:云端服务器需要开放10000(RTSP)和80/8080(HTTP)端口,确保设备能推流到AWS服务器。
- 资源占用:5路640x480的转码流,单核CPU足够应付;如果是更高分辨率,建议用多核服务器。
- 进程管理:可以用
systemd把FFmpeg或Python脚本做成服务,确保服务器重启后自动启动。
内容的提问来源于stack exchange,提问作者ooo
相关产品推荐
相关产品推荐

