From 2dde22b448d8174477e136c1147c1c273511eacb Mon Sep 17 00:00:00 2001 From: deflax Date: Sun, 31 Dec 2023 04:15:22 +0000 Subject: [PATCH] include the rest of the files --- .gitignore | 6 +- config/archive/nginx.conf | 20 ++ config/haproxy/haproxy.cfg.dist | 84 +++++ config/mediamtx/mediamtx.yml | 564 ++++++++++++++++++++++++++++++++ docker-compose.yml.dist | 104 ++++++ src/scheduler/app.py | 2 +- 6 files changed, 778 insertions(+), 2 deletions(-) create mode 100644 config/archive/nginx.conf create mode 100644 config/haproxy/haproxy.cfg.dist create mode 100644 config/mediamtx/mediamtx.yml create mode 100644 docker-compose.yml.dist diff --git a/.gitignore b/.gitignore index 2e0fc66..02eeead 100644 --- a/.gitignore +++ b/.gitignore @@ -161,5 +161,9 @@ cython_debug/ # television -certbot.env +data/ logs/ +docker-compose.yml +certbot.env +haproxy.cfg +*.json diff --git a/config/archive/nginx.conf b/config/archive/nginx.conf new file mode 100644 index 0000000..e49acdb --- /dev/null +++ b/config/archive/nginx.conf @@ -0,0 +1,20 @@ +events { + +} + +http { + error_log /etc/nginx/error_log.log warn; + client_max_body_size 20m; + + proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m; + + + server { + server_name vod.deflax.net; + root /recordings; + + location /live/ { + autoindex on; + } + } +} diff --git a/config/haproxy/haproxy.cfg.dist b/config/haproxy/haproxy.cfg.dist new file mode 100644 index 0000000..0a14d35 --- /dev/null +++ b/config/haproxy/haproxy.cfg.dist @@ -0,0 +1,84 @@ +global + maxconn 4096 + user root + group root + daemon + + tune.ssl.default-dh-param 2048 + ssl-default-bind-options no-sslv3 no-tls-tickets + ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA + +defaults + #log stdout format raw local0 debug + log stdout format raw local0 notice + mode http + balance roundrobin + maxconn 1024 + + #This breaks HTTP2 + #option abortonclose + option httpclose + option forwardfor + + retries 3 + option redispatch + + timeout client 30s + timeout connect 30s + timeout server 30s + + #option httpchk HEAD /haproxy?monitor HTTP/1.0 + #timeout check 5s + #stats enable + #stats uri /haproxy?stats + #stats realm Haproxy\ Statistics + #stats auth admin:yourpasswordhere + #stats refresh 5s + +# PUBLIC +frontend http + bind :80 + option http-server-close + redirect scheme https if ! { path_beg -i /.well-known/acme-challenge } + default_backend certbot + +backend certbot + server c1 certbot:80 + +frontend https + bind :443 ssl crt /certificates alpn http/1.1 + + http-request set-header X-Forwarded-Protocol https + http-request set-header X-Forwarded-Proto https + http-request set-header X-Forwarded-Ssl on + http-request set-header X-Url-Scheme https + http-request set-header Host %[ssl_fc_sni] + + # CORS + http-response set-header Access-Control-Allow-Origin "*" + http-response set-header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization, JSNLog-RequestId, activityId, applicationId, applicationUserId, channelId, senderId, sessionId" + http-response set-header Access-Control-Max-Age 3628800 + http-response set-header Access-Control-Allow-Methods "GET" + + # Router + # ACL to match the sni hosts + acl is_stream ssl_fc_sni -i stream.example.com + acl is_tv ssl_fc_sni -i tv.example.com + acl is_vod ssl_fc_sni -i vod.example.com + + # Define the ACL conditions and corresponding actions + use_backend backend_restreamer if is_stream + use_backend backend_scheduler if is_tv + use_backend backend_archive if is_vod + +backend backend_restreamer + balance leastconn + server restreamer1 restreamer:8080 check inter 5s rise 4 fall 2 + +backend backend_scheduler + balance leastconn + server scheduler1 scheduler:8080 check inter 5s rise 4 fall 2 + +backend backend_archive + balance leastconn + server archive1 archive:80 check inter 5s rise 4 fall 2 diff --git a/config/mediamtx/mediamtx.yml b/config/mediamtx/mediamtx.yml new file mode 100644 index 0000000..12a6829 --- /dev/null +++ b/config/mediamtx/mediamtx.yml @@ -0,0 +1,564 @@ +############################################### +# Global settings + +# Settings in this section are applied anywhere. + +############################################### +# Global settings -> General + +# Verbosity of the program; available values are "error", "warn", "info", "debug". +logLevel: info +# Destinations of log messages; available values are "stdout", "file" and "syslog". +logDestinations: [stdout] +# If "file" is in logDestinations, this is the file which will receive the logs. +logFile: mediamtx.log + +# Timeout of read operations. +readTimeout: 10s +# Timeout of write operations. +writeTimeout: 10s +# Size of the queue of outgoing packets. +# A higher value allows to increase throughput, a lower value allows to save RAM. +writeQueueSize: 512 +# Maximum size of outgoing UDP packets. +# This can be decreased to avoid fragmentation on networks with a low UDP MTU. +udpMaxPayloadSize: 1472 + +# HTTP URL to perform external authentication. +# Every time a user wants to authenticate, the server calls this URL +# with the POST method and a body containing: +# { +# "ip": "ip", +# "user": "user", +# "password": "password", +# "path": "path", +# "protocol": "rtsp|rtmp|hls|webrtc", +# "id": "id", +# "action": "read|publish", +# "query": "query" +# } +# If the response code is 20x, authentication is accepted, otherwise +# it is discarded. +externalAuthenticationURL: + +# Enable the HTTP API. +api: yes +# Address of the API listener. +apiAddress: 127.0.0.1:9997 + +# Enable Prometheus-compatible metrics. +metrics: no +# Address of the metrics listener. +metricsAddress: 127.0.0.1:9998 + +# Enable pprof-compatible endpoint to monitor performances. +pprof: no +# Address of the pprof listener. +pprofAddress: 127.0.0.1:9999 + +# Command to run when a client connects to the server. +# This is terminated with SIGINT when a client disconnects from the server. +# The following environment variables are available: +# * RTSP_PORT: RTSP server port +# * MTX_CONN_TYPE: connection type +# * MTX_CONN_ID: connection ID +runOnConnect: +# Restart the command if it exits. +runOnConnectRestart: no +# Command to run when a client disconnects from the server. +# Environment variables are the same of runOnConnect. +runOnDisconnect: + +############################################### +# Global settings -> RTSP server + +# Allow publishing and reading streams with the RTSP protocol. +rtsp: yes +# List of enabled RTSP transport protocols. +# UDP is the most performant, but doesn't work when there's a NAT/firewall between +# server and clients, and doesn't support encryption. +# UDP-multicast allows to save bandwidth when clients are all in the same LAN. +# TCP is the most versatile, and does support encryption. +# The handshake is always performed with TCP. +protocols: [udp, multicast, tcp] +# Encrypt handshakes and TCP streams with TLS (RTSPS). +# Available values are "no", "strict", "optional". +encryption: "no" +# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional". +rtspAddress: :8554 +# Address of the TCP/TLS/RTSPS listener. This is needed only when encryption is "strict" or "optional". +rtspsAddress: :8322 +# Address of the UDP/RTP listener. This is needed only when "udp" is in protocols. +rtpAddress: :8000 +# Address of the UDP/RTCP listener. This is needed only when "udp" is in protocols. +rtcpAddress: :8001 +# IP range of all UDP-multicast listeners. This is needed only when "multicast" is in protocols. +multicastIPRange: 224.1.0.0/16 +# Port of all UDP-multicast/RTP listeners. This is needed only when "multicast" is in protocols. +multicastRTPPort: 8002 +# Port of all UDP-multicast/RTCP listeners. This is needed only when "multicast" is in protocols. +multicastRTCPPort: 8003 +# Path to the server key. This is needed only when encryption is "strict" or "optional". +# This can be generated with: +# openssl genrsa -out server.key 2048 +# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 +serverKey: server.key +# Path to the server certificate. This is needed only when encryption is "strict" or "optional". +serverCert: server.crt +# Authentication methods. Available are "basic" and "digest". +# "digest" doesn't provide any additional security and is available for compatibility reasons only. +authMethods: [basic] + +############################################### +# Global settings -> RTMP server + +# Allow publishing and reading streams with the RTMP protocol. +rtmp: no +# Address of the RTMP listener. This is needed only when encryption is "no" or "optional". +rtmpAddress: :1935 +# Encrypt connections with TLS (RTMPS). +# Available values are "no", "strict", "optional". +rtmpEncryption: "no" +# Address of the RTMPS listener. This is needed only when encryption is "strict" or "optional". +rtmpsAddress: :1936 +# Path to the server key. This is needed only when encryption is "strict" or "optional". +# This can be generated with: +# openssl genrsa -out server.key 2048 +# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 +rtmpServerKey: server.key +# Path to the server certificate. This is needed only when encryption is "strict" or "optional". +rtmpServerCert: server.crt + +############################################### +# Global settings -> HLS server + +# Allow reading streams with the HLS protocol. +hls: no +# Address of the HLS listener. +hlsAddress: :8888 +# Enable TLS/HTTPS on the HLS server. +# This is required for Low-Latency HLS. +hlsEncryption: no +# Path to the server key. This is needed only when encryption is yes. +# This can be generated with: +# openssl genrsa -out server.key 2048 +# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 +hlsServerKey: server.key +# Path to the server certificate. +hlsServerCert: server.crt +# By default, HLS is generated only when requested by a user. +# This option allows to generate it always, avoiding the delay between request and generation. +hlsAlwaysRemux: no +# Variant of the HLS protocol to use. Available options are: +# * mpegts - uses MPEG-TS segments, for maximum compatibility. +# * fmp4 - uses fragmented MP4 segments, more efficient. +# * lowLatency - uses Low-Latency HLS. +hlsVariant: lowLatency +# Number of HLS segments to keep on the server. +# Segments allow to seek through the stream. +# Their number doesn't influence latency. +hlsSegmentCount: 7 +# Minimum duration of each segment. +# A player usually puts 3 segments in a buffer before reproducing the stream. +# The final segment duration is also influenced by the interval between IDR frames, +# since the server changes the duration in order to include at least one IDR frame +# in each segment. +hlsSegmentDuration: 1s +# Minimum duration of each part. +# A player usually puts 3 parts in a buffer before reproducing the stream. +# Parts are used in Low-Latency HLS in place of segments. +# Part duration is influenced by the distance between video/audio samples +# and is adjusted in order to produce segments with a similar duration. +hlsPartDuration: 200ms +# Maximum size of each segment. +# This prevents RAM exhaustion. +hlsSegmentMaxSize: 50M +# Value of the Access-Control-Allow-Origin header provided in every HTTP response. +# This allows to play the HLS stream from an external website. +hlsAllowOrigin: '*' +# List of IPs or CIDRs of proxies placed before the HLS server. +# If the server receives a request from one of these entries, IP in logs +# will be taken from the X-Forwarded-For header. +hlsTrustedProxies: [] +# Directory in which to save segments, instead of keeping them in the RAM. +# This decreases performance, since reading from disk is less performant than +# reading from RAM, but allows to save RAM. +hlsDirectory: '' + +############################################### +# Global settings -> WebRTC server + +# Allow publishing and reading streams with the WebRTC protocol. +webrtc: no +# Address of the WebRTC HTTP listener. +webrtcAddress: :8889 +# Enable TLS/HTTPS on the WebRTC server. +webrtcEncryption: no +# Path to the server key. +# This can be generated with: +# openssl genrsa -out server.key 2048 +# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 +webrtcServerKey: server.key +# Path to the server certificate. +webrtcServerCert: server.crt +# Value of the Access-Control-Allow-Origin header provided in every HTTP response. +# This allows to play the WebRTC stream from an external website. +webrtcAllowOrigin: '*' +# List of IPs or CIDRs of proxies placed before the WebRTC server. +# If the server receives a request from one of these entries, IP in logs +# will be taken from the X-Forwarded-For header. +webrtcTrustedProxies: [] +# Address of a local UDP listener that will receive connections. +# Use a blank string to disable. +webrtcLocalUDPAddress: :8189 +# Address of a local TCP listener that will receive connections. +# This is disabled by default since TCP is less efficient than UDP and +# introduces a progressive delay when network is congested. +webrtcLocalTCPAddress: '' +# WebRTC clients need to know the IP of the server. +# Gather IPs from interfaces and send them to clients. +webrtcIPsFromInterfaces: yes +# List of interfaces whose IPs will be sent to clients. +# An empty value means to use all available interfaces. +webrtcIPsFromInterfacesList: [] +# List of additional hosts or IPs to send to clients. +webrtcAdditionalHosts: [] +# ICE servers. Needed only when local listeners can't be reached by clients. +# STUN servers allows to obtain and share the public IP of the server. +# TURN/TURNS servers forces all traffic through them. +webrtcICEServers2: [] + # - url: stun:stun.l.google.com:19302 + # if user is "AUTH_SECRET", then authentication is secret based. + # the secret must be inserted into the password field. + # username: '' + # password: '' + +############################################### +# Global settings -> SRT server + +# Allow publishing and reading streams with the SRT protocol. +srt: no +# Address of the SRT listener. +srtAddress: :8890 + +############################################### +# Default path settings + +# Settings in "pathDefaults" are applied anywhere, +# unless they are overridden in "paths". +pathDefaults: + + ############################################### + # Default path settings -> General + + # Source of the stream. This can be: + # * publisher -> the stream is provided by a RTSP, RTMP, WebRTC or SRT client + # * rtsp://existing-url -> the stream is pulled from another RTSP server / camera + # * rtsps://existing-url -> the stream is pulled from another RTSP server / camera with RTSPS + # * rtmp://existing-url -> the stream is pulled from another RTMP server / camera + # * rtmps://existing-url -> the stream is pulled from another RTMP server / camera with RTMPS + # * http://existing-url/stream.m3u8 -> the stream is pulled from another HLS server / camera + # * https://existing-url/stream.m3u8 -> the stream is pulled from another HLS server / camera with HTTPS + # * udp://ip:port -> the stream is pulled with UDP, by listening on the specified IP and port + # * srt://existing-url -> the stream is pulled from another SRT server / camera + # * whep://existing-url -> the stream is pulled from another WebRTC server / camera + # * wheps://existing-url -> the stream is pulled from another WebRTC server / camera with HTTPS + # * redirect -> the stream is provided by another path or server + # * rpiCamera -> the stream is provided by a Raspberry Pi Camera + # If path name is a regular expression, $G1, G2, etc will be replaced + # with regular expression groups. + source: publisher + # If the source is a URL, and the source certificate is self-signed + # or invalid, you can provide the fingerprint of the certificate in order to + # validate it anyway. It can be obtained by running: + # openssl s_client -connect source_ip:source_port /dev/null | sed -n '/BEGIN/,/END/p' > server.crt + # openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':' + sourceFingerprint: + # If the source is a URL, it will be pulled only when at least + # one reader is connected, saving bandwidth. + sourceOnDemand: no + # If sourceOnDemand is "yes", readers will be put on hold until the source is + # ready or until this amount of time has passed. + sourceOnDemandStartTimeout: 10s + # If sourceOnDemand is "yes", the source will be closed when there are no + # readers connected and this amount of time has passed. + sourceOnDemandCloseAfter: 10s + # Maximum number of readers. Zero means no limit. + maxReaders: 0 + # SRT encryption passphrase require to read from this path + srtReadPassphrase: + # If the stream is not available, redirect readers to this path. + # It can be can be a relative path (i.e. /otherstream) or an absolute RTSP URL. + fallback: + + ############################################### + # Default path settings -> Recording + + # Record streams to disk. + record: no + # Path of recording segments. + # Extension is added automatically. + # Available variables are %path (path name), %Y %m %d %H %M %S %f %s (time in strftime format) + recordPath: ./recordings/%path/%Y-%m-%d_%H-%M-%S-%f + # Format of recorded segments. + # Available formats are "fmp4" (fragmented MP4) and "mpegts" (MPEG-TS). + recordFormat: fmp4 + # fMP4 segments are concatenation of small MP4 files (parts), each with this duration. + # MPEG-TS segments are concatenation of 188-bytes packets, flushed to disk with this period. + # When a system failure occurs, the last part gets lost. + # Therefore, the part duration is equal to the RPO (recovery point objective). + recordPartDuration: 100ms + # Minimum duration of each segment. + recordSegmentDuration: 12h + # Delete segments after this timespan. + # Set to 0s to disable automatic deletion. + #recordDeleteAfter: 24h + recordDeleteAfter: 168h + + + ############################################### + # Default path settings -> Authentication + + # Username required to publish. + # SHA256-hashed values can be inserted with the "sha256:" prefix. + publishUser: + # Password required to publish. + # SHA256-hashed values can be inserted with the "sha256:" prefix. + publishPass: + # IPs or networks (x.x.x.x/24) allowed to publish. + publishIPs: [] + + # Username required to read. + # SHA256-hashed values can be inserted with the "sha256:" prefix. + readUser: + # password required to read. + # SHA256-hashed values can be inserted with the "sha256:" prefix. + readPass: + # IPs or networks (x.x.x.x/24) allowed to read. + readIPs: [] + + ############################################### + # Default path settings -> Publisher source (when source is "publisher") + + # Allow another client to disconnect the current publisher and publish in its place. + overridePublisher: yes + # SRT encryption passphrase required to publish to this path + srtPublishPassphrase: + + ############################################### + # Default path settings -> RTSP source (when source is a RTSP or a RTSPS URL) + + # Transport protocol used to pull the stream. available values are "automatic", "udp", "multicast", "tcp". + rtspTransport: automatic + # Support sources that don't provide server ports or use random server ports. This is a security issue + # and must be used only when interacting with sources that require it. + rtspAnyPort: no + # Range header to send to the source, in order to start streaming from the specified offset. + # available values: + # * clock: Absolute time + # * npt: Normal Play Time + # * smpte: SMPTE timestamps relative to the start of the recording + rtspRangeType: + # Available values: + # * clock: UTC ISO 8601 combined date and time string, e.g. 20230812T120000Z + # * npt: duration such as "300ms", "1.5m" or "2h45m", valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" + # * smpte: duration such as "300ms", "1.5m" or "2h45m", valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" + rtspRangeStart: + + ############################################### + # Default path settings -> Redirect source (when source is "redirect") + + # RTSP URL which clients will be redirected to. + sourceRedirect: + + ############################################### + # Default path settings -> Raspberry Pi Camera source (when source is "rpiCamera") + + # ID of the camera + rpiCameraCamID: 0 + # width of frames + rpiCameraWidth: 1920 + # height of frames + rpiCameraHeight: 1080 + # flip horizontally + rpiCameraHFlip: false + # flip vertically + rpiCameraVFlip: false + # brightness [-1, 1] + rpiCameraBrightness: 0 + # contrast [0, 16] + rpiCameraContrast: 1 + # saturation [0, 16] + rpiCameraSaturation: 1 + # sharpness [0, 16] + rpiCameraSharpness: 1 + # exposure mode. + # values: normal, short, long, custom + rpiCameraExposure: normal + # auto-white-balance mode. + # values: auto, incandescent, tungsten, fluorescent, indoor, daylight, cloudy, custom + rpiCameraAWB: auto + # denoise operating mode. + # values: off, cdn_off, cdn_fast, cdn_hq + rpiCameraDenoise: "off" + # fixed shutter speed, in microseconds. + rpiCameraShutter: 0 + # metering mode of the AEC/AGC algorithm. + # values: centre, spot, matrix, custom + rpiCameraMetering: centre + # fixed gain + rpiCameraGain: 0 + # EV compensation of the image [-10, 10] + rpiCameraEV: 0 + # Region of interest, in format x,y,width,height + rpiCameraROI: + # whether to enable HDR on Raspberry Camera 3. + rpiCameraHDR: false + # tuning file + rpiCameraTuningFile: + # sensor mode, in format [width]:[height]:[bit-depth]:[packing] + # bit-depth and packing are optional. + rpiCameraMode: + # frames per second + rpiCameraFPS: 30 + # period between IDR frames + rpiCameraIDRPeriod: 60 + # bitrate + rpiCameraBitrate: 1000000 + # H264 profile + rpiCameraProfile: main + # H264 level + rpiCameraLevel: '4.1' + # Autofocus mode + # values: auto, manual, continuous + rpiCameraAfMode: continuous + # Autofocus range + # values: normal, macro, full + rpiCameraAfRange: normal + # Autofocus speed + # values: normal, fast + rpiCameraAfSpeed: normal + # Lens position (for manual autofocus only), will be set to focus to a specific distance + # calculated by the following formula: d = 1 / value + # Examples: 0 moves the lens to infinity. + # 0.5 moves the lens to focus on objects 2m away. + # 2 moves the lens to focus on objects 50cm away. + rpiCameraLensPosition: 0.0 + # Specifies the autofocus window, in the form x,y,width,height where the coordinates + # are given as a proportion of the entire image. + rpiCameraAfWindow: + # enables printing text on each frame. + rpiCameraTextOverlayEnable: false + # text that is printed on each frame. + # format is the one of the strftime() function. + rpiCameraTextOverlay: '%Y-%m-%d %H:%M:%S - MediaMTX' + + ############################################### + # Default path settings -> Hooks + + # Command to run when this path is initialized. + # This can be used to publish a stream when the server is launched. + # This is terminated with SIGINT when the program closes. + # The following environment variables are available: + # * MTX_PATH: path name + # * RTSP_PORT: RTSP server port + # * G1, G2, ...: regular expression groups, if path name is + # a regular expression. + runOnInit: + # Restart the command if it exits. + runOnInitRestart: no + + # Command to run when this path is requested by a reader + # and no one is publishing to this path yet. + # This can be used to publish a stream on demand. + # This is terminated with SIGINT when there are no readers anymore. + # The following environment variables are available: + # * MTX_PATH: path name + # * MTX_QUERY: query parameters (passed by first reader) + # * RTSP_PORT: RTSP server port + # * G1, G2, ...: regular expression groups, if path name is + # a regular expression. + runOnDemand: + # Restart the command if it exits. + runOnDemandRestart: no + # Readers will be put on hold until the runOnDemand command starts publishing + # or until this amount of time has passed. + runOnDemandStartTimeout: 10s + # The command will be closed when there are no + # readers connected and this amount of time has passed. + runOnDemandCloseAfter: 10s + # Command to run when there are no readers anymore. + # Environment variables are the same of runOnDemand. + runOnUnDemand: + + # Command to run when the stream is ready to be read, whenever it is + # published by a client or pulled from a server / camera. + # This is terminated with SIGINT when the stream is not ready anymore. + # The following environment variables are available: + # * MTX_PATH: path name + # * MTX_QUERY: query parameters (passed by publisher) + # * RTSP_PORT: RTSP server port + # * G1, G2, ...: regular expression groups, if path name is + # a regular expression. + # * MTX_SOURCE_TYPE: source type + # * MTX_SOURCE_ID: source ID + runOnReady: + # Restart the command if it exits. + runOnReadyRestart: no + # Command to run when the stream is not available anymore. + # Environment variables are the same of runOnReady. + runOnNotReady: + + # Command to run when a client starts reading. + # This is terminated with SIGINT when a client stops reading. + # The following environment variables are available: + # * MTX_PATH: path name + # * MTX_QUERY: query parameters (passed by reader) + # * RTSP_PORT: RTSP server port + # * G1, G2, ...: regular expression groups, if path name is + # a regular expression. + # * MTX_READER_TYPE: reader type + # * MTX_READER_ID: reader ID + runOnRead: + # Restart the command if it exits. + runOnReadRestart: no + # Command to run when a client stops reading. + # Environment variables are the same of runOnRead. + runOnUnread: + + # Command to run when a recording segment is created. + # The following environment variables are available: + # * MTX_PATH: path name + # * RTSP_PORT: RTSP server port + # * G1, G2, ...: regular expression groups, if path name is + # a regular expression. + # * MTX_SEGMENT_PATH: segment file path + runOnRecordSegmentCreate: + + # Command to run when a recording segment is complete. + # The following environment variables are available: + # * MTX_PATH: path name + # * RTSP_PORT: RTSP server port + # * G1, G2, ...: regular expression groups, if path name is + # a regular expression. + # * MTX_SEGMENT_PATH: segment file path + runOnRecordSegmentComplete: + +############################################### +# Path settings + +# Settings in "paths" are applied to specific paths, and the map key +# is the name of the path. +# Any setting in "pathDefaults" can be overridden here. +# It's possible to use regular expressions by using a tilde as prefix, +# for example "~^(test1|test2)$" will match both "test1" and "test2", +# for example "~^prefix" will match all paths that start with "prefix". +paths: + live: + record: yes + recordPath: ./recordings/live/%Y-%m-%d_%H-%M-%S-%f + + # Settings under path "all_others" are applied to all paths that + # do not match another entry. + all_others: + diff --git a/docker-compose.yml.dist b/docker-compose.yml.dist new file mode 100644 index 0000000..c73ae3b --- /dev/null +++ b/docker-compose.yml.dist @@ -0,0 +1,104 @@ +version: '3' + +networks: + net: + external: false + +services: + haproxy: + image: haproxy:lts + ports: + - "80:80" + - "443:443" + volumes: + - "./data/certificates:/certificates" + - "./config/haproxy:/usr/local/etc/haproxy" + depends_on: + - "certbot" + - "restreamer" + - "scheduler" + restart: unless-stopped + networks: + - net + labels: + - meta.role=haproxy + + certbot: + image: "certbot/certbot" + hostname: certbot + volumes: + - "./data/certificates:/certificates" + - "./data/certbot/etc:/etc/letsencrypt" + - "./data/certbot/var:/var/lib/letsencrypt" + - "./logs/certbot:/var/log/letsencrypt" + restart: unless-stopped + networks: + - net + labels: + - meta.role=certbot + #entrypoint: sh -c 'while true; do sleep 1; done' + entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 15d & wait $${!}; done;'" + + restreamer: + image: datarhei/restreamer:2.7.0 + environment: + - CORE_LOG_LEVEL=warn + - CORE_API_AUTH_USERNAME=admin + - CORE_API_AUTH_PASSWORD=pass + ports: + - "6000:6000/udp" + volumes: + - "./config/restreamer:/core/config" + - "./data/restreamer:/core/data" + restart: unless-stopped + networks: + - net + labels: + - meta.role=restreamer + + scheduler: + depends_on: + - "restreamer" + build: ./src/scheduler + image: stream-scheduler:latest + environment: + - LOG_LEVEL=info + - CORE_API_HOSTNAME=stream.example.com + - CORE_API_USERNAME=admin + - CORE_API_PASSWORD=pass + restart: unless-stopped + networks: + - net + labels: + - meta.role=scheduler + + recorder: + depends_on: + - "restreamer" + image: bluenviron/mediamtx:latest-ffmpeg + environment: + - MTX_PROTOCOLS=tcp + ports: + - 8554:8554 + volumes: + - "./config/mediamtx/mediamtx.yml:/mediamtx.yml" + - "./data/recordings:/recordings" + restart: unless-stopped + networks: + - net + labels: + - meta.role=recorder + + archive: + depends_on: + - "recorder" + build: ./src/archive + image: stream-archive:latest + volumes: + - "./config/archive/nginx.conf:/etc/nginx/nginx.conf" + - "./data/recordings:/recordings:ro" + restart: unless-stopped + networks: + - net + labels: + - meta.role=archive diff --git a/src/scheduler/app.py b/src/scheduler/app.py index 0aec68a..3e787ef 100644 --- a/src/scheduler/app.py +++ b/src/scheduler/app.py @@ -106,7 +106,7 @@ manager.register_task(name="read_database", job=analyze_db).period(35).start() @app.route('/', methods=['GET']) def root_query(): - playhead = jt + playhead = iway return jsonify(playhead) def create_app():