Add mediamtx vm.

This commit is contained in:
Tom Alexander 2024-07-06 14:43:37 -04:00
parent a9d687448d
commit 5fe48c2587
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
7 changed files with 1123 additions and 16 deletions

View File

@ -1,11 +1,179 @@
#!/usr/bin/env bash
#
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ffmpeg -re -vaapi_device /dev/dri/renderD128 -i "$1" -vf 'format=nv12,hwupload' -c:v h264_vaapi -r 30 -g 30 -loop -1 -c:a aac -b:a 160k -ar 44100 -strict -2 -f flv rtmp:172.16.16.44/live/test &
ffmpegpid=$!
sleep 1
castnow --exit 'https://broadcast.fizz.buzz/hls/hls/test.m3u8'
wait "$ffmpegpid"
sleep 10
function main {
local cmd
cmd=$1
shift
if [ "$cmd" = "copy" ]; then
copy "${@}"
elif [ "$cmd" = "h264" ]; then
h264 "${@}"
elif [ "$cmd" = "software_h264" ]; then
software_h264 "${@}"
elif [ "$cmd" = "preprocess_h264" ]; then
preprocess_h264 "${@}"
elif [ "$cmd" = "preprocess_vp8" ]; then
preprocess_vp8 "${@}"
elif [ "$cmd" = "webcam" ]; then
webcam "${@}"
elif [ "$cmd" = "encode_webcam" ]; then
encode_webcam "${@}"
else
(>&2 echo "Unknown command: $cmd")
exit 1
fi
}
function copy {
local file_to_cast
file_to_cast="$3"
local USERNAME PASSWORD
USERNAME="$1"
PASSWORD="$2"
exec ffmpeg \
-re \
-stream_loop -1 \
-i "$file_to_cast" \
-c copy \
-f rtsp \
-rtsp_transport udp \
"rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch"
}
function h264 {
local file_to_cast
file_to_cast="$3"
local USERNAME PASSWORD
USERNAME="$1"
PASSWORD="$2"
# -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames.
exec ffmpeg \
-re \
-stream_loop -1 \
-init_hw_device vaapi=foo:/dev/dri/renderD128 \
-hwaccel vaapi \
-hwaccel_output_format vaapi \
-hwaccel_device foo \
-i "$file_to_cast" \
-filter_hw_device foo \
-vf 'format=nv12|vaapi,hwupload' \
-c:v h264_vaapi \
-bf 0 \
-c:a aac \
-b:a 160k \
-ar 44100 \
-f rtsp \
-rtsp_transport udp \
"rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch"
}
function software_h264 {
local file_to_cast
file_to_cast="$3"
local USERNAME PASSWORD
USERNAME="$1"
PASSWORD="$2"
# -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames.
exec ffmpeg \
-re \
-stream_loop -1 \
-i "$file_to_cast" \
-c:v h264 \
-bf 0 \
-c:a aac \
-b:a 160k \
-ar 44100 \
-f rtsp \
-rtsp_transport udp \
"rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch"
}
function preprocess_h264 {
local file_to_cast file_to_save
file_to_cast="$1"
file_to_save="$2"
# -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames.
exec ffmpeg \
-i "$file_to_cast" \
-c:v h264 \
-bf 0 \
-c:a aac \
-b:a 160k \
-ar 44100 \
"$file_to_save"
}
function preprocess_vp8 {
local file_to_cast file_to_save
file_to_cast="$1"
file_to_save="$2"
# -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames.
# -strict -2 :: Enable support for experimental codecs like opus.
# -b:v 1M :: Target 1 megabit/s
# -crf 10 :: Target a quality level and adjust bitrate accordingly. This should be preferred, but ideally both should be used.
exec ffmpeg \
-i "$file_to_cast" \
-c:v vp8 \
-b:v 1M \
-crf 10 \
-bf 0 \
-c:a opus \
-b:a 320k \
-ar 48000 \
-strict -2 \
"$file_to_save"
}
function webcam {
# Uses on-webcam h264 encoding.
local USERNAME PASSWORD
USERNAME="$1"
PASSWORD="$2"
exec ffmpeg \
-re \
-input_format h264 \
-video_size 1920x1080 \
-i /dev/video0 \
-c:v copy \
-an \
-f rtsp \
-rtsp_transport udp \
"rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch"
}
function encode_webcam {
# Uses hardware accelerated gpu-based encoding.
local USERNAME PASSWORD
USERNAME="$1"
PASSWORD="$2"
exec ffmpeg \
-re \
-vaapi_device /dev/dri/renderD128 \
-i /dev/video0 \
-vf 'format=nv12,hwupload' \
-c:v h264_vaapi \
-an \
-f rtsp \
-rtsp_transport udp \
"rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch"
}
main "${@}"

