Skip to content

Configuration file ​

Unda reads one YAML file: /etc/unda/unda.yaml with the installer, /etc/unda/unda.yaml inside the Docker container. Restart Unda after changing it (sudo systemctl restart unda; live encoders reconnect by themselves).

Secrets can stay out of the file: UNDA_API_TOKEN, UNDA_SRT_PASSPHRASE and UNDA_STREAM_KEYS (or the same names ending in _FILE, pointing at a file) in /etc/unda/unda.env override it. Restream, webhook and pull input URLs take url_env or url_file instead of url.

api.token (UNDA_API_TOKEN) is deprecated: for scripts and Prometheus, create an API key under Server → API keys in the dashboard instead. While the token is set, Unda logs a warning at startup and shows one to admins on the Overview.

This is the complete example file, with every setting and its default:

yaml
server:
  rtmp_addr: ":1935"
  http_addr: ":8080"
  # HTTPS. Easiest: automatic certificates from Let's Encrypt. Point the
  # domain's DNS at this server, open ports 443 and 80, then:
  # http_addr: ":443"
  # http_redirect_addr: ":80"    # plain HTTP: redirects to HTTPS, answers Let's Encrypt
  # public_https_port: 443       # only behind a port map (Docker 443 -> 8443):
  #                              # the port that redirect sends browsers to
  # tls:
  #   letsencrypt:
  #     domains: [tv.example.com]
  #     email: ops@example.com   # optional: expiry notices from Let's Encrypt
  #     # directory_url: staging # try a setup first without hitting rate limits
  # Certificates are kept in <paths.data_dir>/acme and renewed on their own;
  # the Server page shows their expiry, and an alert fires if renewal fails.
  #
  # Or your own certificate files (certbot or any other tool keeps them fresh;
  # they are re-read when they change, and a corrupt renewal keeps serving the
  # last good certificate):
  # tls:
  #   cert_file: /etc/letsencrypt/live/tv.example.com/fullchain.pem
  #   key_file:  /etc/letsencrypt/live/tv.example.com/privkey.pem
  #
  # rtmps_addr: ":1936"          # RTMP over TLS, with the same certificate
  # Reverse proxies in front of the server (IPs or CIDRs) whose X-Forwarded-For
  # and X-Forwarded-Proto are believed: the client address for sign-in throttling
  # and the audit log, and whether the browser used HTTPS. Empty = trust nobody.
  # trusted_proxies: ["127.0.0.1/32"]
  # The names viewers use, when HTTPS is handled by a proxy in front (Caddy,
  # nginx) so this server has no certificate to tell them from. Needed only for
  # a license issued for a domain.
  # public_domains: [tv.example.com]

# People sign in to the dashboard with accounts (invite-only; the first start
# prints a one-time setup link for the owner). Passwords, API keys, the
# api.token and session cookies are only accepted over HTTPS, or over plain HTTP
# from this machine — see server.tls, trusted_proxies and
# auth.allow_insecure_login.
#
# Secrets can come from the environment instead of this file (env wins):
#   UNDA_API_TOKEN, UNDA_SRT_PASSPHRASE, UNDA_STREAM_KEYS (comma-separated)
# each also as UNDA_<NAME>_FILE=/path (Docker/Kubernetes secrets pattern).
# If this file holds secrets, keep it chmod 600 — the server warns otherwise.

log:
  level: info

# Legacy stream keys: each publishes under a stream of the SAME name, so the key
# is visible in every watch link. Optional — prefer channels (dashboard →
# Channels), whose secret key is separate from the public stream name.
streams:
  keys:
    - mykey

paths:
  recordings_dir: ./data/recordings   # default <data_dir>/recordings
  hls_dir: ./data/hls
  # media_dir: ./data/media   # files that playout channels play (default <data_dir>/media)
  # rewind_dir: ./data/hls/.rewind   # streams' rewind windows and every stream's few HLS segments
  #                                  # (default <hls_dir>/.rewind): a window takes bitrate x minutes,
  #                                  # e.g. 1.1 GB for 30 min at 5 Mb/s
  # The server's own state: the account database (unda.db), the license file
  # and the first-run setup token. Keep it private to the server's user and back
  # it up (`unda admin backup <file>` is safe while the server runs).
  data_dir: ./data

rtmp:
  publish_policy: reject # or "replace"
  idle_timeout_seconds: 8

