go2rtc
go2rtc copied to clipboard
Question how to use API
Greetings!
I want to read mp4 video frame by frame using opencv, and frame by frame push it to go2rtc service. I expect that this framed sequence become a video inside go2rtc, thich I can open in browser.
response = requests.put("http://localhost:1984/api/streams?src=no&name=mystream")
cap = cv2.VideoCapture(video_path)
def send_frame(frame):
_, img_encoded = cv2.imencode(".jpeg", frame)
response = requests.post(go2rtc_url, data=img_encoded.tobytes())
if response.status_code == 200:
print(f"OK. {response.content.strip()}")
else:
print(f"ERROR: {response.status_code} - {response.content.strip()}")
try:
while True:
ret, frame = cap.read()
if not ret:
break
send_frame(frame)
time.sleep(0.1)
this is my script. It does not work and I don't know why. The error log inside the docker container is:
2024-11-18 15:14:10 17:14:10.866 WRN github.com/AlexxIT/go2rtc/internal/mjpeg/init.go:142 > error="mjpeg: no receivers"
- You need to create empty stream in go2rtc config. And use it name in your API.
- You need to open a connection to the API and keep it open. Now you create a new connection every frame.
- You need to use
POST /api/stream?dst={stream_name} - I don't know what inside your
frame, but it should be JPEG. Don't send raw pixels to API.
Thank you for the response! --> You need to use POST /api/stream?dst={stream_name}
Why not /api/stream.mjpeg ?
so now it gives Error 500 - magic: unsupported header: 2f396a2f
import cv2
import requests
import time
import base64
go2rtc_url = "http://localhost:1984/api/stream?dst=mystream"
video_path = "videos/example.mp4"
cap = cv2.VideoCapture(video_path)
session = requests.Session()
def send_frame(frame):
_, img_encoded = cv2.imencode(".JPEG", frame)
img_encoded = img_encoded.tobytes()
img_encoded = base64.b64encode(img_encoded)
response = session.post(go2rtc_url, data=img_encoded)
if response.status_code == 200:
print(f"Ok {response.content.decode()}")
else:
print(f"Error {response.status_code} - {response.content.decode()}")
while True:
ret, frame = cap.read()
if not ret:
break
send_frame(frame)
time.sleep(0.1)
@AlexxIT probably, any additional headers should be provided in post request?
в целом, можно на русском
A lot of problems:
- you can't use
/api/stream.mjpeg, because it's for classic web multipart mjpeg, and you sending frames without delimiter - you still not using one connection, one connection is about stream mode for requests library
- headers are not needed, jpeg will be detected by the first bytes
- it's better not to write in Russian, because this communication could be useful to someone else
- you still not using one connection, one connection is about stream mode for requests library
I wish that is the main problem. Will try to find the solution tomorrow.
By the way, one more thing that bothers me - should I use b64encode when sending frames or not (with it - Error500 - magic: unsupported header: 2f396a2f; without it - Error500 - EOF now)
and I my docker
go2rtc:
image: alexxit/go2rtc
container_name: go2rtc
ports:
- 1984:1984
- 8554:8554
privileged: true
restart: unless-stopped
environment:
- TZ=Asia/Yekaterinburg # timezone in logs
volumes:
- ./config:/config # folder for go2rtc.yaml file (edit from WebUI)
I can't use host and prefered to open only 2 ports: 8554, 1984. I wish it's enough
config now is:
streams:
mystream:
b64encode is completely unnecessary here
you can check here for a working example: https://github.com/fuatakgun/eufy_security/blob/master/custom_components/eufy_security/eufy_security_api/p2p_streamer.py#L37