Unterschiede zwischen den Revisionen 3 und 4
Revision 3 vom 2021-06-13 18:56:46
Größe: 9954
Autor: lars
Kommentar:
Revision 4 vom 2021-06-13 18:57:09
Größe: 9859
Autor: lars
Kommentar: remove "rename" comments
Gelöschter Text ist auf diese Art markiert. Hinzugefügter Text ist auf diese Art markiert.
Zeile 1: Zeile 1:
## page was renamed from GoPro_Hero_Streaming
## page was renamed from GoPro_Hero7_Streaming

Overview

The GoPro cameras are small, robust, shake-compensating and offer a wide field of view. Thus they are fine devices for recording or sharing your physical adventures.

Sadly the cameras are rather hard to integrate into a streaming environment.

The following description should help fellow users along that path. It is tested with the GoPro Hero7 Silver, but should work for many other models, too.

Camera interfaces

Wireless network

The device can create a wireless network:

  • the connection details can be found in the device's preference menu (via the touchscreen)
  • SSID and password can be changed via the API (see goprocom)

  • only "ap" (accesspoint) mode is supported (not "sta" (station))
    • thus it is not possible to simply join an existing local network
  • clients are isolated (i.e. you cannot reach your router, if these two devices are connected to the camera network)
  • 2,4 and 5 GHz are supported
  • the camera enters sleep mode after a period of inactivity, but it keeps its wireless network open, as long as there is another client connected to it
    • this allows a "wakeup" packet to be received (based on the MAC address of the camera)
    • thus clients should be disconnected after usage
  • the camera always uses the IP 10.5.5.9

HTTP API

The camera supports an HTTP interface for reading and modifying the device's properties:

  • inspect the meaning of the device's control registers: curl -sS http://10.5.5.9/gp/gpControl

    • sadly many control registers are not really writable (or some values are not accepted)
  • settings can be written with an HTTP GET request, e.g. curl -sS http://10.5.5.9/gp/gpControl/setting/2/9 (change the resolution to 1080p)

    • sometimes changes are outright rejected (with a malformed JSON response containing unescaped special characters; no reason is given)
    • sometimes changes are accepted, but not applied (the previous value stays unchanged)
  • the current state of all settings can be inspected:

    curl -sS http://10.5.5.9/gp/gpControl/status

Streaming format

A video stream can be started by sending a packet to the camera:

echo '_GPHD_:0:0:2:0.000000'; done | nc -u -q 0 10.5.5.9 8554

(other cameras may need a different packet, e.g. _GPHD_:1:0:2:0.000000 for Hero8/9 Black)

The UDP stream points is sent towards port 8554 of the sender (of the above packet).

The stream must be kept awake by sending the above packet repeatedly. A period of 2.5 seconds seems to be a good choice.

The stream is probably only meant to be used for a preview within the mobile app. But it can also be used for other purposes, of course.

At least for the Hero7 Silver the stream was not easy to access properly (e.g. VLC, mplayer of ffplay produced only partial and distorted frames). See below for details.

Technically (according to ffprobe), the stream seems to contain the following channels:

Stream #0:0[0x1011]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuvj420p(pc, smpte170m, progressive), 640x480 [SAR 1:1 DAR 4:3], 30 fps, 30 tbr, 90k tbn, 60 tbc
Stream #0:1[0x1100]: Audio: aac ([15][0][0][0] / 0x000F), 0 channels, fltp
Stream #0:2[0x200]: Unknown: none ([128][0][0][0] / 0x0080)
Stream #0:3[0x201]: Audio: ac3 ([129][0][0][0] / 0x0081), 0 channels, fltp

Remote Streaming

Please note, that you need to start the stream (and keep it awake) by sending the following packet periodically to the camera:

while sleep 2.5; do echo '_GPHD_:0:0:2:0.000000'; done | nc -u -q 0 10.5.5.9 8554

You can easily watch the amount of bandwidth used by the stream via bwm-ng or similar tools.

ffmpeg

For unknown reasons ffmpeg / ffplay produced only distorted and partial frames (at least for my Hero7 Silver):

ffplay -fflags nobuffer -f:v mpegts -probesize 8192 udp://:8554

After quite a good amount of playing around with different ffmpeg's and ffplay's options, I gave up.

gstreamer