hls:
  segment_duration_seconds: 2 # target segment duration; default 2
  segment_count: 6 # sliding-window segment count; default 6, min 3
  # Each HLS viewer gets a session id (?sid=) carried in its playlist and segment
  # URLs, so one browser tab counts as one viewer. Behind a CDN that caches on the
  # full URL, either make it ignore the query string or set this to true (viewers
  # are then counted by address + User-Agent).
  disable_session_ids: false
  # Each stream is packaged for HLS from the moment it goes live, so a viewer
  # opening a channel nobody is watching starts at once instead of waiting for a
  # segment to be made. true packages a stream only once someone asks for it.
  on_demand: false
  # Segments are written to paths.rewind_dir (a few MB per stream, written at
  # the stream's bitrate): about 0.3 MB of memory per stream instead of about
  # 14 at 3 Mb/s. true keeps them in memory instead (no disk writes).
  segments_in_memory: false

api:
  # DEPRECATED: an owner-level bearer token for scripts and Prometheus, from
  # before accounts existed. It has no two-factor sign-in, never expires and
  # is "config token" in the audit log; while it is set the server logs a
  # warning and the dashboard shows one to admins. Use API keys instead
  # (dashboard → API keys): each has a name and a role and can be revoked.
  #   curl -H "Authorization: Bearer <token>" http://localhost:8080/api/v1/streams
  # If you still use it, generate a strong one (openssl rand -hex 32), ideally via
  # UNDA_API_TOKEN / UNDA_API_TOKEN_FILE instead of this file. The server
  # refuses to start with the placeholder value below.
  # token: "changeme-generate-a-strong-random-token"

auth:
  # Accept passwords, API keys, the api.token and session cookies over plain
  # HTTP from other machines. Off by default: any of them sent unencrypted can
  # be read on the network. Only for a closed studio LAN; prefer HTTPS.
  allow_insecure_login: false

license:
  # The signed license file. Default: <paths.data_dir>/license.json, which is
  # where the dashboard (License page) and "unda license install" write it.
  # No license = evaluation mode for 30 days (2 live streams, 2 accounts besides
  # the owner); after that new streams are refused until a license is installed.
  # file: /var/lib/unda/state/license.json

srt:
  # Optional. SRT ingest is disabled unless addr is set — a third way to
  # get media in, alongside RTMP and (soon) whatever else, not a
  # requirement. Publish with e.g.:
  #   ffmpeg ... -f mpegts "srt://SERVER:6000?streamid=publish:mykey"
  # Viewers pull with:  srt://SERVER:6000?streamid=read:mykey  (no stream key needed;
  # the passphrase below applies to viewers too). ":6000" listens on IPv4 and IPv6.
  # addr: ":6000"
  # latency_ms: 500          # SRT transmission latency; default 500
  # passphrase: ""           # if set (10-79 chars), publishers and viewers must encrypt with it

webrtc:
  # WebRTC (license feature "webrtc"): about a second of delay.
  #   Publish (WHIP, OBS 30+: Service "WHIP"): https://SERVER/whip/<stream>, Bearer Token = the stream key
  #   Play (WHEP): https://SERVER/webrtc/<stream>, or the watch page's "Low latency" switch
  # Keys and playback tokens are refused over plain HTTP (except from this machine).
  # All media uses one UDP port: open it in the firewall (and publish it in Docker).
  # disabled: false
  # udp_port: 8189
  # public_ips: [203.0.113.7]  # behind 1:1 NAT (Docker's bridge, a cloud VM with a private address):
  #                            #   the public address(es) to announce; forward udp_port to this machine
  # stun_servers: ["stun:stun.l.google.com:19302"]  # or let the server find its public address itself
  # ice_servers:               # given to players and encoders whose network blocks UDP (a TURN relay)
  #   - urls: ["turn:turn.example.com:3478?transport=udp", "turns:turn.example.com:443?transport=tcp"]
  #     # username: unda       # a fixed account, with credential / credential_env / credential_file
  # turn_secret_env: UNDA_TURN_SECRET  # or turn_secret / turn_secret_file: coturn's static-auth-secret;
  #                            #   each client gets its own credentials, valid turn_ttl_minutes (default 1440)
  #                            #   Limit coturn to relaying to this server (allowed-peer-ip), see the WebRTC guide
  # max_publishers: 64         # WHIP sessions at once
  # max_viewers: 500           # WHEP sessions at once
  # max_audio_streams: 16      # streams whose sound is converted for WHEP viewers at once (one FFmpeg each)