14
router/k8s-stream.yaml Normal file
View File

@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: stream-cert
namespace: default
spec:
dnsNames:
- "home.fizz.buzz"
- "stream.fizz.buzz"
secretName: stream-cert
issuerRef:
name: letsencrypt-prd
kind: ClusterIssuer
group: cert-manager.io

151
router/launch_mediamtx.bash Normal file
View File

@ -0,0 +1,151 @@
#!/usr/local/bin/bash
#
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
: ${CD:=""}
: ${VNC_ENABLE:="NO"}
: ${VNC_LISTEN:="127.0.0.1:5900"}
: ${PID_FILE:="/var/run/mediamtx.pid"}
############## Setup #########################
function cleanup {
for vm in "${vms[@]}"; do
log "Destroying bhyve vm $vm"
bhyvectl "--vm=$vm" --destroy
log "Destroyed bhyve vm $vm"
done
}
vms=()
for sig in EXIT INT QUIT HUP TERM; do
trap "set +e; sleep 10; cleanup" "$sig"
done
function die {
local status_code="$1"
shift
(>&2 echo "${@}")
exit "$status_code"
}
function log {
(>&2 echo "${@}")
}
############## Program #########################
function main {
start_vm
}
function start_vm {
local name="mediamtx"
# -H release the CPU when guest issues HLT instruction. Otherwise 100% of core will be consumed.
# -s 3,ahci-cd,/vm/.iso/archlinux-2023.04.01-x86_64.iso \
# -s 29,fbuf,tcp=0.0.0.0:5900,w=1920,h=1080,wait \
# -s 29,fbuf,tcp=0.0.0.0:5900,w=1920,h=1080 \
# TODO: Look into using nmdm instead of stdio for serial console
if [ -n "$CD" ]; then
additional_args+=("-s" "5,ahci-cd,$CD")
fi
if [ "$VNC_ENABLE" = "YES" ]; then
additional_args+=("-s" "29,fbuf,tcp=$VNC_LISTEN,w=1920,h=1080")
fi
local bridge_name="bridge_vm"
wait_for_bridge "$bridge_name"
local mac_address
mac_address=$(calculate_mac_address "$name")
local bridge_link_name
bridge_link_name=$(detect_available_link "${bridge_name}")
# additional_args+=("-s" "2:0,virtio-net,netgraph,path=${bridge_name}:,peerhook=${bridge_link_name},mac=${mac_address}")
additional_args+=("-s" "2:0,virtio-net,netgraph,path=${bridge_name}:,peerhook=${bridge_link_name},mac=${mac_address}" "-s" "3,ahci-cd,/home/talexander/disk.iso")
vms+=("$name")
while true; do
set -x
set +e
bhyve \
-D \
-c 1 \
-m 3G \
-H \
-o 'rtc.use_localtime=false' \
-s 0,hostbridge \
-s "4,nvme,/dev/zvol/zroot/vm/mediamtx/disk0" \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l "bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd,/vm/mediamtx/BHYVE_UEFI_VARS.fd" \
"${additional_args[@]}" \
"$name"
# local bhyvepid=$!
# echo "$bhyvepid" > "$PID_FILE"
# wait $bhyvepid
local exit_code=$?
set +x
set -e
if [ $exit_code -eq 0 ]; then
echo "Rebooting."
sleep 5
elif [ $exit_code -eq 1 ]; then
echo "Powered off."
break
elif [ $exit_code -eq 2 ]; then
echo "Halted."
break
elif [ $exit_code -eq 3 ]; then
echo "Triple fault."
break
elif [ $exit_code -eq 4 ]; then
echo "Exited due to an error."
break
fi
done
}
function ng_exists {
ngctl status "${1}" >/dev/null 2>&1
}
function wait_for_bridge {
local bridge_name="$1"
while ! ng_exists "${bridge_name}:"; do
echo "${bridge_name} does not yet exist, sleeping."
sleep 10
done
}
function detect_available_link {
local bridge_name="$1"
local linknum=1
while true; do
local link_name="link${linknum}"
if ! ng_exists "${bridge_name}:${link_name}"; then
echo "$link_name"
return
fi
linknum=$((linknum + 1))
if [ "$linknum" -gt 90 ]; then
(>&2 echo "No available links on bridge $bridge_name")
exit 1
fi
done
}
function calculate_mac_address {
local name="$1"
local source
source=$(md5 -r -s "$name" | awk '{print $1}')
echo "06:${source:0:2}:${source:2:2}:${source:4:2}:${source:6:2}:${source:8:2}"
}
main "${@}"

