不止OBS:用Python+OpenCV把摄像头或RTSP流转成直播流(SRS服务器推流实战) 用PythonOpenCV构建轻量级直播推流系统从摄像头到SRS服务器的全代码实战直播技术早已不再是专业团队的专利。作为一名长期从事多媒体开发的工程师我发现很多场景下我们需要的只是一个简单可靠的推流方案——不需要OBS复杂的界面不需要手动操作只需几行代码就能把摄像头画面或网络视频流稳定地推送到直播服务器。本文将分享如何用PythonOpenCV打造这样一个轻量级推流系统特别适合需要自动化处理的监控、远程教学等场景。1. 环境搭建与SRS服务器部署1.1 SRS流媒体服务器快速部署SRS(Simple RTMP Server)是一款国人开发的高性能流媒体服务器支持RTMP、HLS、HTTP-FLV等多种协议。相比Nginx-RTMP它的配置更简单资源占用更低。以下是两种最常用的部署方式Docker一键部署方案推荐开发测试使用docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:4 \ ./objs/srs -c conf/srs.conf源码编译安装方案适合生产环境git clone https://github.com/ossrs/srs.git cd srs/trunk ./configure make提示如果需要在CentOS上设置为开机自启可以创建systemd服务单元文件具体参考SRS官方文档。1.2 Python环境准备我们需要以下Python包来实现视频采集和推流功能pip install opencv-python numpy subprocess.run关键组件作用说明OpenCV视频帧捕获和处理subprocess调用FFmpeg进行编码和推流numpy图像数据格式转换2. 核心推流代码实现2.1 摄像头推流基础实现以下代码实现了从本地摄像头采集视频并推流到SRS服务器的完整流程import cv2 import subprocess import numpy as np def camera_to_rtmp(rtmp_url, camera_index0, fps25): # 初始化视频捕获 cap cv2.VideoCapture(camera_index) if not cap.isOpened(): raise RuntimeError(无法打开摄像头) # 获取视频属性 width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # FFmpeg命令构建 command [ ffmpeg, -y, -an, -f, rawvideo, -vcodec, rawvideo, -pix_fmt, bgr24, -s, f{width}x{height}, -r, str(fps), -i, -, -c:v, libx264, -pix_fmt, yuv420p, -preset, ultrafast, -f, flv, rtmp_url ] # 启动FFmpeg进程 process subprocess.Popen(command, stdinsubprocess.PIPE) try: while True: ret, frame cap.read() if not ret: break # 写入帧数据到FFmpeg process.stdin.write(frame.tobytes()) # 按q键退出 if cv2.waitKey(1) 0xFF ord(q): break finally: cap.release() process.stdin.close() process.terminate() if __name__ __main__: camera_to_rtmp(rtmp://localhost/live/mystream)2.2 支持RTSP源的增强版本只需稍作修改我们就能支持网络摄像头的RTSP流作为输入源def rtsp_to_rtmp(rtsp_url, rtmp_url, fps25): cap cv2.VideoCapture(rtsp_url) # 其余代码与camera_to_rtmp相同典型RTSP URL格式示例rtsp://admin:password192.168.1.64:554/Streaming/Channels/1013. 高级功能实现3.1 多流管理与负载均衡在实际应用中我们经常需要同时处理多个视频源。以下是管理多个推流进程的示例from concurrent.futures import ThreadPoolExecutor def multi_stream_manager(stream_configs): with ThreadPoolExecutor(max_workers4) as executor: futures [] for config in stream_configs: if config[type] camera: future executor.submit(camera_to_rtmp, config[rtmp_url], config[camera_index]) elif config[type] rtsp: future executor.submit(rtsp_to_rtmp, config[rtsp_url], config[rtmp_url]) futures.append(future) # 等待所有任务完成 for future in futures: future.result()3.2 视频处理中间件在推流前对视频帧进行处理是常见需求比如添加水印、人脸识别等def processing_pipeline(frame): # 示例添加时间戳水印 timestamp datetime.now().strftime(%Y-%m-%d %H:%M:%S) cv2.putText(frame, timestamp, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2) return frame # 在推流循环中加入处理逻辑 ret, frame cap.read() frame processing_pipeline(frame) process.stdin.write(frame.tobytes())4. 性能优化与异常处理4.1 关键参数调优FFmpeg编码参数对推流性能影响巨大以下是几个关键参数的建议值参数推荐值说明-presetultrafast/superfast编码速度与质量的权衡-tunezerolatency降低编码延迟-gfps*2GOP大小影响seek和容错-b:v1500k视频比特率根据分辨率调整-threads2编码线程数优化后的FFmpeg命令示例command [ ffmpeg, -y, -an, -f, rawvideo, -vcodec, rawvideo, -pix_fmt, bgr24, -s, f{width}x{height}, -r, str(fps), -i, -, -c:v, libx264, -pix_fmt, yuv420p, -preset, superfast, -tune, zerolatency, -g, str(fps*2), -b:v, 1500k, -threads, 2, -f, flv, rtmp_url ]4.2 健壮性增强实际运行中可能遇到各种异常情况我们需要增强代码的容错能力import time def robust_streaming(rtmp_url, camera_index0, max_retries3): retry_count 0 while retry_count max_retries: try: camera_to_rtmp(rtmp_url, camera_index) except Exception as e: print(f推流中断: {str(e)}) retry_count 1 time.sleep(5) # 等待5秒后重试 continue break5. 应用场景与扩展5.1 典型应用案例无人值守监控系统7×24小时运行异常事件自动报警远程教学直播多摄像头切换实时白板标注工业质检生产线视频实时分析并推流到质检平台智能家居家庭安防摄像头集成到统一平台5.2 与OBS方案的对比特性PythonOpenCV方案OBS方案自动化程度高可编程控制低需人工操作资源占用低中等功能扩展性强可深度定制有限依赖插件上手难度需要编程基础图形界面友好多路推流易于代码实现需要复杂配置在实际项目中使用这套方案后我发现它特别适合需要长时间稳定运行的场景。曾经有一个监控项目需要连续工作30天不中断基于Python的方案通过简单的守护进程和自动恢复机制完美满足了需求而传统OBS方案则经常因为界面卡死需要人工干预。