record:
  # Recording is started/stopped per stream via the API:
  #   curl -X POST -H "Authorization: Bearer <token>" \
  #        -d '{"action":"start"}' http://localhost:8080/api/v1/streams/mykey/record
  # Files land in paths.recordings_dir/<stream>/<YYYY-MM-DD_HH-MM-SS>.ts
  # (MPEG-TS: crash-safe by construction, playable while still being written).
  split_duration_minutes: 60 # new file every ~N minutes, at the next keyframe; default 60
  retention_days: 0 # delete recordings older than N days; 0 (default) = never delete

restream:
  # Push live streams to external destinations (RTMP, RTMPS, SRT, UDP or RTP). Targets
  # here start at boot; more can be added/removed live via
  #   POST   /api/v1/streams/<stream>/push        {"name":"yt","url":"rtmp://..."}
  #   GET    /api/v1/streams/<stream>/push        (state, redacted URL, last error)
  #   DELETE /api/v1/streams/<stream>/push/<id>
  # A failing destination retries with backoff (5s, 10s, 30s, 60s cap) and
  # never affects the others. The URL contains the destination's stream key:
  # it is never logged or returned by the API (only a redacted form is), but
  # it IS stored in plaintext in this file unless you use url_env / url_file
  # (exactly one of url / url_env / url_file per target) — keep unda.yaml private.
  # targets:
  #   - stream: mykey
  #     name: youtube
  #     url: rtmp://a.rtmp.youtube.com/live2/xxxx-xxxx-xxxx-xxxx
  #   - stream: mykey
  #     name: relay
  #     url: srt://relay.example.com:9000?streamid=publish:mykey&latency=800
  #   - stream: mykey                # MPEG-TS over UDP: set-top boxes, hardware decoders, IPTV
  #     name: headend
  #     url: udp://192.168.1.60:6000               # unicast
  #   - stream: mykey
  #     name: lan-multicast
  #     url: udp://239.1.1.10:6000?ttl=4&iface=eth0   # multicast; pkt_size=1316 is the default
  #   - stream: mykey
  #     name: rtp-headend
  #     url: rtp://192.168.1.60:5004?pkt_size=1316  # MPEG-TS over RTP; operator only, no encryption
  #   - stream: mykey
  #     name: rist-partner
  #     url: rist://partner.example.com:5000?buffer=1000  # RIST Simple Profile: lost packets resent; even port
  #   - stream: mykey
  #     name: rist-encrypted
  #     url_env: UNDA_PUSH_RIST_URL   # rist://host:port?secret=...&aes-type=256: Main Profile, encrypted, any port
  #   - stream: mykey
  #     name: twitch
  #     url_env: UNDA_PUSH_TWITCH_URL     # or: url_file: /run/secrets/twitch_url
  #   - stream: mykey                # broadcast TV: re-encoded for a DVB multiplexer,
  #     name: dtt-mux                #   IP modulator or satellite uplink (udp://, rtp://, srt://, rist:// or http-pull://)
  #     url: udp://239.1.1.20:5000?ttl=4
  #     broadcast:                   # 16:9, CBR MPEG-TS with DVB service information
  #       format: 576p25             # 576p25 (SD, default), 720p50 or 1080i25 (HD, interlaced)
  #       video_codec: h264          # h264 (default), hevc (576p25/720p50 only) or mpeg2 (576p25 only);
  #                                  #   H.264-only DVB-T2/S2 networks can't show hevc or mpeg2
  #       mux_kbps: 1300             # constant total rate, null packets included: what the station takes.
  #                                  #   Default 1300 for SD h264; otherwise the minimum safe value for the video
  #       # video_kbps: 960          # default: fitted to mux_kbps (960 in 1300 with AAC 128); else h264 8000 HD,
  #                                  #   hevc 1200 / 4000, mpeg2 4000
  #       audio_codec: aac           # aac (default; mp2 with mpeg2 video), mp2 or ac3 (Dolby Digital)
  #       audio_kbps: 128            # default 128 (aac) / 192 (mp2, ac3)
  #       # aac_packing: latm        # adts (default, most receivers) or latm (DVB's LATM/LOAS, stream type 0x11)
  #       service_name: "Unda TV"    # SDT channel name (default: the stream name)
  #       service_provider: "Unda"   # SDT provider
  #       service_id: 1              # also: transport_stream_id, original_network_id,
  #       # pmt_pid: 4096            #   pmt_pid, video_pid (256), audio_pid (257)
  #       # ad_cues: true            # SCTE 35 ad cues for an ad inserter (start breaks on the stream page);
  #                                  #   cue_pid: 258 by default
  #   - stream: mykey                # broadcast TV the station's receiver pulls over HTTP from this server:
  #     name: cable-headend          #   https://<server>/tv/<token>.ts (the Restream tab shows the link)
  #     url: http-pull://?token=Ab3dEf6hIj9kLm2nOp5qRs&allow=198.51.100.0/24
  #                                  #   token: 22 letters, digits, - or _ (without it the link changes at
  #                                  #   every start); allow: who may pull; plain=1: plain HTTP too
  #     broadcast:
  #       service_name: "Unda TV"

