feat: Add signal related params to exec

This commit is contained in:
dadav
2024-01-10 20:20:00 +01:00
parent 4b62a6e34f
commit 152719441e
6 changed files with 358 additions and 156 deletions
+100 -88
View File
@@ -37,60 +37,60 @@ Ultimate camera streaming application with support RTSP, WebRTC, HomeKit, FFmpeg
--- ---
* [Fast start](#fast-start) - [Fast start](#fast-start)
* [go2rtc: Binary](#go2rtc-binary) - [go2rtc: Binary](#go2rtc-binary)
* [go2rtc: Docker](#go2rtc-docker) - [go2rtc: Docker](#go2rtc-docker)
* [go2rtc: Home Assistant Add-on](#go2rtc-home-assistant-add-on) - [go2rtc: Home Assistant Add-on](#go2rtc-home-assistant-add-on)
* [go2rtc: Home Assistant Integration](#go2rtc-home-assistant-integration) - [go2rtc: Home Assistant Integration](#go2rtc-home-assistant-integration)
* [go2rtc: Dev version](#go2rtc-dev-version) - [go2rtc: Dev version](#go2rtc-dev-version)
* [Configuration](#configuration) - [Configuration](#configuration)
* [Module: Streams](#module-streams) - [Module: Streams](#module-streams)
* [Two way audio](#two-way-audio) - [Two way audio](#two-way-audio)
* [Source: RTSP](#source-rtsp) - [Source: RTSP](#source-rtsp)
* [Source: RTMP](#source-rtmp) - [Source: RTMP](#source-rtmp)
* [Source: HTTP](#source-http) - [Source: HTTP](#source-http)
* [Source: ONVIF](#source-onvif) - [Source: ONVIF](#source-onvif)
* [Source: FFmpeg](#source-ffmpeg) - [Source: FFmpeg](#source-ffmpeg)
* [Source: FFmpeg Device](#source-ffmpeg-device) - [Source: FFmpeg Device](#source-ffmpeg-device)
* [Source: Exec](#source-exec) - [Source: Exec](#source-exec)
* [Source: Echo](#source-echo) - [Source: Echo](#source-echo)
* [Source: Expr](#source-expr) - [Source: Expr](#source-expr)
* [Source: HomeKit](#source-homekit) - [Source: HomeKit](#source-homekit)
* [Source: Bubble](#source-bubble) - [Source: Bubble](#source-bubble)
* [Source: DVRIP](#source-dvrip) - [Source: DVRIP](#source-dvrip)
* [Source: Tapo](#source-tapo) - [Source: Tapo](#source-tapo)
* [Source: Kasa](#source-kasa) - [Source: Kasa](#source-kasa)
* [Source: GoPro](#source-gopro) - [Source: GoPro](#source-gopro)
* [Source: Ivideon](#source-ivideon) - [Source: Ivideon](#source-ivideon)
* [Source: Hass](#source-hass) - [Source: Hass](#source-hass)
* [Source: ISAPI](#source-isapi) - [Source: ISAPI](#source-isapi)
* [Source: Nest](#source-nest) - [Source: Nest](#source-nest)
* [Source: Roborock](#source-roborock) - [Source: Roborock](#source-roborock)
* [Source: WebRTC](#source-webrtc) - [Source: WebRTC](#source-webrtc)
* [Source: WebTorrent](#source-webtorrent) - [Source: WebTorrent](#source-webtorrent)
* [Incoming sources](#incoming-sources) - [Incoming sources](#incoming-sources)
* [Stream to camera](#stream-to-camera) - [Stream to camera](#stream-to-camera)
* [Publish stream](#publish-stream) - [Publish stream](#publish-stream)
* [Module: API](#module-api) - [Module: API](#module-api)
* [Module: RTSP](#module-rtsp) - [Module: RTSP](#module-rtsp)
* [Module: RTMP](#module-rtmp) - [Module: RTMP](#module-rtmp)
* [Module: WebRTC](#module-webrtc) - [Module: WebRTC](#module-webrtc)
* [Module: HomeKit](#module-homekit) - [Module: HomeKit](#module-homekit)
* [Module: WebTorrent](#module-webtorrent) - [Module: WebTorrent](#module-webtorrent)
* [Module: ngrok](#module-ngrok) - [Module: ngrok](#module-ngrok)
* [Module: Hass](#module-hass) - [Module: Hass](#module-hass)
* [Module: MP4](#module-mp4) - [Module: MP4](#module-mp4)
* [Module: HLS](#module-hls) - [Module: HLS](#module-hls)
* [Module: MJPEG](#module-mjpeg) - [Module: MJPEG](#module-mjpeg)
* [Module: Log](#module-log) - [Module: Log](#module-log)
* [Security](#security) - [Security](#security)
* [Codecs filters](#codecs-filters) - [Codecs filters](#codecs-filters)
* [Codecs madness](#codecs-madness) - [Codecs madness](#codecs-madness)
* [Codecs negotiation](#codecs-negotiation) - [Codecs negotiation](#codecs-negotiation)
* [Projects using go2rtc](#projects-using-go2rtc) - [Projects using go2rtc](#projects-using-go2rtc)
* [Camera experience](#cameras-experience) - [Camera experience](#cameras-experience)
* [TIPS](#tips) - [TIPS](#tips)
* [FAQ](#faq) - [FAQ](#faq)
## Fast start ## Fast start
@@ -152,7 +152,7 @@ Latest, but maybe unstable version:
## Configuration ## Configuration
- by default go2rtc will search `go2rtc.yaml` in the current work dirrectory - by default go2rtc will search `go2rtc.yaml` in the current work directory
- `api` server will start on default **1984 port** (TCP) - `api` server will start on default **1984 port** (TCP)
- `rtsp` server will start on default **8554 port** (TCP) - `rtsp` server will start on default **8554 port** (TCP)
- `webrtc` will use port **8555** (TCP/UDP) for connections - `webrtc` will use port **8555** (TCP/UDP) for connections
@@ -305,7 +305,7 @@ streams:
#### Source: ONVIF #### Source: ONVIF
*[New in v1.5.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.5.0)* _[New in v1.5.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.5.0)_
The source is not very useful if you already know RTSP and snapshot links for your camera. But it can be useful if you don't. The source is not very useful if you already know RTSP and snapshot links for your camera. But it can be useful if you don't.
@@ -399,12 +399,23 @@ streams:
#### Source: Exec #### Source: Exec
Exec source can run any external application and expect data from it. Two transports are supported - **pipe** (*from [v1.5.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.5.0)*) and **RTSP**. Exec source can run any external application and expect data from it. Two transports are supported - **pipe** (_from [v1.5.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.5.0)_) and **RTSP**.
If you want to use **RTSP** transport - the command must contain the `{output}` argument in any place. On launch, it will be replaced by the local address of the RTSP server. If you want to use **RTSP** transport - the command must contain the `{output}` argument in any place. On launch, it will be replaced by the local address of the RTSP server.
**pipe** reads data from app stdout in different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**. **pipe** reads data from app stdout in different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**.
Pipe commands support two parameters:
- **killsignal**: Signal which will be send to stop the process (default: sigkill)
- **killtimeout**: Time in seconds after the process will killed with sigkill (default: 5)
The **killtimeout** parameter is only relevant if **killsignal** is not sigkill.
Setting **killtimeout** to a negative number (or zero) will result in an immediate SIGKILL.
See `man 7 signal` to get a full list of all the signals.
Format: `exec:{command}#{param1}#{param2}`
The source can be used with: The source can be used with:
- [FFmpeg](https://ffmpeg.org/) - go2rtc ffmpeg source just a shortcut to exec source - [FFmpeg](https://ffmpeg.org/) - go2rtc ffmpeg source just a shortcut to exec source
@@ -417,6 +428,7 @@ streams:
stream: exec:ffmpeg -re -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {output} stream: exec:ffmpeg -re -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {output}
picam_h264: exec:libcamera-vid -t 0 --inline -o - picam_h264: exec:libcamera-vid -t 0 --inline -o -
picam_mjpeg: exec:libcamera-vid -t 0 --codec mjpeg -o - picam_mjpeg: exec:libcamera-vid -t 0 --codec mjpeg -o -
canon: exec:gphoto2 --capture-movie --stdout#killsignal=sigint
``` ```
#### Source: Echo #### Source: Echo
@@ -434,7 +446,7 @@ streams:
#### Source: Expr #### Source: Expr
*[New in v1.8.2](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.2)* _[New in v1.8.2](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.2)_
Like `echo` source, but uses the built-in [expr](https://github.com/antonmedv/expr) expression language ([read more](https://github.com/AlexxIT/go2rtc/blob/master/internal/expr/README.md)). Like `echo` source, but uses the built-in [expr](https://github.com/antonmedv/expr) expression language ([read more](https://github.com/AlexxIT/go2rtc/blob/master/internal/expr/README.md)).
@@ -473,7 +485,7 @@ RTSP link with "normal" audio for any player: `rtsp://192.168.1.123:8554/aqara_g
#### Source: Bubble #### Source: Bubble
*[New in v1.6.1](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.1)* _[New in v1.6.1](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.1)_
Other names: [ESeeCloud](http://www.eseecloud.com/), [dvr163](http://help.dvr163.com/). Other names: [ESeeCloud](http://www.eseecloud.com/), [dvr163](http://help.dvr163.com/).
@@ -487,7 +499,7 @@ streams:
#### Source: DVRIP #### Source: DVRIP
*[New in v1.2.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.2.0)* _[New in v1.2.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.2.0)_
Other names: DVR-IP, NetSurveillance, Sofia protocol (NETsurveillance ActiveX plugin XMeye SDK). Other names: DVR-IP, NetSurveillance, Sofia protocol (NETsurveillance ActiveX plugin XMeye SDK).
@@ -507,7 +519,7 @@ streams:
#### Source: Tapo #### Source: Tapo
*[New in v1.2.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.2.0)* _[New in v1.2.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.2.0)_
[TP-Link Tapo](https://www.tapo.com/) proprietary camera protocol with **two way audio** support. [TP-Link Tapo](https://www.tapo.com/) proprietary camera protocol with **two way audio** support.
@@ -533,7 +545,7 @@ echo -n "cloud password" | shasum -a 256 | awk '{print toupper($0)}'
#### Source: Kasa #### Source: Kasa
*[New in v1.7.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.7.0)* _[New in v1.7.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.7.0)_
[TP-Link Kasa](https://www.kasasmart.com/) non-standard protocol [more info](https://medium.com/@hu3vjeen/reverse-engineering-tp-link-kc100-bac4641bf1cd). [TP-Link Kasa](https://www.kasasmart.com/) non-standard protocol [more info](https://medium.com/@hu3vjeen/reverse-engineering-tp-link-kc100-bac4641bf1cd).
@@ -544,7 +556,7 @@ streams:
#### Source: GoPro #### Source: GoPro
*[New in v1.8.3](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.3)* _[New in v1.8.3](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.3)_
Support streaming from [GoPro](https://gopro.com/) cameras, connected via USB or Wi-Fi to Linux, Mac, Windows. [Read more](https://github.com/AlexxIT/go2rtc/tree/master/internal/gopro). Support streaming from [GoPro](https://gopro.com/) cameras, connected via USB or Wi-Fi to Linux, Mac, Windows. [Read more](https://github.com/AlexxIT/go2rtc/tree/master/internal/gopro).
@@ -575,7 +587,7 @@ streams:
aqara_g3: hass:Camera-Hub-G3-AB12 aqara_g3: hass:Camera-Hub-G3-AB12
``` ```
**WebRTC Cameras** (*from [v1.6.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.0)*) **WebRTC Cameras** (_from [v1.6.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.0)_)
Any cameras in WebRTC format are supported. But at the moment Home Assistant only supports some [Nest](https://www.home-assistant.io/integrations/nest/) cameras in this fomat. Any cameras in WebRTC format are supported. But at the moment Home Assistant only supports some [Nest](https://www.home-assistant.io/integrations/nest/) cameras in this fomat.
@@ -595,7 +607,7 @@ By default, the Home Assistant API does not allow you to get dynamic RTSP link t
#### Source: ISAPI #### Source: ISAPI
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
This source type support only backchannel audio for Hikvision ISAPI protocol. So it should be used as second source in addition to the RTSP protocol. This source type support only backchannel audio for Hikvision ISAPI protocol. So it should be used as second source in addition to the RTSP protocol.
@@ -608,7 +620,7 @@ streams:
#### Source: Nest #### Source: Nest
*[New in v1.6.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.0)* _[New in v1.6.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.0)_
Currently only WebRTC cameras are supported. Stream reconnects every 5 minutes. Currently only WebRTC cameras are supported. Stream reconnects every 5 minutes.
@@ -621,7 +633,7 @@ streams:
#### Source: Roborock #### Source: Roborock
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
This source type support Roborock vacuums with cameras. Known working models: This source type support Roborock vacuums with cameras. Known working models:
@@ -634,7 +646,7 @@ If you have graphic pin for your vacuum - add it as numeric pin (lines: 123, 456
#### Source: WebRTC #### Source: WebRTC
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
This source type support four connection formats. This source type support four connection formats.
@@ -646,15 +658,15 @@ This source type support four connection formats.
This format is only supported in go2rtc. Unlike WHEP it supports asynchronous WebRTC connection and two way audio. This format is only supported in go2rtc. Unlike WHEP it supports asynchronous WebRTC connection and two way audio.
**openipc** (*from [v1.7.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.7.0)*) **openipc** (_from [v1.7.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.7.0)_)
Support connection to [OpenIPC](https://openipc.org/) cameras. Support connection to [OpenIPC](https://openipc.org/) cameras.
**wyze** (*from [v1.6.1](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.1)*) **wyze** (_from [v1.6.1](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.1)_)
Supports connection to [Wyze](https://www.wyze.com/) cameras, using WebRTC protocol. You can use [docker-wyze-bridge](https://github.com/mrlt8/docker-wyze-bridge) project to get connection credentials. Supports connection to [Wyze](https://www.wyze.com/) cameras, using WebRTC protocol. You can use [docker-wyze-bridge](https://github.com/mrlt8/docker-wyze-bridge) project to get connection credentials.
**kinesis** (*from [v1.6.1](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.1)*) **kinesis** (_from [v1.6.1](https://github.com/AlexxIT/go2rtc/releases/tag/v1.6.1)_)
Supports [Amazon Kinesis Video Streams](https://aws.amazon.com/kinesis/video-streams/), using WebRTC protocol. You need to specify signalling WebSocket URL with all credentials in query params, `client_id` and `ice_servers` list in [JSON format](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer). Supports [Amazon Kinesis Video Streams](https://aws.amazon.com/kinesis/video-streams/), using WebRTC protocol. You need to specify signalling WebSocket URL with all credentials in query params, `client_id` and `ice_servers` list in [JSON format](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer).
@@ -671,7 +683,7 @@ streams:
#### Source: WebTorrent #### Source: WebTorrent
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
This source can get a stream from another go2rtc via [WebTorrent](#module-webtorrent) protocol. This source can get a stream from another go2rtc via [WebTorrent](#module-webtorrent) protocol.
@@ -711,7 +723,7 @@ By default, go2rtc establishes a connection to the source when any client reques
#### Incoming: Browser #### Incoming: Browser
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
You can turn the browser of any PC or mobile into an IP-camera with support video and two way audio. Or even broadcast your PC screen: You can turn the browser of any PC or mobile into an IP-camera with support video and two way audio. Or even broadcast your PC screen:
@@ -723,7 +735,7 @@ You can turn the browser of any PC or mobile into an IP-camera with support vide
#### Incoming: WebRTC/WHIP #### Incoming: WebRTC/WHIP
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
You can use **OBS Studio** or any other broadcast software with [WHIP](https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html) protocol support. This standard has not yet been approved. But you can download OBS Studio [dev version](https://github.com/obsproject/obs-studio/actions/runs/3969201209): You can use **OBS Studio** or any other broadcast software with [WHIP](https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html) protocol support. This standard has not yet been approved. But you can download OBS Studio [dev version](https://github.com/obsproject/obs-studio/actions/runs/3969201209):
@@ -731,7 +743,7 @@ You can use **OBS Studio** or any other broadcast software with [WHIP](https://w
#### Stream to camera #### Stream to camera
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
go2rtc support play audio files (ex. music or [TTS](https://www.home-assistant.io/integrations/#text-to-speech)) and live streams (ex. radio) on cameras with [two way audio](#two-way-audio) support (RTSP/ONVIF cameras, TP-Link Tapo, Hikvision ISAPI, Roborock vacuums, any Browser). go2rtc support play audio files (ex. music or [TTS](https://www.home-assistant.io/integrations/#text-to-speech)) and live streams (ex. radio) on cameras with [two way audio](#two-way-audio) support (RTSP/ONVIF cameras, TP-Link Tapo, Hikvision ISAPI, Roborock vacuums, any Browser).
@@ -753,7 +765,7 @@ POST http://localhost:1984/api/streams?dst=camera1&src=ffmpeg:http://example.com
### Publish stream ### Publish stream
*[New in v1.8.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.0)* _[New in v1.8.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.0)_
You can publish any stream to streaming services (YouTube, Telegram, etc.) via RTMP/RTMPS. Important: You can publish any stream to streaming services (YouTube, Telegram, etc.) via RTMP/RTMPS. Important:
@@ -852,7 +864,7 @@ Read more about [codecs filters](#codecs-filters).
### Module: RTMP ### Module: RTMP
*[New in v1.8.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.0)* _[New in v1.8.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.8.0)_
You can get any stream as RTMP-stream: `rtmp://192.168.1.123/{stream_name}`. Only H264/AAC codecs supported right now. You can get any stream as RTMP-stream: `rtmp://192.168.1.123/{stream_name}`. Only H264/AAC codecs supported right now.
@@ -932,7 +944,7 @@ webrtc:
### Module: HomeKit ### Module: HomeKit
*[New in v1.7.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.7.0)* _[New in v1.7.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.7.0)_
HomeKit module can work in two modes: HomeKit module can work in two modes:
@@ -986,7 +998,7 @@ homekit:
### Module: WebTorrent ### Module: WebTorrent
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)* _[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)_
This module support: This module support:
@@ -1118,7 +1130,7 @@ API examples:
- MP4 snapshot: `http://192.168.1.123:1984/api/frame.mp4?src=camera1` (H264, H265) - MP4 snapshot: `http://192.168.1.123:1984/api/frame.mp4?src=camera1` (H264, H265)
- MP4 stream: `http://192.168.1.123:1984/api/stream.mp4?src=camera1` (H264, H265, AAC) - MP4 stream: `http://192.168.1.123:1984/api/stream.mp4?src=camera1` (H264, H265, AAC)
- MP4 file: `http://192.168.1.123:1984/api/stream.mp4?src=camera1` (H264, H265*, AAC, OPUS, MP3, PCMA, PCMU, PCM) - MP4 file: `http://192.168.1.123:1984/api/stream.mp4?src=camera1` (H264, H265\*, AAC, OPUS, MP3, PCMA, PCMU, PCM)
- You can use `mp4`, `mp4=flac` and `mp4=all` param for codec filters - You can use `mp4`, `mp4=flac` and `mp4=all` param for codec filters
- You can use `duration` param in seconds (ex. `duration=15`) - You can use `duration` param in seconds (ex. `duration=15`)
- You can use `filename` param (ex. `filename=record.mp4`) - You can use `filename` param (ex. `filename=record.mp4`)
@@ -1131,7 +1143,7 @@ Read more about [codecs filters](#codecs-filters).
### Module: HLS ### Module: HLS
*[New in v1.1.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.1.0)* _[New in v1.1.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.1.0)_
[HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming) is the worst technology for real-time streaming. It can only be useful on devices that do not support more modern technology, like [WebRTC](#module-webrtc), [MSE/MP4](#module-mp4). [HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming) is the worst technology for real-time streaming. It can only be useful on devices that do not support more modern technology, like [WebRTC](#module-webrtc), [MSE/MP4](#module-mp4).
@@ -1240,14 +1252,14 @@ Some examples:
`AVC/H.264` video can be played almost anywhere. But `HEVC/H.265` has a lot of limitations in supporting with different devices and browsers. It's all about patents and money, you can't do anything about it. `AVC/H.264` video can be played almost anywhere. But `HEVC/H.265` has a lot of limitations in supporting with different devices and browsers. It's all about patents and money, you can't do anything about it.
| Device | WebRTC | MSE | HTTP* | HLS | | Device | WebRTC | MSE | HTTP\* | HLS |
|--------------------------------------------------------------------------|-----------------------------------------|-----------------------------------------|----------------------------------------------|-----------------------------| | ------------------------------------------------------------------------ | ---------------------------------------- | --------------------------------------- | -------------------------------------------- | ---------------------------- |
| *latency* | best | medium | bad | bad | | _latency_ | best | medium | bad | bad |
| - Desktop Chrome 107+ <br/> - Desktop Edge <br/> - Android Chrome 107+ | H264 <br/> PCMU, PCMA <br/> OPUS | H264, H265* <br/> AAC, FLAC* <br/> OPUS | H264, H265* <br/> AAC, FLAC* <br/> OPUS, MP3 | no | | - Desktop Chrome 107+ <br/> - Desktop Edge <br/> - Android Chrome 107+ | H264 <br/> PCMU, PCMA <br/> OPUS | H264, H265* <br/> AAC, FLAC* <br/> OPUS | H264, H265* <br/> AAC, FLAC* <br/> OPUS, MP3 | no |
| Desktop Firefox | H264 <br/> PCMU, PCMA <br/> OPUS | H264 <br/> AAC, FLAC* <br/> OPUS | H264 <br/> AAC, FLAC* <br/> OPUS | no | | Desktop Firefox | H264 <br/> PCMU, PCMA <br/> OPUS | H264 <br/> AAC, FLAC\* <br/> OPUS | H264 <br/> AAC, FLAC\* <br/> OPUS | no |
| - Desktop Safari 14+ <br/> - iPad Safari 14+ <br/> - iPhone Safari 17.1+ | H264, H265* <br/> PCMU, PCMA <br/> OPUS | H264, H265 <br/> AAC, FLAC* | **no!** | H264, H265 <br/> AAC, FLAC* | | - Desktop Safari 14+ <br/> - iPad Safari 14+ <br/> - iPhone Safari 17.1+ | H264, H265\* <br/> PCMU, PCMA <br/> OPUS | H264, H265 <br/> AAC, FLAC\* | **no!** | H264, H265 <br/> AAC, FLAC\* |
| iPhone Safari 14+ | H264, H265* <br/> PCMU, PCMA <br/> OPUS | **no!** | **no!** | H264, H265 <br/> AAC, FLAC* | | iPhone Safari 14+ | H264, H265\* <br/> PCMU, PCMA <br/> OPUS | **no!** | **no!** | H264, H265 <br/> AAC, FLAC\* |
| macOS [Hass App][1] | no | no | no | H264, H265 <br/> AAC, FLAC* | | macOS [Hass App][1] | no | no | no | H264, H265 <br/> AAC, FLAC\* |
[1]: https://apps.apple.com/app/home-assistant/id1099568401 [1]: https://apps.apple.com/app/home-assistant/id1099568401
+20 -7
View File
@@ -20,6 +20,12 @@ import (
"github.com/rs/zerolog" "github.com/rs/zerolog"
) )
type Params struct {
KillSignal os.Signal
Command string
KillTimeout time.Duration
}
func Init() { func Init() {
rtsp.HandleFunc(func(conn *pkg.Conn) bool { rtsp.HandleFunc(func(conn *pkg.Conn) bool {
waitersMu.Lock() waitersMu.Lock()
@@ -47,7 +53,12 @@ func Init() {
func execHandle(url string) (core.Producer, error) { func execHandle(url string) (core.Producer, error) {
var path string var path string
args := shell.QuoteSplit(url[5:]) // remove `exec:` params, err := parseParams(url)
if err != nil {
return nil, err
}
args := shell.QuoteSplit(params.Command[5:]) // remove `exec:`
for i, arg := range args { for i, arg := range args {
if arg == "{output}" { if arg == "{output}" {
if rtsp.Port == "" { if rtsp.Port == "" {
@@ -67,14 +78,14 @@ func execHandle(url string) (core.Producer, error) {
} }
if path == "" { if path == "" {
return handlePipe(url, cmd) return handlePipe(url, cmd, params)
} }
return handleRTSP(url, path, cmd) return handleRTSP(url, path, cmd)
} }
func handlePipe(url string, cmd *exec.Cmd) (core.Producer, error) { func handlePipe(_ string, cmd *exec.Cmd, params *Params) (core.Producer, error) {
r, err := PipeCloser(cmd) r, err := PipeCloser(cmd, params)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -144,6 +155,8 @@ func handleRTSP(url, path string, cmd *exec.Cmd) (core.Producer, error) {
// internal // internal
var log zerolog.Logger var (
var waiters = map[string]chan core.Producer{} log zerolog.Logger
var waitersMu sync.Mutex waiters = map[string]chan core.Producer{}
waitersMu sync.Mutex
)
+34
View File
@@ -0,0 +1,34 @@
//go:build !linux
package exec
import (
"fmt"
"net/url"
"runtime"
"strings"
"github.com/AlexxIT/go2rtc/internal/streams"
)
func parseParams(s string) (*Params, error) {
args := &Params{
Command: s,
}
var query url.Values
if i := strings.IndexByte(s, '#'); i > 0 {
query = streams.ParseQuery(s[i+1:])
args.Command = s[:i]
}
if _, ok := query["killsignal"]; ok {
return nil, fmt.Errorf("killsignal is not supported this %s", runtime.GOOS)
}
if _, ok := query["killtimeout"]; ok {
return nil, fmt.Errorf("killtimeout is not supported in %s", runtime.GOOS)
}
return args, nil
}
+88
View File
@@ -0,0 +1,88 @@
package exec
import (
"fmt"
"net/url"
"os"
"strconv"
"strings"
"syscall"
"time"
"github.com/AlexxIT/go2rtc/internal/streams"
)
func parseParams(s string) (*Params, error) {
args := &Params{
KillSignal: syscall.SIGKILL,
KillTimeout: 5 * time.Second,
Command: s,
}
var query url.Values
if i := strings.IndexByte(s, '#'); i > 0 {
query = streams.ParseQuery(s[i+1:])
args.Command = s[:i]
}
if val, ok := query["killsignal"]; ok {
if sig, err := parseSignal(val[0]); err == nil {
args.KillSignal = sig
} else {
return nil, fmt.Errorf("could not parse killsignal param (%s)", val[0])
}
}
if val, ok := query["killtimeout"]; ok {
if i, err := strconv.Atoi(val[0]); err == nil {
args.KillTimeout = time.Duration(i) * time.Second
} else {
return nil, fmt.Errorf("could not convert killtimeout param (%s) to int", val[0])
}
}
return args, nil
}
func parseSignal(signalString string) (os.Signal, error) {
signalMap := map[string]os.Signal{
"sighup": syscall.SIGHUP,
"sigint": syscall.SIGINT,
"sigquit": syscall.SIGQUIT,
"sigill": syscall.SIGILL,
"sigtrap": syscall.SIGTRAP,
"sigabrt": syscall.SIGABRT,
"sigbus": syscall.SIGBUS,
"sigfpe": syscall.SIGFPE,
"sigkill": syscall.SIGKILL,
"sigusr1": syscall.SIGUSR1,
"sigsegv": syscall.SIGSEGV,
"sigusr2": syscall.SIGUSR2,
"sigpipe": syscall.SIGPIPE,
"sigalrm": syscall.SIGALRM,
"sigterm": syscall.SIGTERM,
"sigchld": syscall.SIGCHLD,
"sigcont": syscall.SIGCONT,
"sigstop": syscall.SIGSTOP,
"sigtstp": syscall.SIGTSTP,
"sigttin": syscall.SIGTTIN,
"sigttou": syscall.SIGTTOU,
"sigurg": syscall.SIGURG,
"sigxcpu": syscall.SIGXCPU,
"sigxfsz": syscall.SIGXFSZ,
"sigvtalrm": syscall.SIGVTALRM,
"sigprof": syscall.SIGPROF,
"sigwinch": syscall.SIGWINCH,
"sigio": syscall.SIGIO,
"sigpoll": syscall.SIGPOLL,
"sigpwr": syscall.SIGPWR,
"sigsys": syscall.SIGSYS,
}
signalValue, ok := signalMap[strings.ToLower(signalString)]
if !ok {
return nil, fmt.Errorf("invalid signal: %s", signalString)
}
return signalValue, nil
}
+10 -3
View File
@@ -1,3 +1,5 @@
//go:build !linux
package exec package exec
import ( import (
@@ -9,22 +11,27 @@ import (
) )
// PipeCloser - return StdoutPipe that Kill cmd on Close call // PipeCloser - return StdoutPipe that Kill cmd on Close call
func PipeCloser(cmd *exec.Cmd) (io.ReadCloser, error) { func PipeCloser(cmd *exec.Cmd, params *Params) (io.ReadCloser, error) {
stdout, err := cmd.StdoutPipe() stdout, err := cmd.StdoutPipe()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// add buffer for pipe reader to reduce syscall // add buffer for pipe reader to reduce syscall
return pipeCloser{bufio.NewReaderSize(stdout, core.BufferSize), stdout, cmd}, nil return pipeCloser{bufio.NewReaderSize(stdout, core.BufferSize), stdout, cmd, params}, nil
} }
type pipeCloser struct { type pipeCloser struct {
io.Reader io.Reader
io.Closer io.Closer
cmd *exec.Cmd cmd *exec.Cmd
params *Params
} }
func (p pipeCloser) Close() error { func (p pipeCloser) Close() error {
return core.Any(p.Closer.Close(), p.cmd.Process.Kill(), p.cmd.Wait()) finished := make(chan bool)
err := core.Any(p.Closer.Close(), p.cmd.Process.Kill(), p.cmd.Wait())
finished <- true
return err
} }
+48
View File
@@ -0,0 +1,48 @@
package exec
import (
"bufio"
"io"
"os/exec"
"syscall"
"time"
"github.com/AlexxIT/go2rtc/pkg/core"
)
// PipeCloser - return StdoutPipe that Kill cmd on Close call
func PipeCloser(cmd *exec.Cmd, params *Params) (io.ReadCloser, error) {
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
// add buffer for pipe reader to reduce syscall
return pipeCloser{bufio.NewReaderSize(stdout, core.BufferSize), stdout, cmd, params}, nil
}
type pipeCloser struct {
io.Reader
io.Closer
cmd *exec.Cmd
params *Params
}
func (p pipeCloser) Close() error {
finished := make(chan bool)
if p.params.KillSignal != syscall.SIGKILL {
go func() {
select {
case <-time.After(p.params.KillTimeout):
p.cmd.Process.Kill()
break
case <-finished:
break
}
}()
}
err := core.Any(p.Closer.Close(), p.cmd.Process.Signal(p.params.KillSignal), p.cmd.Wait())
finished <- true
return err
}