View File

@ -73,7 +73,7 @@ function start_vm {
set +e
bhyve \
-D \
-c 6 \
-c 4 \
-m 8G \
-H \
-o 'rtc.use_localtime=false' \

47
router/mediamtx_rc.bash Normal file
View File

@ -0,0 +1,47 @@
#!/bin/sh
#
# REQUIRE: FILESYSTEMS kld
# PROVIDE: mediamtx
# BEFORE: netif
. /etc/rc.subr
name=mediamtx
rcvar=${name}_enable
start_cmd="${name}_start"
stop_cmd="${name}_stop"
status_cmd="${name}_status"
load_rc_config $name
tmux_name="mediamtx"
mediamtx_start() {
/usr/local/bin/tmux new-session -d -s "$tmux_name" "/usr/bin/env VNC_ENABLE=YES VNC_LISTEN=0.0.0.0:5900 /usr/local/bin/bash /home/talexander/launch_mediamtx.bash"
# /usr/local/bin/tmux new-session -d -s "$tmux_name" "/usr/bin/env VNC_ENABLE=NO VNC_LISTEN=0.0.0.0:5900 /usr/local/bin/bash /home/talexander/launch_mediamtx.bash"
}
mediamtx_status() {
if /usr/local/bin/tmux has-session -t $tmux_name 2>/dev/null; then
echo "$tmux_name is running."
else
echo "$tmux_name is not running."
return 1
fi
}
mediamtx_stop() {
/usr/local/bin/tmux has-session -t $tmux_name 2>/dev/null && (
/usr/local/bin/tmux kill-session -t $tmux_name
sleep 10
bhyvectl --vm=mediamtx --destroy
# kill `cat /var/run/mediamtx.pid`
)
mediamtx_wait_for_end
}
mediamtx_wait_for_end() {
while /usr/local/bin/tmux has-session -t $tmux_name 2>dev/null; do
sleep 1
done
}
run_rc_command "$1"

727
router/stream.yml Normal file
View File

@ -0,0 +1,727 @@
#
# How to update cert:
#
# kubectl apply -f k8s-stream.yaml
# kubectl wait --for=condition=ready=true --timeout=300s -n default certificate stream-cert
# decrypt_k8s_secret -n default stream-cert | jq -r '.["tls.crt"]' | tee server.crt
# decrypt_k8s_secret -n default stream-cert | jq -r '.["tls.key"]' | tee server.key
# kdel -f k8s-stream.yaml
# gpg_auth scp stream.yml server.crt server.key 172.16.16.251:~/ ; gpg_auth ssh 172.16.16.251 doas install -o root -g root -m 0644 stream.yml server.crt /etc/mediamtx/ ; gpg_auth ssh 172.16.16.251 doas install -o root -g root -m 0600 server.key /etc/mediamtx/
###############################################
# 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
# 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 -> Authentication
# Authentication method. Available values are:
# * internal: users 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.
# list of 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: []
# List of 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:
- user: heyheyyouyou
# Password. Not used in case of 'any' user.
pass: idontlikeyourgirlfriend
# IPs or networks allowed to use this user. An empty list means any IP.
ips: []
# List of 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"]
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",
# "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:
# 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 a query parameter.
# This is the JWKS URL that will be used to pull (once) the public key that allows
# to validate JWTs.
authJWTJWKS:
###############################################
# Global settings -> Control API
# Enable controlling the server through the Control API.
api: no
# Address of the Control API listener.
apiAddress: :9997
# Enable TLS/HTTPS on the Control API server.
apiEncryption: 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
apiServerKey: /etc/mediamtx/server.key
# Path to the server certificate.
apiServerCert: /etc/mediamtx/server.crt
# Value of the Access-Control-Allow-Origin header provided in every HTTP response.
apiAllowOrigin: "*"
# List of IPs or CIDRs of proxies placed before the HTTP server.
# If the server receives a request from one of these entries, IP in logs
# will be taken from the X-Forwarded-For header.
apiTrustedProxies: []
###############################################
# Global settings -> Metrics
# Enable Prometheus-compatible metrics.
metrics: no
# Address of the metrics HTTP listener.
metricsAddress: :9998
# Enable TLS/HTTPS on the Metrics server.
metricsEncryption: 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
metricsServerKey: /etc/mediamtx/server.key
# Path to the server certificate.
metricsServerCert: /etc/mediamtx/server.crt
# Value of the Access-Control-Allow-Origin header provided in every HTTP response.
metricsAllowOrigin: "*"
# List of IPs or CIDRs of proxies placed before the HTTP server.
# If the server receives a request from one of these entries, IP in logs
# will be taken from the X-Forwarded-For header.
metricsTrustedProxies: []
###############################################
# Global settings -> PPROF
# Enable pprof-compatible endpoint to monitor performances.
pprof: no
# Address of the pprof listener.
pprofAddress: :9999
# Enable TLS/HTTPS on the pprof server.
pprofEncryption: 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
pprofServerKey: /etc/mediamtx/server.key
# Path to the server certificate.
pprofServerCert: /etc/mediamtx/server.crt
# Value of the Access-Control-Allow-Origin header provided in every HTTP response.
pprofAllowOrigin: "*"
# List of IPs or CIDRs of proxies placed before the HTTP server.
# If the server receives a request from one of these entries, IP in logs
# will be taken from the X-Forwarded-For header.
pprofTrustedProxies: []
###############################################
# Global settings -> Playback server
# Enable downloading recordings from the playback server.
playback: no
# Address of the playback server listener.
playbackAddress: :9996
# Enable TLS/HTTPS on the playback server.
playbackEncryption: 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
playbackServerKey: /etc/mediamtx/server.key
# Path to the server certificate.
playbackServerCert: /etc/mediamtx/server.crt
# Value of the Access-Control-Allow-Origin header provided in every HTTP response.
playbackAllowOrigin: "*"
# List of IPs or CIDRs of proxies placed before the HTTP server.
# If the server receives a request from one of these entries, IP in logs
# will be taken from the X-Forwarded-For header.
playbackTrustedProxies: []
###############################################
# Global settings -> RTSP server
# Enable 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: /etc/mediamtx/server.key
# Path to the server certificate. This is needed only when encryption is "strict" or "optional".
serverCert: /etc/mediamtx/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: yes
# 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: /etc/mediamtx/server.key
# Path to the server certificate. This is needed only when encryption is "strict" or "optional".
rtmpServerCert: /etc/mediamtx/server.crt
###############################################
# Global settings -> HLS server
# Enable reading streams with the HLS protocol.
hls: yes
# Address of the HLS listener.
hlsAddress: :8888
# Enable TLS/HTTPS on the HLS server.
# This is required for Low-Latency HLS.
hlsEncryption: yes
# 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: /etc/mediamtx/server.key
# Path to the server certificate.
hlsServerCert: /etc/mediamtx/server.crt
# 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: []
# 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
# 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: yes
# Address of the WebRTC HTTP listener.
webrtcAddress: :8889
# Enable TLS/HTTPS on the WebRTC server.
webrtcEncryption: yes
# 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: /etc/mediamtx/server.key
# Path to the server certificate.
webrtcServerCert: /etc/mediamtx/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: no
# 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: [68.197.252.15, stream.fizz.buzz]
# 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.cloudflare.com:3478
# - 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
# Time to wait for the WebRTC handshake to complete.
webrtcHandshakeTimeout: 10s
# Maximum time to gather video tracks.
webrtcTrackGatherTimeout: 2s
###############################################
# Global settings -> SRT server
# Enable publishing and reading streams with the SRT protocol.
srt: yes
# 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 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: 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 -> Record
# 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: 1s
# Minimum duration of each segment.
recordSegmentDuration: 1h
# Delete segments after this timespan.
# Set to 0s to disable automatic deletion.
recordDeleteAfter: 24h
###############################################
# 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
# auto-white-balance fixed gains. This can be used in place of rpiCameraAWB.
# format: [red,blue]
rpiCameraAWBGains: [0, 0]
# 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
# * MTX_SEGMENT_DURATION: segment duration
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:

View File

@ -5,7 +5,7 @@
# BEFORE: netif
. /etc/rc.subr
name=opnsense
name=unifi
rcvar=${name}_enable
start_cmd="${name}_start"
stop_cmd="${name}_stop"
@ -14,12 +14,12 @@ load_rc_config $name
tmux_name="unifi"
opnsense_start() {
# /usr/local/bin/tmux new-session -d -s "$tmux_name" "/usr/bin/env VNC_ENABLE=YES VNC_LISTEN=0.0.0.0:5900 /usr/local/bin/bash /home/talexander/launch_opnsense.bash"
/usr/local/bin/tmux new-session -d -s "$tmux_name" "/usr/bin/env VNC_ENABLE=NO VNC_LISTEN=0.0.0.0:5900 /usr/local/bin/bash /home/talexander/launch_unifi.bash"
unifi_start() {
/usr/local/bin/tmux new-session -d -s "$tmux_name" "/usr/bin/env VNC_ENABLE=YES VNC_LISTEN=0.0.0.0:5900 /usr/local/bin/bash /home/talexander/launch_unifi.bash"
# /usr/local/bin/tmux new-session -d -s "$tmux_name" "/usr/bin/env VNC_ENABLE=NO VNC_LISTEN=0.0.0.0:5900 /usr/local/bin/bash /home/talexander/launch_unifi.bash"
}
opnsense_status() {
unifi_status() {
if /usr/local/bin/tmux has-session -t $tmux_name 2>/dev/null; then
echo "$tmux_name is running."
else
@ -28,17 +28,17 @@ opnsense_status() {
fi
}
opnsense_stop() {
unifi_stop() {
/usr/local/bin/tmux has-session -t $tmux_name 2>/dev/null && (
/usr/local/bin/tmux kill-session -t $tmux_name
sleep 10
bhyvectl --vm=unifi --destroy
# kill `cat /var/run/opnsense.pid`
# kill `cat /var/run/unifi.pid`
)
opnsense_wait_for_end
unifi_wait_for_end
}
opnsense_wait_for_end() {
unifi_wait_for_end() {
while /usr/local/bin/tmux has-session -t $tmux_name 2>dev/null; do
sleep 1
done