limits:
  # Concurrent connections per client IP, counted separately on the RTMP, HTTP
  # and SRT listeners and for WebRTC sessions. Set it on any server reachable from the internet: left
  # at 0 (unlimited, the built-in default) one client can hold as many
  # connections as it likes. Raise it where many viewers share one address (a
  # venue, an office); browsers over HTTPS use one connection each. Behind a
  # reverse proxy (Caddy, nginx) every HTTP connection comes from the proxy,
  # so either leave it at 0 there or let the proxy do its own per-IP limiting.
  max_conns_per_ip: 100
  # max_egress_mbps: 80      # once reached, NEW viewers are refused (503 / RTMP reject);
  #                          # existing viewers are never throttled or dropped

# UDP / MPEG-TS (M13): plain UDP in and out, for LANs, IPTV headends, set-top boxes and
# hardware encoders. Use SRT over the internet: UDP has no retransmission, login or encryption.
# udp:
#   timeout: 5s              # a silent input goes offline after this, and resumes by itself
#   jitter: 200ms            # input delay line that smooths arrival timing
#   recv_buffer_mb: 8        # socket receive buffer per input; Linux caps it at net.core.rmem_max (see README)
#   loss_warn_percent: 0.1   # recent (60 s) packet loss that turns the dashboard yellow ...
#   loss_critical_percent: 1 # ... and red
#   inputs:
#     - name: camera-1                 # the stream key it publishes as
#       listen: 0.0.0.0:5001
#       allow: [192.168.1.20]          # sender IPs or CIDRs; empty = anyone who can reach the port
#       timeout: 5s
#     - name: rtp-camera
#       listen: 0.0.0.0:5004
#       rtp: true                       # RFC 2250 MPEG-TS over RTP (payload type 33)
#       allow: [192.168.1.20]
#       # path2: "239.2.1.1:5004"        # RTP only: the same stream a second way (SMPTE 2022-7)
#       # interface2: eth2               # the interface to join the path2 group on
#     - name: iptv-feed
#       multicast: 239.1.1.1:5000      # IPv4 group to join
#       interface: eth0
#   outputs:                           # any stream out as MPEG-TS over UDP (these become restream targets)
#     - stream: channel-1
#       to: 192.168.1.60:6000
#     - stream: channel-1
#       multicast: 239.1.1.10:6000
#       ttl: 4
#       interface: eth0

# Pull inputs (license feature "pull"): streams Unda fetches from elsewhere and
# publishes under the input's name, one FFmpeg each (FFmpeg required). HLS
# (.m3u8; the highest-bitrate variant is taken), MPEG-TS or FLV over HTTP(S),
# RTMP(S) and RTSP(S). H.264 video is copied, audio that isn't AAC converted;
# other video only with transcode_video: true (about a core per HD channel). An
# address can hold a password or token: give it with url_env or url_file to
# keep it out of this file. They can also be made in the dashboard (Server ->
# Pull inputs).
# pull_inputs:
#   - name: news
#     url: https://example.com/live/news/index.m3u8
#   - name: lobby-camera
#     url_env: LOBBY_CAMERA_URL                # e.g. rtsp://user:password@192.168.1.64/stream1
#     rtsp_transport: tcp                      # or udp
#   - name: partner-feed
#     url_file: /etc/unda/partner-feed.url     # e.g. http://iptv.example.com:8080/live/user/pass/123.ts
#     # user_agent: "VLC/3.0.20"               # some IPTV providers only serve certain players
#     # timeout: 10s                           # how long the stream is held while the source reconnects
#     # transcode_video: true                  # MPEG-2/HEVC sources
#     # paused: true                           # listed, not pulled

