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.
75 lines
2.0 KiB
Markdown
75 lines
2.0 KiB
Markdown
# 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](07-rtsp-clients.md). OpenCV must be compiled with support for GStreamer, by following this procedure:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
python3 -c 'import cv2; print(cv2.getBuildInformation())'
|
|
```
|
|
|
|
Check that the output contains `GStreamer: YES`.
|
|
|
|
Videos can then be published with `cv2.VideoWriter`:
|
|
|
|
```python
|
|
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`.
|