gstreamer is a great pipeline-based processor for audio and video data. For unknown reasons it was quite trivial (compared to ffmpeg) to extract a beautiful video stream with its udpsrc module.

  • watch the stream locally:

    gst-launch-1.0 udpsrc uri=udp://0.0.0.0:8554 \! tsdemux latency=100 \! h264parse \! avdec_h264 \! videoconvert \! gtksink
  • send the stream to a remote RTMP server (see below for its setup):

    gst-launch-1.0 udpsrc uri=udp://0.0.0.0:8554 \! tsdemux latency=100 \! "video/x-h264,profile=baseline,framerate=10/1" \! h264parse \! flvmux streamable=true \! queue \! rtmpsink location="rtmp://example.org/camera/foo live=1"
  • serve a stream for local access (e.g. via OBS Studio):

    gst-launch-1.0 udpsrc uri=udp://0.0.0.0:8554 \! tsdemux latency=100 \! "video/x-h264,profile=baseline,framerate=10/1" \! queue \! udpsink host=127.0.0.1 port=1234
    • since v26.1 OBS supports the Virtual CAM feature (providing a /dev/videoX device to be used in a browser and other desktop programs - see below for a similar approach directly via gstreamer)

  • create a local video source (similar to a local webcam):

    gst-launch-1.0 udpsrc uri=udp://0.0.0.0:8554 \! tsdemux latency=100 \! "video/x-h264, profile=baseline, framerate=30/1, width=640, height=480, format=(string)YUY2" \! h264parse \! avdec_h264 \! queue \! videoconvert \! v4l2sink device=/dev/video2 sync=false
    • adjust the /dev/videoX selection according to your locally accessible devices

    • the /dev/videoX device can be used by your local programs (e.g. join a jitsi] meeting with your browser)

    • the v4l2loopback module is required (apt install v4l2loopback-dkms)

    • Chromium: in order to use this virtual camera (e.g. for video conferences), you need to add a specific parameter when loading the module (see v4l2loopback#274):

      modprobe v4l2loopback exclusive_caps=1
    • Firefox: only the very first frame is shown (no further updates) - see v4l2loopback#190 for details

Stream server (nginx)

The rtmpsink pipeline above can be used for sending the stream to an rtmp server.

An easily accessible setup can be accomplished with nginx in combination with the rtmp module:

  • apt install libnginx-mod-rtmp

  • module configuration for receiving a stream (to be placed below /etc/nginx/modules-enabled/, since it operates above the http level):

    rtmp_auto_push on;
    
    rtmp {
        server {
            listen 1935;
    
            chunk_size 4000;
    
            application camera {
                live on;
    
                dash on;
                dash_nested;
                dash_path /run/nginx-rtmp/dash;
                dash_fragment 3;
                dash_playlist_length 3;
    
                hls on;
                hls_nested on;
                hls_fragment_naming system;
                hls_path /run/nginx-rtmp/hls;
                hls_fragment 3;
                hls_playlist_length 6;
    
                allow publish 127.0.0.1;
                deny publish all;
                allow play 192.168.0.0/24;
                deny play all;
            }
        }
    }
  • site configuration for delivering the streams via HTTP (to be located below /etc/nginx/sites-enabled/:

    server {
        listen 80;
        server_name stream.example.org;
        root /var/www/html;
    
        # Source: https://gist.github.com/spiermar/b389b96642fb973d0cc9766ee7b559ac
        location /play/ {
            add_header Cache-Control no-cache;
    
            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length';
    
            # Allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }
    
            location /play/hls/ {
                types {
                    application/vnd.apple.mpegurl m3u8;
                    video/mp2t ts;
                }
                alias /run/nginx-rtmp/hls/;
            }
    
            location /play/dash/ {
                alias /run/nginx-rtmp/dash/;
                types {
                    application/dash+xml mpd;
                    video/mp4 mp4;
                }
            }
        }
    }

The streams are accessible in a variety of ways:

  • RTMP stream (if the source IP address is allowed - see above): vlc rtmp://stream.example.org/camera/foo

  • HTTP stream:
    • dash: http://stream.example.org/play/dash/foo/index.mpd

    • hls: http://stream.example.org/play/hls/foo/index.m3u8

The stream obviously only contains data while your are sending an input stream (see above: rtmpsink).

Useful ressources

GoPro Hero Streaming (zuletzt geändert am 2021-06-13 18:57:09 durch lars)


Creative Commons Lizenzvertrag
This page is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.