You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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配置步骤:

  1. 添加「VLC Video Source」
  2. 在URL输入框填写 rtsp://localhost:8554/stream
  3. 点击确定即可加载流

注意:若代码无法直接启动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配置步骤:

  1. 添加「Video Capture Device」
  2. 设备选择列表中找到pyvirtualcam对应的虚拟摄像头
  3. 点击确定即可显示处理后的帧

方法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配置步骤:

  1. 添加「Media Source」
  2. 取消勾选「本地文件」,在输入框填写 udp://localhost:5000
  3. 点击确定即可接收流

内容的提问来源于stack exchange,提问作者bozolino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:02:55