# joule-moq-ingest: every field, with its default where it has one. # No secret lives here: the relay token and the signing key are files the operator # provides, and a room is its signed descriptor, which is public. [http] listen = "127.0.0.1:8088" # the WHIP and WHEP resources; put a TLS front before them origin = "" # this gateway's origin as grants name it, e.g. "https://ingest.example" cors_allow_origin = "*" max_body_bytes = 65536 request_timeout_ms = 10000 challenge_ttl_s = 300 # how long a proof-of-possession challenge stays good max_challenges = 65536 # challenges held at once, issued and consumed each [media] bind_ip = "127.0.0.1" # each session's UDP socket, and its host candidate ice_lite = true connect_timeout_ms = 15000 idle_timeout_ms = 20000 [relay] addr = "127.0.0.1:4443" # the relay's native QUIC endpoint draft = 22 # the MOQT draft offered in the ALPN: 23, 22, 18 or 16 server_name = "localhost" cert_path = "relay-cert.pem" # the relay's certificate, trusted as a root token_path = "relay-token" # the token value the relay's grant names by SHA-256 [signing] key_path = "gateway.key" # 32 bytes, the Ed25519 seed; absent: made at start signer_id = "" # empty: the key's did:key origin_label = "wai-ingest" [[rooms]] descriptor_path = "room.wrd1" # the room's signed descriptor (WRD1) revoked = [] # grant digests and viewer tags the room's key log revokes [limits] max_whip_sessions = 64 # one more: 503 with Retry-After max_whep_sessions = 256 max_tracks_per_session = 2 # media sections in one offer; more: 422 max_bitrate_kbps = 8000 # per WHIP session, all tracks; stated per track as b=AS bitrate_window_ms = 2000 max_frame_bytes = 4194304 max_queue_bytes = 33554432 # a session's queue to the relay retry_after_s = 5 [groups] audio_group_ms = 200 # an audio group's duration max_video_group_ms = 2000 # a longer video group asks the publisher for a keyframe keyframe_request_interval_ms = 1000 [timeline] max_skew_ms = 250 # |mapped time - arrival| bound; past it, re-anchor [whep] trust = [] # first-hop keys whose receipts WHEP accepts; empty: this gateway's hold_ms = 5000 # how long a group's objects wait for its receipts catalog_wait_ms = 2000 retry_after_s = 2 # what a 409 asks a player to wait [summary] # out_path = "sessions.jsonl" # session records, one JSON line each; absent: kept in memory only # link_out_path = "links.hex" # contribution link records (WLK1), one hexadecimal line each [rtmp] # Enhanced RTMP ingest (live-ingest ยง12); off unless a listener is set. listen = "127.0.0.1:1935" # RTMP over TCP # tls_listen = "127.0.0.1:1936" # RTMPS, with the two files below # cert_path = "rtmps-chain.pem" # key_path = "rtmps-key.pem" # PKCS #8 url = "" # what a stream key's response names; empty: rtmp:///live stream_key_ttl_s = 60 # a stream key from POST /rtmp is good this long for its first use max_sessions = 64 max_message_bytes = 8388608 # the largest message the chunk stream takes max_bitrate_kbps = 40000 # per publisher, every track, over limits.bitrate_window_ms connect_timeout_ms = 15000 # a connection that has not published by then is closed idle_timeout_ms = 20000 chunk_size = 4096 # the chunk size the gateway sends with reconnect_url = "" # the tcUrl a reconnect request names; empty: none reconnect_grace_ms = 5000 # how long a session stays after a reconnect request [injector] # SCTE 104 automation into signed cues (cue-injection); off unless listen is set. # listen = "127.0.0.1:5167" room = "" # the room id, 64 hexadecimal digits, one of [[rooms]] # key_path = "injector.key" # 32 bytes, the injector principal's Ed25519 seed # grant_path = "injector.wrg1" # the principal's room grant, permitting cue and meta leap_seconds = 18 # GPS - UTC, for a UTC timestamp() fps_num = 30000 # the frame rate duration_extension_frames counts in fps_den = 1001 dpi_pid_index = [] # the DPI_PID_index values answered; empty: any max_pending = 256 # cues held for splices still to come # Uncompressed essence over RTP (WAI extensions/essence-contribution.md): a SMPTE ST 2110 # contribution's video, PCM and ancillary data into the room's tracks. Served by a gateway # built with the st2110 feature. A publisher POSTs /st2110 with its room grant and proof and # the description (SDP) of its streams, and gets the ports to send to. [st2110] enabled = false bind_ip = "0.0.0.0" # where a unicast stream's socket binds; the port is the gateway's multicast = false # whether a stream sent to a multicast group is joined interface = "0.0.0.0" # the interface an IPv4 group is joined on encoder = "auto" # auto (the first that passes its probe: va, svt-av1, rav1e), or one by name svt_av1_library = "" # the SVT-AV1 library svt-av1 loads: a path, or "" for libSvtAv1Enc.so.4 svt_av1_preset = 0 # its slowest preset a session may use, 7 to 13 (the stage moves up to 13); # 0: chosen for the stream's size and frame rate va_device = "/dev/dri/renderD128" # the render node va encodes through encoder_fallback = false # a named encoder that is not here: false refuses to start; true takes the # next and says so at start and in every session's answer and record encoder_threads = 0 # 0: as many as the host has bitrate_kbps = 0 # the target bit rate, at most 20000; 0: a tenth of a bit a luma sample calibrate_ms = 400 # how long the encoder is timed on computed pictures at start; 0: not timed key_interval_ms = 2000 # a keyframe, and so a group, at least this often quantizer = 100 # rav1e's base quantizer index, 0 to 255 (it runs at a constant quantizer) encode_queue = 0 # frames that may wait for the encoder; the next is not encoded, and counted. # 0: the frames of two fifteenths of a second, at least 4 audio_object_ms = 20 # the sound one audio object holds playout_delay_ms = 0 # the playout delay the tracks' catalog states leap_seconds = 37 # the seconds the PTP timescale is ahead of UTC max_capture_skew_ms = 1000 # past it, an RTP timestamp is not stated as a capture instant queue_packets = 65536 # datagrams that may wait for a session's readers receive_buffer_octets = 16777216 # asked for on each stream's socket; the host's limit bounds what is given # The telephony bridge (WAI extensions/telephony-bridge.md): callers from one SIP trunk or PBX # into a room as audio participants, and the room's mix back to them. Served by a gateway built # with the telephony feature. No secret lives here: passwords and PINs are files. [telephony] enabled = false sip_udp = "0.0.0.0:5060" # port 0: the system's, logged # sip_tcp = "0.0.0.0:5060" # sip_tls = "0.0.0.0:5061" # with tls_cert_path and tls_key_path (PEM) peer = "192.0.2.10:5060" # the one trunk or PBX; requests from elsewhere are dropped peer_transport = "udp" # how the bridge sends its own requests: udp or tcp media_ip = "0.0.0.0" # where a call's RTP socket binds advertise_ip = "192.0.2.1" # the address a description states jitter_ms = 60 # the longest a packet waits for the one before it audio_group_ms = 100 # a call's group: its receipts follow its end playout_ms = 160 # a room track's sound held before the mix takes from it # source = "digitalCapture" # the digital source type the trunk carries: each call's origin claim hear_callers = true # each call hears the room's other calls hear_owners = [] # and these owners' audio tracks caller_in_record = false # whether a call's record holds the caller's From URI # [telephony.auth] # credentials asked of the peer # realm = "bridge.example" # user = "trunk" # password_path = "/etc/wai/trunk.password" # [telephony.outbound] # credentials the bridge answers the peer's challenges with # user = "bridge" # password_path = "/etc/wai/bridge.password" # register = false # [[telephony.number]] # number = "+15550100" # the Request-URI's user part, as the peer writes it # grants = [""] # [[telephony.number]] # number = "+15550200" # pin = true # the caller enters a PIN, which names its grants # [[telephony.pin]] # pin_path = "/etc/wai/pin-1" # grants = [""] # Contribution over SRT and RIST (WAI extensions/live-contribution.md). A publisher POSTs # /srt or /rist with its room grant and proof, and gets a one-time session. [contrib] host = "" # the host name stated in a session's answer session_ttl_s = 60 # a session not connected by then is dropped max_sessions = 16 max_bitrate_kbps = 80000 # per session, all streams, over limits.bitrate_window_ms record_interval_ms = 10000 # how often a session signs a part of its link record idle_ms = 5000 # a link that receives nothing this long is ended [contrib.srt] # listen = "127.0.0.1:9000" # the SRT listener; absent: /srt is 404 latency_ms = 120 # the connection's is the larger of the two ends' pbkeylen = 16 # AES key bytes: 16, 24 or 32 call_allow = [] # publishers' listeners the gateway may call: "ip:port" or "ip" [contrib.rist] enabled = false # needs a build with the feature `rist` bind_ip = "127.0.0.1" port_min = 0 # the ports sessions are given; 0 and 0: any free port port_max = 0 buffer_ms = 1000 aes = 128 # the Main Profile's PSK key bits: 128 or 256