Files
mediamtx/docs/3-publish/20-python-opencv.md
T
Alessandro RosandGitHub b5b63d02fc support reading and publishing with Media-over-QUIC (#5815)
Media-over-QUIC is a streaming protocol built upon cutting edge
protocols (QUIC, HTTP3) and browser APIs (WebTransport, WebCodecs).
It's slightly faster than WebRTC, has an advanced data recovery
mechanism (placed at the frame level and not at the packet level), it
supports additional codecs (FLAC) and is less complicated to route.
2026-06-02 23:04:24 +02:00

2.0 KiB

Python and OpenCV

Python-based software can publish streams to the server with the OpenCV library and its GStreamer plugin, acting as a RTSP client. OpenCV must be compiled with support for GStreamer, by following this procedure:

sudo apt install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-ugly gstreamer1.0-rtsp python3-dev python3-numpy
git clone --depth=1 -b 4.5.4 https://github.com/opencv/opencv
cd opencv
mkdir build && cd build
cmake -D CMAKE_INSTALL_PREFIX=/usr -D WITH_GSTREAMER=ON ..
make -j$(nproc)
sudo make install

You can check that OpenCV has been installed correctly by running:

python3 -c 'import cv2; print(cv2.getBuildInformation())'

Check that the output contains GStreamer: YES.

Videos can then be published with cv2.VideoWriter:

from datetime import datetime
from time import sleep, time

import cv2
import numpy as np

fps = 15
width = 800
height = 600
colors = [
    (0, 0, 255),
    (255, 0, 0),
    (0, 255, 0),
]

out = cv2.VideoWriter('appsrc ! videoconvert' + \
    ' ! video/x-raw,format=I420' + \
    ' ! x264enc speed-preset=ultrafast bitrate=600 key-int-max=' + str(fps * 2) + \
    ' ! video/x-h264,profile=baseline' + \
    ' ! rtspclientsink location=rtsp://localhost:8554/mystream',
    cv2.CAP_GSTREAMER, 0, fps, (width, height), True)
if not out.isOpened():
    raise Exception("can't open video writer")

curcolor = 0
start = time()

while True:
    frame = np.zeros((height, width, 3), np.uint8)

    # create a rectangle
    color = colors[curcolor]
    curcolor += 1
    curcolor %= len(colors)
    for y in range(0, int(frame.shape[0] / 2)):
        for x in range(0, int(frame.shape[1] / 2)):
            frame[y][x] = color

    out.write(frame)
    print("%s frame written to the server" % datetime.now())

    now = time()
    diff = (1 / fps) - now - start
    if diff > 0:
        sleep(diff)
    start = now

The resulting stream will be available on path /mystream.