# Multi-channel inputs (MPTS in): split a bundle of TV channels (a satellite
# receiver's or operator's multi-program transport stream) into separate streams.
# Programs in H.264 + AAC are split in-process; other audio is converted with
# FFmpeg; other video only with transcode_video: true (costly).
# mpts_inputs:
#   - name: sat-bundle
#     source: udp://239.1.1.1:5000             # or udp://:5000 (unicast), rtp://...
#     # source: srt://ird.example.com:9000?streamid=sat&passphrase=...  # connect to an SRT sender
#     # source: srt://:9000?passphrase=...     # or wait for one to connect (one at a time)
#     # source: rist://@:5000?buffer=1000      # RIST Simple Profile receiver (even port; RTCP on the next)
#     # source: rist://@:5001?secret=...       # RIST Main Profile, encrypted with the sender's passphrase (any port)
#     interface: eth0                          # multicast: interface to join on
#     # allow: [192.168.1.20]                  # optional: only these senders
#     # discover_only: true                    # list the programs (API/dashboard), publish nothing
#     programs:
#       - program: 101                         # program_number in the feed
#         stream: sports-hd                    # the Unda stream it becomes
#         # audio_language: eng                # or audio_pid: 0x102; default the first audio
#         # transcode_video: true              # needed for MPEG-2/HEVC video (about a core per HD channel)
#       - program: 102
#         stream: news-24

# Multi-channel transport streams (MPTS): several streams as the programs (TV
# channels) of one constant-bitrate MPEG-TS, for an IPTV network, a DVB
# multiplexer or modulator, or a partner. Needs FFmpeg: each program is copied
# (bitrate = its share, above its source's peak) or re-encoded to SD with encode.
# mpts_outputs:
#   - name: iptv-bundle-1
#     destination: udp://239.2.2.1:6000        # or rtp://..., srt://host:port?streamid=..., rist://host:5000
#     interface: eth0                          # multicast: outgoing interface
#     ttl: 4
#     provider: "Unda Community TV"            # SDT provider name
#     network_id: 1
#     transport_stream_id: 1
#     total_bitrate: 25Mbps                    # constant, null packets included; omit = the programs' sum + headroom;
#                                              #   vbr = variable: no padding, only what the channels carry (IP networks)
#     pat_pmt_interval: 100ms                  # sdt_interval defaults to 500ms (at most 2s)
#     offline: black                           # while a stream is offline its channel shows: black (default), slate, none
#     # slate_image: /etc/unda/slate.png       # the picture for offline: slate
#     # epg: false                             # playout channels carry now/next (DVB EIT) unless this is false
#     programs:
#       - stream: channel-1
#         program: 1
#         name: "Channel 1"                    # SDT service name
#         pmt_pid: 0x100
#         pids: { video: 0x101, audio: [0x102] }
#         bitrate: 6Mbps                       # copied as it is: this program's constant share
#         # ad_cues: true                      # SCTE 35 ad cues (cue_pid: automatic unless set)
#       - stream: sports-hd
#         program: 2
#         name: "Sports HD"
#         pids: auto                           # assigned without clashes
#         encode: { format: 1080i25, video_codec: h264, audio_codec: ac3 }  # re-encoded (see broadcast outputs)

# Adaptive-bitrate transcoding. Turn it on and choose the encoder (CPU or a GPU)
# in the dashboard: Server → Transcoding. Needs FFmpeg. The settings below are
# optional and advanced; enabled/hardware/max_concurrent here only seed a server
# that has never saved them from the dashboard.
# transcode:
#   streams: ["vip"]       # optional: keys transcoded automatically at publish ("*" = every stream)
#   # ffmpeg_path: ffmpeg  segment_seconds: 2
#   # fps: 30              MAXIMUM output frame rate; each stream keeps its own (25, 30); 50 and 60 are halved
#   # max_source_mbps: 60  refuse to transcode a source above this video bitrate (it is still served passthrough)
#   # Rungs are ceilings: each stream gets rungs no bigger than itself, in its own aspect ratio,
#   # at no more bitrate than it justifies (see the README).
#   # renditions default to 2160p/1080p/720p/480p/360p/240p/144p; override with a list of
#   #   {name, width, height, video_kbps, audio_kbps} (even dimensions, name a-z0-9_-)

