go2rtc icon indicating copy to clipboard operation
go2rtc copied to clipboard

Question how to use API

Open ankhafizov opened this issue 1 year ago • 9 comments

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"

ankhafizov avatar Nov 18 '24 12:11 ankhafizov

  1. You need to create empty stream in go2rtc config. And use it name in your API.
  2. You need to open a connection to the API and keep it open. Now you create a new connection every frame.
  3. You need to use POST /api/stream?dst={stream_name}
  4. I don't know what inside your frame, but it should be JPEG. Don't send raw pixels to API.

AlexxIT avatar Nov 18 '24 12:11 AlexxIT

Thank you for the response! --> You need to use POST /api/stream?dst={stream_name}

Why not /api/stream.mjpeg ?

ankhafizov avatar Nov 18 '24 12:11 ankhafizov

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)

ankhafizov avatar Nov 18 '24 14:11 ankhafizov

@AlexxIT probably, any additional headers should be provided in post request?

ankhafizov avatar Nov 18 '24 14:11 ankhafizov

в целом, можно на русском

ankhafizov avatar Nov 18 '24 14:11 ankhafizov

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

AlexxIT avatar Nov 18 '24 17:11 AlexxIT

  • 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:

ankhafizov avatar Nov 18 '24 22:11 ankhafizov

b64encode is completely unnecessary here

AlexxIT avatar Nov 19 '24 04:11 AlexxIT

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

fuatakgun avatar Nov 24 '24 19:11 fuatakgun