如何将 cv2.VideoWriter 帧流式传输到 RTSP 服务器

cha*_*z0r 7 opencv ffmpeg rtsp video-streaming

环境:Docker、Ubuntu 20.04、OpenCV 3.5.4、FFmpeg 4.2.4

\n

我目前cv2.VideoCapture使用CV_FFMPEG后端读取会话的输出,并使用cv2.VideoWriter. 我这样做的原因是在输入上绘制边界框并将其保存到新的输出中。

\n

问题是我是在无头环境(Docker 容器)中执行此操作。cv2.VideoWriter我\xe2\x80\x99d 喜欢实时查看正在写入的内容。

\n

我知道有一些方法可以通过使用 XQuartz 来传递我的显示,这样我就可以使用cv2.imshow. 但我真正想做的是将这些帧写入 RTSP 服务器。因此,不仅我的主持人可以“观看”,其他主持人也可以观看。

\n

视频发布后,我可以使用此命令轻松地将视频流式传输到我的 RTSP 服务器。

\n

ffmpeg -re -stream_loop -1 -i output.mp4 -c copy -f rtsp rtsp://rtsp_server_host:8554/stream

\n

当帧进入上述命令时,是否有办法通过管道传输帧?本身可以cv2.VideoWriter将帧写入 RTSP 服务器吗?

\n

任何想法将不胜感激!谢谢。

\n

cha*_*z0r 9

经过大量搜索,我终于弄清楚如何在子进程中使用 FFmpeg 来做到这一点。希望这对其他人有帮助!

def open_ffmpeg_stream_process(self):
    args = (
        "ffmpeg -re -stream_loop -1 -f rawvideo -pix_fmt "
        "rgb24 -s 1920x1080 -i pipe:0 -pix_fmt yuv420p "
        "-f rtsp rtsp://rtsp_server:8554/stream"
    ).split()
    return subprocess.Popen(args, stdin=subprocess.PIPE)


def capture_loop():
    ffmpeg_process = open_ffmpeg_stream_process()
    capture = cv2.VideoCapture(<video/stream>)    
    while True:
        grabbed, frame = capture.read()
        if not grabbed:
            break
        ffmpeg_process.stdin.write(frame.astype(np.uint8).tobytes())
    capture.release()
    ffmpeg_process.stdin.close()
    ffmpeg_process.wait()
Run Code Online (Sandbox Code Playgroud)