# Dashboard multiview stills (one small JPEG per stream, decoded from the latest
# keyframe by FFmpeg). On whenever FFmpeg is found; bounded to a couple of decodes at a time.
# thumbnails:
#   disabled: false       # true = no stills (tiles show names and stats only)
#   ffmpeg_path: ffmpeg   # default: transcode.ffmpeg_path, else ffmpeg from PATH
#   max_concurrent: 2     # simultaneous decodes (1-16)

monitoring:
  # /metrics (Prometheus) and /debug/pprof/* are served behind the API token —
  # metrics carry live stream keys, which are publish credentials.
  # disable_pprof: true   # remove /debug/pprof/* entirely
  # Every live channel's sound is measured (Multiview meters, the "no sound"
  # alarm) when FFmpeg is found: about 0.5% of a CPU core and 15 MB a channel.
  # silence_alarm_seconds: 10      # silent this long = "no sound" (3-3600)
  # disable_audio_levels: true     # no meters, no alarm
  # Every live channel's picture is checked from its keyframes every few
  # seconds (the "picture frozen" and "picture black" alarms) when FFmpeg is
  # found: one small decoder a channel.
  # frozen_alarm_seconds: 20       # not moving this long = "picture frozen" (5-3600)
  # black_alarm_seconds: 10        # black this long = "picture black" (3-3600)
  # disable_picture_check: true    # no picture alarms

# Webhook alerts (M10). Nothing is sent unless at least one webhook is set.
# alerts:
#   min_input_kbps: 1500        # alert if an input stays below this; 0 (default) = no bitrate alerts
#   bitrate_grace_seconds: 20   # how long it must stay low; also the warm-up after a stream starts
#   cooldown_seconds: 60        # min gap between identical alerts for one stream
#   events: [stream_down, stream_up, bitrate_low, bitrate_recovered]   # default: all four
#   webhooks:
#     - name: ops
#       url_env: UNDA_ALERT_OPS_URL     # exactly one of url / url_env / url_file;
#                                           # Slack/Discord URLs are secrets — keep them out of this file

# Twice a day, read the vendor's latest release description and tell owners
# and admins on the dashboard when a newer version exists. Nothing is
# downloaded or installed; the request carries only this server's version.
# updates:
#   disabled: true

# Viewer sessions (the dashboard's Sessions page): each player watching a
# stream over HLS, DASH, RTMP or SRT, with its address, player, start, length
# and traffic. Kept in the database; only operators and above can see them.
# sessions:
#   retention_days: 30    # 0 = 30, at most 365
#   disabled: true        # keep no history on disk (viewers watching now are still shown)

# Daily database copies: once a day, while it runs, the server copies its
# database (accounts, channels and their keys, playlists, inputs, settings)
# to <data_dir>/backups/daily-<date>.db. They stay on this disk: copy that
# folder and license.json to another machine (see the install guide).
# backups:
#   keep_days: 7          # 0 = 7, at most 365
#   disabled: true        # take no daily copies (another backup covers the database)

# 24/7 channels (playout). Each channel plays the files of a schedule, fills
# the gaps, and lets a live stream take over while it is live. It is a stream
# like any other: watch /watch/<name>, restream it, record it. Every item is
# re-encoded to one picture size, so each channel runs an encoder all the
# time: about half to two thirds of a CPU core at 720p30 with libx264.
# Needs FFmpeg (and ffprobe next to it) and the "playout" license feature.
# playout:
#   asrun_retention_days: 90   # the as-run log; -1 keeps it forever
#   media_max_gb: 0            # cap on the media folder for uploads (0: none; 5 GB of disk is always left free)
#   channels:
#     - name: tv1                          # the stream's name
#       schedule: /etc/unda/schedules/tv1.yaml
#       live: studio                       # optional: this stream takes over while live
#       # width: 1280, height: 720, fps: 30 (25/30/50/60), video_kbps: 3000, audio_kbps: 128
#       filler: image                      # black (default), image or video (looped)
#       filler_file: /etc/unda/slate.png   # image: a picture file; video: a file in media_dir