Added a second device, tracking mediamtx metrics
This commit is contained in:
parent
7be46bcc52
commit
53d4fde672
@ -17,7 +17,7 @@ import CommandsWidget from "./components/dashboard/CommandsWidget.vue";
|
||||
<AppTopbar />
|
||||
<div class="layout-grid">
|
||||
<div class="layout-grid-row">
|
||||
<PropertiesWidget device-id="example-gps-fedora" />
|
||||
<PropertiesWidget device-id="mediamtx-fedora" />
|
||||
<CommandsWidget device-id="example-gps-fedora" />
|
||||
</div>
|
||||
<!-- <StatsWidget /> -->
|
||||
|
||||
@ -20,41 +20,49 @@ function buildNodes(obj, path='') {
|
||||
return Object.entries(obj).map(([key, val]) => {
|
||||
const fullKey = path ? `${path}/${key}` : key
|
||||
|
||||
if (val && typeof val === 'object' && !('value' in val)) {
|
||||
return {
|
||||
key: fullKey,
|
||||
data: { name: key },
|
||||
children: buildNodes(val, fullKey)
|
||||
}
|
||||
}
|
||||
const hasChildren = Object.keys(val).some(k => k !== 'value' && k !== '_value')
|
||||
|
||||
return {
|
||||
key: fullKey,
|
||||
data: {
|
||||
name: key,
|
||||
value: val.value
|
||||
}
|
||||
value: val.value ?? val._value
|
||||
},
|
||||
children: hasChildren ? buildNodes(
|
||||
Object.fromEntries(
|
||||
Object.entries(val).filter(([k]) => k !== 'value' && k !== '_value')
|
||||
),
|
||||
fullKey
|
||||
) : undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function insertProperty(pathParts, value) {
|
||||
let node = propertyTree
|
||||
|
||||
const fullKey = pathParts.join('/')
|
||||
|
||||
pathParts.forEach((part, i) => {
|
||||
if (i === pathParts.length - 1) {
|
||||
node[part] = { value }
|
||||
const isLeaf = i === pathParts.length - 1
|
||||
|
||||
if (!node[part]) {
|
||||
node[part] = {}
|
||||
}
|
||||
|
||||
// If this node used to be a leaf, convert it into a branch
|
||||
if (node[part].value !== undefined && !isLeaf) {
|
||||
node[part] = { _value: node[part].value }
|
||||
}
|
||||
|
||||
if (isLeaf) {
|
||||
node[part].value = value
|
||||
} else {
|
||||
if (!node[part]) node[part] = {}
|
||||
node = node[part]
|
||||
}
|
||||
})
|
||||
|
||||
// 🔥 always flash on update
|
||||
// flash logic
|
||||
changedKeys.value[fullKey] = true
|
||||
|
||||
setTimeout(() => {
|
||||
delete changedKeys.value[fullKey]
|
||||
}, 600)
|
||||
@ -62,10 +70,6 @@ function insertProperty(pathParts, value) {
|
||||
nodes.value = buildNodes(propertyTree)
|
||||
}
|
||||
|
||||
function rowClass(node) {
|
||||
return changedKeys.value.has(node.key) ? 'flash-row' : ''
|
||||
}
|
||||
|
||||
watch(() => props.deviceId, () => {
|
||||
propertyTree = {}
|
||||
nodes.value = []
|
||||
|
||||
26
docker-compose.yaml
Normal file
26
docker-compose.yaml
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
services:
|
||||
emqx:
|
||||
container_name: emqx
|
||||
image: emqx/emqx:latest
|
||||
ports:
|
||||
- 1883:1883
|
||||
- 8083:8083
|
||||
- 8084:8084
|
||||
- 8883:8883
|
||||
- 18083:18083
|
||||
|
||||
mediamtx:
|
||||
container_name: mediamtx
|
||||
image: bluenviron/mediamtx:1.17.0-ffmpeg
|
||||
volumes:
|
||||
- ./mediamtx.yml:/mediamtx.yml:z
|
||||
ports:
|
||||
- 8554:8554
|
||||
- 1935:1935
|
||||
- 8888:8888
|
||||
- 8889:8889
|
||||
- 8890:8890/udp
|
||||
- 8189:8189/udp
|
||||
- 9998:9998
|
||||
|
||||
68
mediamtx.py
Executable file
68
mediamtx.py
Executable file
@ -0,0 +1,68 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import socket
|
||||
import signal
|
||||
import asyncio
|
||||
from dataclasses import dataclass
|
||||
import aiohttp
|
||||
|
||||
from mqtthandler.command import command
|
||||
from mqtthandler.handler import MQTTConfig, MQTTHandler, task
|
||||
|
||||
|
||||
@dataclass
|
||||
class MediaMTXConfig:
|
||||
host: str = "http://localhost"
|
||||
metrics_path: str = ":9998/metrics"
|
||||
username: str | None = "admin"
|
||||
password: str | None = "admin"
|
||||
|
||||
|
||||
class MediaMTXHandler(MQTTHandler):
|
||||
def __init__(
|
||||
self,
|
||||
mqtt_config: MQTTConfig,
|
||||
handler_id: str,
|
||||
mediamtx_config: MediaMTXConfig,
|
||||
):
|
||||
super().__init__(mqtt_config, handler_id)
|
||||
self.config = mediamtx_config
|
||||
|
||||
@task
|
||||
async def retrieve_metrics(self):
|
||||
cache = {}
|
||||
|
||||
while True:
|
||||
auth = aiohttp.BasicAuth(login=self.config.username, password=self.config.password)
|
||||
async with aiohttp.ClientSession(auth=auth) as session:
|
||||
while True:
|
||||
async with session.get(f"{self.config.host}{self.config.metrics_path}") as r:
|
||||
metrics = await r.text()
|
||||
|
||||
for line in metrics.split("\n")[:-1]:
|
||||
metric, value = line.split(" ")
|
||||
topic = metric.replace("_", "/")
|
||||
full_topic = f"{self.property_topic}/{topic}"
|
||||
|
||||
if cache.get(full_topic) != value:
|
||||
cache[full_topic] = value
|
||||
await self.mqtt_client.publish(full_topic, value, retain=True)
|
||||
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
print("Connection dropped!")
|
||||
await asyncio.sleep(10)
|
||||
|
||||
|
||||
async def main():
|
||||
handler_id = f"mediamtx-{socket.gethostname()}"
|
||||
mqtt_config = MQTTConfig(host="127.0.0.1")
|
||||
handler = MediaMTXHandler(mqtt_config, handler_id, MediaMTXConfig())
|
||||
|
||||
signal.signal(signal.SIGINT, lambda signum, frame: handler.stop())
|
||||
await handler.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
815
mediamtx.yml
Normal file
815
mediamtx.yml
Normal file
@ -0,0 +1,815 @@
|
||||
###############################################
|
||||
# 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]
|
||||
# When destination is "stdout" or "file", emit logs in structured format (JSONL).
|
||||
logStructured: false
|
||||
# When "file" is in logDestinations, this is the file which will receive logs.
|
||||
logFile: mediamtx.log
|
||||
# When "syslog" is in logDestinations, use prefix for logs.
|
||||
sysLogPrefix: mediamtx
|
||||
# Dump packets to disk. This is useful for debugging.
|
||||
dumpPackets: false
|
||||
|
||||
# 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 payloads.
|
||||
# It defaults to the maximum packet size on ethernet (1500) minus IPv6 and UDP headers (48).
|
||||
# This can be decreased to avoid fragmentation on networks with a low MTU.
|
||||
udpMaxPayloadSize: 1452
|
||||
# Size of the read buffer of every UDP socket.
|
||||
# This can be increased to decrease packet losses.
|
||||
# It defaults to the default value of the operating system.
|
||||
udpReadBufferSize: 0
|
||||
|
||||
# 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:
|
||||
# * MTX_CONN_TYPE: connection type
|
||||
# * MTX_CONN_ID: connection ID
|
||||
# * RTSP_PORT: RTSP server port
|
||||
runOnConnect:
|
||||
# Restart the command if it exits.
|
||||
runOnConnectRestart: false
|
||||
# Command to run when a client disconnects from the server.
|
||||
# Environment variables are the same of runOnConnect.
|
||||
runOnDisconnect:
|
||||
|
||||
###############################################
|
||||
# Global settings -> Authentication
|
||||
|
||||
# Authentication method. Available values are:
|
||||
# * internal: credentials are stored in the configuration file
|
||||
# * http: an external HTTP URL is contacted to perform authentication
|
||||
# * jwt: an external identity server provides authentication through JWTs
|
||||
authMethod: internal
|
||||
|
||||
# Internal authentication.
|
||||
# Enabled users.
|
||||
authInternalUsers:
|
||||
# Default unprivileged user.
|
||||
# Username. 'any' means any user, including anonymous ones.
|
||||
- user: any
|
||||
# Password. Not used in case of 'any' user.
|
||||
pass:
|
||||
# IPs or networks allowed to use this user. An empty list means any IP.
|
||||
ips: []
|
||||
# Permissions.
|
||||
permissions:
|
||||
# Available actions are: publish, read, playback, api, metrics, pprof.
|
||||
- action: publish
|
||||
# Paths can be set to further restrict access to a specific path.
|
||||
# An empty path means any path.
|
||||
# Regular expressions can be used by using a tilde as prefix.
|
||||
path:
|
||||
- action: read
|
||||
path:
|
||||
- action: playback
|
||||
path:
|
||||
|
||||
# Default administrator.
|
||||
# This allows to use API, metrics and PPROF without authentication,
|
||||
# if the IP is localhost.
|
||||
- user: any
|
||||
pass:
|
||||
ips: ['127.0.0.1', '::1', '192.168.0.0/24']
|
||||
permissions:
|
||||
- action: api
|
||||
- action: metrics
|
||||
- action: pprof
|
||||
|
||||
- user: admin
|
||||
pass: admin
|
||||
ips: ['0.0.0.0/0']
|
||||
permissions:
|
||||
- action: api
|
||||
- action: metrics
|
||||
- action: pprof
|
||||
|
||||
|
||||
# HTTP-based authentication.
|
||||
# URL called to perform authentication. Every time a user wants
|
||||
# to authenticate, the server calls this URL with the POST method
|
||||
# and a body containing:
|
||||
# {
|
||||
# "user": "user",
|
||||
# "password": "password",
|
||||
# "token": "token",
|
||||
# "ip": "ip",
|
||||
# "action": "publish|read|playback|api|metrics|pprof",
|
||||
# "path": "path",
|
||||
# "protocol": "rtsp|rtmp|hls|webrtc|srt",
|
||||
# "id": "id",
|
||||
# "query": "query"
|
||||
# }
|
||||
# If the response code is 20x, authentication is accepted, otherwise
|
||||
# it is discarded.
|
||||
authHTTPAddress:
|
||||
# If the HTTP authentication URL has a self-signed or invalid certificate,
|
||||
# you can provide the fingerprint of the certificate in order to
|
||||
# validate it anyway. It can be obtained by running:
|
||||
# openssl s_client -connect auth_http_domain:443 </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
|
||||
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
|
||||
authHTTPFingerprint:
|
||||
# Actions to exclude from HTTP-based authentication.
|
||||
# Format is the same as the one of user permissions.
|
||||
authHTTPExclude:
|
||||
- action: api
|
||||
- action: metrics
|
||||
- action: pprof
|
||||
|
||||
# JWT-based authentication.
|
||||
# Users have to login through an external identity server and obtain a JWT.
|
||||
# This JWT must contain the claim "mediamtx_permissions" with permissions,
|
||||
# for instance:
|
||||
# {
|
||||
# "mediamtx_permissions": [
|
||||
# {
|
||||
# "action": "publish",
|
||||
# "path": "somepath"
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
# Users are expected to pass the JWT in the Authorization header or as password.
|
||||
# This is the JWKS URL that will be used to pull (once) the public key that allows
|
||||
# to validate JWTs.
|
||||
authJWTJWKS:
|
||||
# If the JWKS URL has a self-signed or invalid certificate,
|
||||
# you can provide the fingerprint of the certificate in order to
|
||||
# validate it anyway. It can be obtained by running:
|
||||
# openssl s_client -connect jwt_jwks_domain:443 </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
|
||||
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
|
||||
authJWTJWKSFingerprint:
|
||||
# name of the claim that contains permissions.
|
||||
authJWTClaimKey: mediamtx_permissions
|
||||
# Actions to exclude from JWT-based authentication.
|
||||
# Format is the same as the one of user permissions.
|
||||
authJWTExclude: []
|
||||
# Allow passing the JWT through query parameters of HTTP requests (i.e. ?jwt=JWT).
|
||||
# This is a security risk and will be disabled in the future.
|
||||
# RTSP and RTMP always allow JWT in query even if disabled, since there is no alternative.
|
||||
authJWTInHTTPQuery: true
|
||||
# Expected issuer (iss) claim in the JWT. Leave empty to skip validation.
|
||||
authJWTIssuer:
|
||||
# Expected audience (aud) claim in the JWT. Leave empty to skip validation.
|
||||
authJWTAudience:
|
||||
|
||||
###############################################
|
||||
# Global settings -> Control API
|
||||
|
||||
# Enable controlling the server through the Control API.
|
||||
api: false
|
||||
# Address of the Control API listener.
|
||||
apiAddress: :9997
|
||||
# Enable HTTPS on the Control API server.
|
||||
apiEncryption: false
|
||||
# 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
|
||||
apiServerKey: server.key
|
||||
# Path to the server certificate.
|
||||
apiServerCert: server.crt
|
||||
# Allowed CORS origins.
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
apiAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
apiTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
# Global settings -> Metrics
|
||||
|
||||
# Enable Prometheus-compatible metrics.
|
||||
metrics: true
|
||||
# Address of the metrics HTTP listener.
|
||||
metricsAddress: :9998
|
||||
# Enable HTTPS on the Metrics server.
|
||||
metricsEncryption: false
|
||||
# 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
|
||||
metricsServerKey: server.key
|
||||
# Path to the server certificate.
|
||||
metricsServerCert: server.crt
|
||||
# Allowed CORS origins.
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
metricsAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
metricsTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
# Global settings -> PPROF
|
||||
|
||||
# Enable pprof-compatible endpoint to monitor performances.
|
||||
pprof: false
|
||||
# Address of the pprof listener.
|
||||
pprofAddress: :9999
|
||||
# Enable HTTPS on the pprof server.
|
||||
pprofEncryption: false
|
||||
# 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
|
||||
pprofServerKey: server.key
|
||||
# Path to the server certificate.
|
||||
pprofServerCert: server.crt
|
||||
# Allowed CORS origins.
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
pprofAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
pprofTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
# Global settings -> Playback server
|
||||
|
||||
# Enable downloading recordings from the playback server.
|
||||
playback: false
|
||||
# Address of the playback server listener.
|
||||
playbackAddress: :9996
|
||||
# Enable HTTPS on the playback server.
|
||||
playbackEncryption: false
|
||||
# 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
|
||||
playbackServerKey: server.key
|
||||
# Path to the server certificate.
|
||||
playbackServerCert: server.crt
|
||||
# Allowed CORS origins.
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
playbackAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
playbackTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
# Global settings -> RTSP server
|
||||
|
||||
# Enable publishing and reading streams with the RTSP protocol.
|
||||
rtsp: true
|
||||
# Enabled RTSP transport protocols. The handshake is always performed with TCP.
|
||||
rtspTransports: [udp, multicast, tcp]
|
||||
# Use secure protocol variants (RTSPS, SRTP, SRTCP).
|
||||
# Available values are "no", "strict", "optional".
|
||||
rtspEncryption: "no"
|
||||
# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional".
|
||||
rtspAddress: :8554
|
||||
# Address of the TCP/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 rtspTransports and encryption is "no" or "optional".
|
||||
rtpAddress: :8000
|
||||
# Address of the UDP/RTCP listener. This is needed only when "udp" is in rtspTransports and encryption is "no" or "optional".
|
||||
rtcpAddress: :8001
|
||||
# IP range of all UDP-multicast listeners. This is needed only when "multicast" is in rtspTransports and encryption is "no" or "optional".
|
||||
multicastIPRange: 224.1.0.0/16
|
||||
# Port of all UDP-multicast/RTP listeners. This is needed only when "multicast" is in rtspTransports and encryption is "no" or "optional".
|
||||
multicastRTPPort: 8002
|
||||
# Port of all UDP-multicast/RTCP listeners. This is needed only when "multicast" is in rtspTransports and encryption is "no" or "optional".
|
||||
multicastRTCPPort: 8003
|
||||
# Address of the UDP/SRTP listener. This is needed only when "udp" is in rtspTransports and encryption is "strict" or "optional".
|
||||
srtpAddress: :8004
|
||||
# Address of the UDP/SRTCP listener. This is needed only when "udp" is in rtspTransports and encryption is "strict" or "optional".
|
||||
srtcpAddress: :8005
|
||||
# Port of all UDP-multicast/SRTP listeners. This is needed only when "multicast" is in rtspTransports and encryption is "strict" or "optional".
|
||||
multicastSRTPPort: 8006
|
||||
# Port of all UDP-multicast/SRTCP listeners. This is needed only when "multicast" is in rtspTransports and encryption is "strict" or "optional".
|
||||
multicastSRTCPPort: 8007
|
||||
# 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
|
||||
rtspServerKey: server.key
|
||||
# Path to the server certificate. This is needed only when encryption is "strict" or "optional".
|
||||
rtspServerCert: server.crt
|
||||
# Authentication methods. Available are "basic" and "digest".
|
||||
# "digest" doesn't provide any additional security and is available for compatibility only.
|
||||
rtspAuthMethods: [basic]
|
||||
|
||||
###############################################
|
||||
# Global settings -> RTMP server
|
||||
|
||||
# Enable publishing and reading streams with the RTMP protocol.
|
||||
rtmp: true
|
||||
# Use the secure protocol variant (RTMP).
|
||||
# Available values are "no", "strict", "optional".
|
||||
rtmpEncryption: "no"
|
||||
# Address of the RTMP listener. This is needed only when encryption is "no" or "optional".
|
||||
rtmpAddress: :1935
|
||||
# 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
|
||||
|
||||
# Enable reading streams with the HLS protocol.
|
||||
hls: true
|
||||
# Address of the HLS listener.
|
||||
hlsAddress: :8888
|
||||
# Enable HTTPS on the HLS server.
|
||||
# This is required for Low-Latency HLS to function correctly on Apple devices.
|
||||
hlsEncryption: false
|
||||
# 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
|
||||
# Allowed CORS origins.
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
hlsAllowOrigins: ['*']
|
||||
# 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: []
|
||||
# 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: false
|
||||
# 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
|
||||
# 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: ''
|
||||
# The muxer will be closed when there are no
|
||||
# reader requests and this amount of time has passed.
|
||||
hlsMuxerCloseAfter: 60s
|
||||
|
||||
###############################################
|
||||
# Global settings -> WebRTC server
|
||||
|
||||
# Enable publishing and reading streams with the WebRTC protocol.
|
||||
webrtc: true
|
||||
# Address of the WebRTC HTTP listener.
|
||||
webrtcAddress: :8889
|
||||
# Enable HTTPS on the WebRTC server.
|
||||
# This covers only the WebRTC handshake and does not influence the encryption of WebRTC streams
|
||||
# which are always encrypted, with a key that is exchanged during the WebRTC handshake.
|
||||
webrtcEncryption: false
|
||||
# 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
|
||||
# Allowed CORS origins.
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
webrtcAllowOrigins: ['*']
|
||||
# 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: true
|
||||
# Interfaces whose IPs will be sent to clients.
|
||||
# An empty value means to use all available interfaces.
|
||||
webrtcIPsFromInterfacesList: []
|
||||
# Additional hosts or IPs to send to clients.
|
||||
webrtcAdditionalHosts: []
|
||||
# ICE servers. Needed only when local listeners can't be reached by clients.
|
||||
# STUN servers allow to obtain and share the public IP of the server.
|
||||
# TURN/TURNS servers force 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: ''
|
||||
# clientOnly: false
|
||||
# Maximum time to gather STUN candidates.
|
||||
webrtcSTUNGatherTimeout: 5s
|
||||
# Time to wait for the WebRTC handshake to complete.
|
||||
webrtcHandshakeTimeout: 10s
|
||||
# Maximum time to gather tracks.
|
||||
webrtcTrackGatherTimeout: 2s
|
||||
|
||||
###############################################
|
||||
# Global settings -> SRT server
|
||||
|
||||
# Enable publishing and reading streams with the SRT protocol.
|
||||
srt: true
|
||||
# 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
|
||||
# * rtsp+http://existing-url -> the stream is pulled from another RTSP server / camera, with HTTP tunneling
|
||||
# * rtsps+http://existing-url -> the stream is pulled from another RTSP server / camera, with HTTPS tunneling
|
||||
# * rtsp+ws://existing-url -> the stream is pulled from another RTSP server / camera, with WebSocket tunneling
|
||||
# * rtsps+ws://existing-url -> the stream is pulled from another RTSP server / camera, with secure WebSocket tunneling
|
||||
# * 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+mpegts://ip:port -> the stream is pulled from MPEG-TS over UDP, by listening on the specified address
|
||||
# * unix+mpegts://socket -> the stream is pulled from MPEG-TS over Unix socket, by using the socket
|
||||
# * udp+rtp://ip:port -> the stream is pulled from RTP over UDP, by listening on the specified address
|
||||
# * srt://existing-url -> the stream is pulled from another SRT server / camera
|
||||
# * whep://existing-url -> the stream is pulled from another WebRTC server / camera with HTTP+WHEP
|
||||
# * wheps://existing-url -> the stream is pulled from another WebRTC server / camera with HTTPS+WHEP
|
||||
# * redirect -> the stream is provided by another path or server
|
||||
# * rpiCamera -> the stream is provided by a Raspberry Pi Camera
|
||||
# The following variables can be used in the source string:
|
||||
# * $MTX_QUERY: query parameters (passed by first reader)
|
||||
# * $G1, $G2, ...: regular expression groups, if path name is
|
||||
# a regular expression.
|
||||
source: publisher
|
||||
# If the source is a URL, and the source TLS 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 2>/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: false
|
||||
# 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 required to read from this path.
|
||||
srtReadPassphrase:
|
||||
# Use absolute timestamp of frames, instead of replacing them with the current time.
|
||||
useAbsoluteTimestamp: false
|
||||
|
||||
###############################################
|
||||
# Default path settings -> Always available
|
||||
|
||||
# Enable always-available mode, in which a offline segment is played on repeat when the stream is not available.
|
||||
alwaysAvailable: false
|
||||
# Tracks of the default offline segment.
|
||||
alwaysAvailableTracks: []
|
||||
# Available values are: AV1, VP9, H265, H264, Opus, MPEG4Audio, G711, LPCM
|
||||
# - codec: H264
|
||||
# # in case of MPEG4Audio, G711, LPCM, sampleRate and ChannelCount must be provided too.
|
||||
# sampleRate: 48000
|
||||
# channelCount: 2
|
||||
# # in case of G711, muLaw must be provided too.
|
||||
# muLaw: false
|
||||
# A MP4 file can be used instead of the default offline segment.
|
||||
alwaysAvailableFile: ''
|
||||
|
||||
###############################################
|
||||
# Default path settings -> Record
|
||||
|
||||
# Record streams to disk.
|
||||
record: false
|
||||
# Path of recording segments.
|
||||
# Extension is added automatically.
|
||||
# Available variables are %path (path name), %Y %m %d (year, month, day),
|
||||
# %H %M %S (hours, minutes, seconds), %f (microseconds), %z (time zone), %s (unix epoch).
|
||||
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: 1s
|
||||
# This prevents RAM exhaustion.
|
||||
recordMaxPartSize: 50M
|
||||
# Minimum duration of each segment.
|
||||
recordSegmentDuration: 1h
|
||||
# Delete segments after this timespan.
|
||||
# Set to 0s to disable automatic deletion.
|
||||
recordDeleteAfter: 1d
|
||||
|
||||
###############################################
|
||||
# Default path settings -> Publisher source (when source is "publisher")
|
||||
|
||||
# Allow another client to disconnect the current publisher and publish in its place.
|
||||
overridePublisher: true
|
||||
# SRT encryption passphrase required to publish to this path.
|
||||
srtPublishPassphrase:
|
||||
# Demux MPEG-TS over RTSP into elementary streams.
|
||||
# When enabled, RTSP publishers sending MP2T/90000 will be demultiplexed
|
||||
# and their elementary streams (H.264, H.265, AAC, etc.) exposed as native tracks.
|
||||
# This allows HLS, WebRTC, and other outputs to work transparently with MPEG-TS sources.
|
||||
rtspDemuxMpegts: false
|
||||
|
||||
###############################################
|
||||
# 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: false
|
||||
# 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:
|
||||
# Range of ports used as source port in outgoing UDP packets.
|
||||
rtspUDPSourcePortRange: [10000, 65535]
|
||||
|
||||
###############################################
|
||||
# Default path settings -> RTP source (when source is RTP)
|
||||
|
||||
# session description protocol (SDP) of the RTP stream.
|
||||
rtpSDP:
|
||||
|
||||
###############################################
|
||||
# Default path settings -> WebRTC / WHEP source (when source is WHEP)
|
||||
|
||||
# Token to insert in the Authorization: Bearer header.
|
||||
whepBearerToken: ''
|
||||
# Maximum time to gather STUN candidates.
|
||||
whepSTUNGatherTimeout: 5s
|
||||
# Time to wait for the WebRTC handshake to complete.
|
||||
whepHandshakeTimeout: 10s
|
||||
# Maximum time to gather tracks.
|
||||
whepTrackGatherTimeout: 2s
|
||||
|
||||
###############################################
|
||||
# Default path settings -> Redirect source (when source is "redirect")
|
||||
|
||||
# path which clients will be redirected to.
|
||||
# It can be can be a relative path (i.e. /otherstream) or an absolute RTSP URL.
|
||||
sourceRedirect:
|
||||
|
||||
###############################################
|
||||
# Default path settings -> Raspberry Pi Camera source (when source is "rpiCamera")
|
||||
|
||||
# ID of the camera.
|
||||
rpiCameraCamID: 0
|
||||
# Whether this is a secondary stream.
|
||||
rpiCameraSecondary: false
|
||||
# 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.
|
||||
# (auto, incandescent, tungsten, fluorescent, indoor, daylight, cloudy or custom).
|
||||
rpiCameraAWB: auto
|
||||
# Auto-white-balance fixed gains. This can be used in place of rpiCameraAWB.
|
||||
# format: [red,blue].
|
||||
rpiCameraAWBGains: [0, 0]
|
||||
# Denoise operating mode (off, cdn_off, cdn_fast, cdn_hq).
|
||||
rpiCameraDenoise: "off"
|
||||
# Fixed shutter speed, in microseconds.
|
||||
rpiCameraShutter: 0
|
||||
# Metering mode of the AEC/AGC algorithm (centre, spot, matrix or custom).
|
||||
rpiCameraMetering: centre
|
||||
# Fixed gain.
|
||||
rpiCameraGain: 0
|
||||
# EV compensation of the image in range [-10, 10].
|
||||
rpiCameraEV: 0
|
||||
# Region of interest, in format x,y,width,height (all normalized between 0 and 1).
|
||||
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
|
||||
# Autofocus mode (auto, manual or continuous).
|
||||
rpiCameraAfMode: continuous
|
||||
# Autofocus range (normal, macro or full).
|
||||
rpiCameraAfRange: normal
|
||||
# Autofocus speed (normal or 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
|
||||
# Autofocus window, in the form x,y,width,height where the coordinates
|
||||
# are given as a proportion of the entire image.
|
||||
rpiCameraAfWindow:
|
||||
# Manual flicker correction period, in microseconds.
|
||||
rpiCameraFlickerPeriod: 0
|
||||
# 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'
|
||||
# Codec (auto, hardwareH264, softwareH264 or mjpeg).
|
||||
# When is "auto" and stream is primary, it defaults to hardwareH264 (if available) or softwareH264.
|
||||
# When is "auto" and stream is secondary, it defaults to mjpeg.
|
||||
rpiCameraCodec: auto
|
||||
# Period between IDR frames (when codec is hardwareH264 or softwareH264).
|
||||
rpiCameraIDRPeriod: 60
|
||||
# Bitrate (when codec is hardwareH264 or softwareH264).
|
||||
rpiCameraBitrate: 5000000
|
||||
# Hardware H264 profile (baseline, main or high) (when codec is hardwareH264).
|
||||
rpiCameraHardwareH264Profile: main
|
||||
# Hardware H264 level (4.0, 4.1 or 4.2) (when codec is hardwareH264).
|
||||
rpiCameraHardwareH264Level: '4.1'
|
||||
# Software H264 profile (baseline, main or high) (when codec is softwareH264).
|
||||
rpiCameraSoftwareH264Profile: baseline
|
||||
# Software H264 level (4.0, 4.1 or 4.2) (when codec is softwareH264).
|
||||
rpiCameraSoftwareH264Level: '4.1'
|
||||
# M-JPEG JPEG quality (when codec is mjpeg).
|
||||
rpiCameraMJPEGQuality: 60
|
||||
|
||||
###############################################
|
||||
# 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: false
|
||||
|
||||
# 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: false
|
||||
# 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)
|
||||
# * MTX_SOURCE_TYPE: source type
|
||||
# * MTX_SOURCE_ID: source ID
|
||||
# * RTSP_PORT: RTSP server port
|
||||
# * G1, G2, ...: regular expression groups, if path name is
|
||||
# a regular expression.
|
||||
runOnReady:
|
||||
# Restart the command if it exits.
|
||||
runOnReadyRestart: false
|
||||
# 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)
|
||||
# * MTX_READER_TYPE: reader type
|
||||
# * MTX_READER_ID: reader ID
|
||||
# * RTSP_PORT: RTSP server port
|
||||
# * G1, G2, ...: regular expression groups, if path name is
|
||||
# a regular expression.
|
||||
runOnRead:
|
||||
# Restart the command if it exits.
|
||||
runOnReadRestart: false
|
||||
# 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
|
||||
# * MTX_SEGMENT_PATH: segment file path
|
||||
# * RTSP_PORT: RTSP server port
|
||||
# * G1, G2, ...: regular expression groups, if path name is
|
||||
# a regular expression.
|
||||
runOnRecordSegmentCreate:
|
||||
|
||||
# Command to run when a recording segment is complete.
|
||||
# The following environment variables are available:
|
||||
# * MTX_PATH: path name
|
||||
# * MTX_SEGMENT_PATH: segment file path
|
||||
# * MTX_SEGMENT_DURATION: segment duration
|
||||
# * RTSP_PORT: RTSP server port
|
||||
# * G1, G2, ...: regular expression groups, if path name is
|
||||
# a regular expression.
|
||||
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:
|
||||
# example:
|
||||
# my_camera:
|
||||
# source: rtsp://my_camera
|
||||
|
||||
# Settings under path "all_others" are applied to all paths that
|
||||
# do not match another entry.
|
||||
all_others:
|
||||
@ -4,3 +4,5 @@ black
|
||||
pyubx2
|
||||
pyubxutils
|
||||
jsonschema
|
||||
aiohttp
|
||||
aiodns
|
||||
|
||||
Loading…
Reference in New Issue
Block a user