如何将Python中OpenCV处理后的帧直接推流到OBS Studio?
将OpenCV处理后的帧推流到OBS Studio的解决方案
问题描述
之前尝试用Flask生成网页作为OBS的「Browser」源,来显示Python脚本中OpenCV处理后的帧,但存在卡顿、不稳定的问题。希望找到直接将OpenCV帧推流至OBS的方法,比如生成RTSP流后通过OBS的「VLC Video Source」读取。现有代码骨架如下:
import cv2 output_to_obs = True output_to_cv2 = True camera = cv2.VideoCapture(0) def frame_to_obs(frame): # ========================== # don't know what to do here # ========================== pass def process_frame(frame): # just an example frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) return frame_gray while (camera.isOpened()): ret, frame = camera.read() if ret == True: frame = process_frame(frame) if output_to_obs: frame_to_obs(frame) if output_to_cv2: cv2.imshow('frame',frame) if cv2.waitKey(1) == 27: # escape was pressed break else: break
可行解决方案
方法1:OpenCV+FFmpeg生成RTSP流
依赖FFmpeg(需确保OpenCV编译时包含FFmpeg支持),直接用VideoWriter生成RTSP流,OBS通过VLC源读取。
修改后的完整代码:
import cv2 output_to_obs = True output_to_cv2 = True camera = cv2.VideoCapture(0) # 获取摄像头基础参数 frame_width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = int(camera.get(cv2.CAP_PROP_FPS)) rtsp_url = "rtsp://localhost:8554/stream" fourcc = cv2.VideoWriter_fourcc(*'MJPG') rtsp_writer = None def frame_to_obs(frame): global rtsp_writer # 首次调用时初始化RTSP写入器 if rtsp_writer is None: # 判断帧是否为彩色(灰度图通道数为1) is_color = len(frame.shape) == 3 and frame.shape[2] == 3 rtsp_writer = cv2.VideoWriter(rtsp_url, fourcc, fps, (frame_width, frame_height), isColor=is_color) rtsp_writer.write(frame) def process_frame(frame): frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) return frame_gray try: while camera.isOpened(): ret, frame = camera.read() if ret: frame = process_frame(frame) if output_to_obs: frame_to_obs(frame) if output_to_cv2: cv2.imshow('frame', frame) if cv2.waitKey(1) == 27: break else: break finally: camera.release() if rtsp_writer: rtsp_writer.release() cv2.destroyAllWindows()
OBS配置步骤:
- 添加「VLC Video Source」
- 在URL输入框填写
rtsp://localhost:8554/stream - 点击确定即可加载流
注意:若代码无法直接启动RTSP服务,可先在终端启动FFmpeg内置RTSP服务器:
ffmpeg -listen 1 -i rtsp://localhost:8554/stream -c copy -f rtsp rtsp://localhost:8554/stream
方法2:虚拟摄像头输出(低延迟最稳定)
将处理后的帧输出到虚拟摄像头,OBS直接选择虚拟摄像头作为视频源,延迟极低且稳定性高。
步骤1:安装依赖库
pip install pyvirtualcam opencv-python
步骤2:修改代码
import cv2 import pyvirtualcam output_to_obs = True output_to_cv2 = True camera = cv2.VideoCapture(0) frame_width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = int(camera.get(cv2.CAP_PROP_FPS)) # 初始化虚拟摄像头 with pyvirtualcam.Camera(width=frame_width, height=frame_height, fps=fps) as cam: def frame_to_obs(frame): # 灰度图转RGB(虚拟摄像头要求RGB格式) if len(frame.shape) == 2: frame_rgb = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB) else: frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) cam.send(frame_rgb) cam.sleep_until_next_frame() def process_frame(frame): frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) return frame_gray while camera.isOpened(): ret, frame = camera.read() if ret: frame = process_frame(frame) if output_to_obs: frame_to_obs(frame) if output_to_cv2: cv2.imshow('frame', frame) if cv2.waitKey(1) == 27: break else: break camera.release() cv2.destroyAllWindows()
OBS配置步骤:
- 添加「Video Capture Device」
- 设备选择列表中找到
pyvirtualcam对应的虚拟摄像头 - 点击确定即可显示处理后的帧
方法3:UDP推流到OBS
用FFmpeg将帧通过UDP协议推流,OBS直接读取UDP流,适合低延迟场景。
步骤1:安装依赖库
pip install ffmpeg-python opencv-python
步骤2:修改代码
import cv2 import ffmpeg output_to_obs = True output_to_cv2 = True camera = cv2.VideoCapture(0) frame_width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = int(camera.get(cv2.CAP_PROP_FPS)) # UDP推流地址 udp_url = "udp://localhost:5000" # 初始化FFmpeg推流进程 process = ( ffmpeg .input('pipe:', format='rawvideo', pix_fmt='gray', s=f'{frame_width}x{frame_height}', r=fps) .output(udp_url, pix_fmt='yuv420p', vcodec='libx264', preset='ultrafast', r=fps) .overwrite_output() .run_async(pipe_stdin=True) ) def frame_to_obs(frame): # 将帧转为字节流写入FFmpeg标准输入 process.stdin.write(frame.tobytes()) def process_frame(frame): frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) return frame_gray try: while camera.isOpened(): ret, frame = camera.read() if ret: frame = process_frame(frame) if output_to_obs: frame_to_obs(frame) if output_to_cv2: cv2.imshow('frame', frame) if cv2.waitKey(1) == 27: break else: break finally: camera.release() process.stdin.close() process.wait() cv2.destroyAllWindows()
OBS配置步骤:
- 添加「Media Source」
- 取消勾选「本地文件」,在输入框填写
udp://localhost:5000 - 点击确定即可接收流
内容的提问来源于stack exchange,提问作者bozolino
相关产品推荐
相关产品推荐

