ROC-RECV(1)

πŸ“¦
version 0.4.0 Β· 4 versions
, in alpine 3.24, arch rolling, debian trixie, nixos 26.05, nixpkgs unstable, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– NAME πŸ’–

roc-recv β€” receive real-time audio 🎧✨


🌸 SYNOPSIS 🌸

roc-recv OPTIONS

πŸŽ€ DESCRIPTION πŸŽ€

okay so bestie, here's the tea: roc-recv catches audio streams flying in from remote senders and writes them straight to an audio device or a file. that's the whole vibe. πŸ¦‹

πŸ’… Options πŸ’…

  • -h, --help β€” print the help and dip out πŸ‘‹
  • -V, --version β€” print the version and dip out 🏷️
  • -v, --verbose β€” turn the verbosity level up (and yes you can use it multiple times, stack it like scrunchies) πŸ”₯
  • -L, --list-supported β€” list all the supported schemes and formats πŸ“‹
  • -o,--output=IO_URI β€” the output file or device URI πŸ’Ύ
  • --output-format=FILE_FORMAT β€” force the output file format, no auto-detect energy πŸ”’
  • --backup=IO_URI β€” the backup file or device URI (if you set it, it gets used whenever there are literally no sessions) πŸ™ˆ
  • --backup-format=FILE_FORMAT β€” force the backup file format πŸ”’
  • -s,--source=ENDPOINT_URI β€” the local source endpoint 🌱
  • -r,--repair=ENDPOINT_URI β€” the local repair endpoint 🩹
  • -c,--control=ENDPOINT_URI β€” the local control endpoint πŸŽ›οΈ
  • --miface=MIFACE β€” the IPv4 or IPv6 address of the network interface you wanna join the multicast group on 🌐
  • --reuseaddr β€” enable SO_REUSEADDR when binding sockets πŸ”
  • --target-latency=STRING β€” target latency, in TIME units ⏱️
  • --io-latency=STRING β€” playback target latency, in TIME units ⏱️
  • --latency-tolerance=STRING β€” max deviation from target latency, in TIME units πŸ“
  • --no-play-timeout=STRING β€” no playback timeout, in TIME units βŒ›
  • --choppy-play-timeout=STRING β€” choppy playback timeout, in TIME units 😭
  • --frame-len=TIME β€” duration of the internal frames, in TIME units 🧩
  • --max-packet-size=SIZE β€” maximum packet size, in SIZE units πŸ“¦
  • --max-frame-size=SIZE β€” maximum internal frame size, in SIZE units πŸ“¦
  • --rate=INT β€” override the output sample rate, in Hz 🎡
  • --latency-backend=ENUM β€” which latency to use in the latency tuner (possible values are "niq", default is niq) 🎚️
  • --latency-profile=ENUM β€” the latency tuning profile (possible values are "default", "responsive", "gradual", "intact", default is default) 🎚️
  • --resampler-backend=ENUM β€” the resampler backend (possible values are "default", "builtin", "speex", "speexdec", default is default) πŸ”„
  • --resampler-profile=ENUM β€” the resampler profile (possible values are "low", "medium", "high", default is medium) πŸ”„
  • -1, --oneshot β€” exit when the last connected client disconnects (default is off) πŸšͺ
  • --profiling β€” enable self-profiling (default is off) πŸ“Š
  • --beep β€” enable beeping on packet loss (default is off) πŸ”Š
  • --color=ENUM β€” set the colored logging mode for stderr output (possible values are "auto", "always", "never", default is auto) 🌈

🌐 Endpoint URI 🌐

the --source, --repair, and --control options define the network endpoints where you receive the traffic. that's the whole point bestie.

ENDPOINT_URI should look like this:

protocol://host[:port][/path][?query]

Examples, served fresh:

  • rtsp://localhost:123/path?query
  • rtp+rs8m://localhost:123
  • rtp://0.0.0.0:123
  • rtp://[::1]:123
  • rtcp://0.0.0.0:123

you can grab the list of supported protocols with the --list-supported option, no cap. πŸ‘‘

the host field should be either an FQDN (domain name), or an IPv4 address, or an IPv6 address wrapped in square brackets. it can be 0.0.0.0 (for IPv4) or [::] (for IPv6) to bind the endpoint to all network interfaces. 🌍

the port field can be left out if the protocol defines a standard port. otherwise it's mandatory, fr. and it can be set to zero to bind the endpoint to a randomly chosen ephemeral port. 🎲

the path and query fields are only allowed for protocols that support them, like RTSP. πŸ›€οΈ

if FEC is enabled on the sender, you need to provide a pair of a source and repair endpoint. the two endpoints should use compatible protocols, like rtp+rs8m:// for the source endpoint and rs8m:// for the repair endpoint. if FEC is disabled, you just provide a single source endpoint. πŸ’«

Supported source and repair protocols:

  • source rtp://, repair none (bare RTP without FEC) πŸƒ
  • source rtp+rs8m://, repair rs8m:// (RTP with Reed-Solomon FEC) πŸ›‘οΈ
  • source rtp+ldpc://, repair ldpc:// (RTP with LDPC-Staircase FEC) πŸ›‘οΈ

on top of that, it's recommended to provide a control endpoint. it's used to exchange non-media info that identifies the session, carries feedback, etc. if you don't provide a control endpoint, the session operates in a reduced fallback mode, which may be less robust and may not support all the features. 😬

Supported control protocols:

  • rtcp://

πŸ’Ύ IO URI πŸ’Ύ

the --output and --backup options need a device or file URI in one of these forms:

  • DEVICE_TYPE://DEVICE_NAME β€” an audio device πŸ”Š
  • DEVICE_TYPE://default β€” the default audio device for that device type ✨
  • file:///ABS/PATH β€” an absolute file path πŸ“
  • file://localhost/ABS/PATH β€” an absolute file path, alternative form (only the "localhost" host is supported) πŸ“
  • file:/ABS/PATH β€” an absolute file path, alternative form πŸ“
  • file:REL/PATH β€” a relative file path πŸ“
  • file://- β€” stdout πŸ“€
  • file:- β€” stdout, alternative form πŸ“€

Examples, because we love a demo:

  • pulse://default
  • pulse://alsa_output.pci-0000_00_1f.3.analog-stereo
  • alsa://hw:1,0
  • file:///home/user/test.wav
  • file://localhost/home/user/test.wav
  • file:/home/user/test.wav
  • file:./test.wav
  • file:-

the list of supported schemes and file formats is available via the --list-supported option. πŸ“‹

if --output is omitted, the default driver and device get selected. if --backup is omitted, no backup source is used. simple as that. 🫢

the --output-format and --backup-format options can force the output or backup file format. if the option is omitted, the file format is auto-detected. and heads up: the option is always required when the output or backup is stdout or stdin. ⚠️

the path component of the URI you provide gets percent-decoded. for convenience, unencoded characters are allowed too, except that % should always be encoded as %25. πŸ“

for example, the file named /foo/bar%/[baz] may be specified using either of these URIs: file:///foo%2Fbar%25%2F%5Bbaz%5D and file:///foo/bar%25/[baz]. πŸ€“

πŸ“‘ Multicast interface πŸ“‘

if the --miface option is present, it defines an IP address of the network interface to join the multicast group on. if it's not present, no multicast group should be joined. 🚫

real talk: it's not possible to receive multicast traffic without joining a multicast group. so you should either provide the multicast interface, or join the group manually using foreign tools. πŸ’€

MIFACE should be an IP address of the network interface to join the multicast group on. it may be 0.0.0.0 (for IPv4) or :: (for IPv6) to join the multicast group on all available interfaces. 🌍

🧚 Multiple slots 🧚

you can specify multiple sets of endpoints to retrieve media from multiple addresses. main character energy, honestly.

those endpoint sets are called slots. all slots should have the same set of endpoint types (source, repair, etc) and should use the same protocols for them. all slots should also have their own multicast interface option, if it's used. 🎰

πŸ” SO_REUSEADDR πŸ”

if the --reuseaddr option is provided, the SO_REUSEADDR socket option will be enabled for all sockets (by default it's enabled only for multicast sockets). πŸ”§

for TCP, it lets you immediately reuse a recently closed socket in TIME_WAIT state, which may be useful when you want to be able to restart the server quickly. ⚑

for UDP, it lets multiple processes bind to the same address, which may be useful if you're using systemd socket activation. πŸ‘―

regardless of the option, SO_REUSEADDR is always disabled when binding to an ephemeral port. 🚫

🎢 Backup audio 🎢

if the --backup option is given, it defines the input audio device or file that will be played when there are no connected sessions. if it's not given, silence is played instead. 🀫

the backup file is restarted from the beginning each time the last session disconnects. and the playback of the backup file is automatically looped. πŸ”

⏱️ Time units ⏱️

TIME should have one of the following forms:

123ns; 1.23us; 1.23ms; 1.23s; 1.23m; 1.23h;

πŸ“ Size units πŸ“

SIZE should have one of the following forms:

123; 1.23K; 1.23M; 1.23G;

🎧 EXAMPLES 🎧

okay bestie this is the part where it gets fun β€” real commands you can literally copy-paste. every single one is here, nothing skipped, i promise. ✨


πŸ’– Endpoint examples

bind one bare RTP endpoint on all IPv4 interfaces:

$ roc-recv -vv -s rtp://0.0.0.0:10001

bind source, repair, and control endpoints to all IPv4 interfaces (but not IPv6):

$ roc-recv -vv -s rtp+rs8m://0.0.0.0:10001 -r rs8m://0.0.0.0:10002 \
    -c rtcp://0.0.0.0:10003

bind source, repair, and control endpoints to all IPv6 interfaces (but not IPv4):

$ roc-recv -vv -s rtp+rs8m://[::]:10001 -r rs8m://[::]:10002 -c rtcp://[::]:10003

bind source, repair, and control endpoints to a particular network interface:

$ roc-recv -vv -s rtp+rs8m://192.168.0.3:10001 -r rs8m://192.168.0.3:10002 \
    -c rtcp://192.168.0.3:10003

bind endpoints to a particular multicast address and join a multicast group on a particular network interface:

$ roc-recv -vv -s rtp+rs8m://225.1.2.3:10001 -r rs8m://225.1.2.3:10002 \
    -c rtcp://225.1.2.3:10003 \
    --miface 192.168.0.3

bind two sets of source, repair, and control endpoints (that's six endpoints in total, we love a multitasker):

$ roc-recv -vv \
    -s rtp+rs8m://192.168.0.3:10001 -r rs8m://192.168.0.3:10002 \
        -c rtcp://192.168.0.3:10003 \
    -s rtp+rs8m://198.214.0.7:10001 -r rs8m://198.214.0.7:10002 \
        -c rtcp://198.214.0.7:10003

πŸŽ€ I/O examples

output to the default device (just omit -o, she's low maintenance like that):

$ roc-recv -vv -s rtp://0.0.0.0:10001

output to the default ALSA device:

$ roc-recv -vv -s rtp://0.0.0.0:10001 -o alsa://default

output to a specific PulseAudio device:

$ roc-recv -vv -s rtp://0.0.0.0:10001 -o pulse://alsa_input.pci-0000_00_1f.3.analog-stereo

output to a file in WAV format (guess the format by extension, she's smart):

$ roc-recv -vv -s rtp://0.0.0.0:10001 -o file:./output.wav

output to a file in WAV format (specify the format manually, no guessing):

$ roc-recv -vv -s rtp://0.0.0.0:10001 -o file:./output.file --output-format wav

output to stdout in WAV format:

$ roc-recv -vv -s rtp://0.0.0.0:10001 -o file:- --output-format wav >./output.wav

output to a file in WAV format (absolute path era):

$ roc-recv -vv -s rtp://0.0.0.0:10001 -o file:///home/user/output.wav

specify backup file:

$ roc-recv -vv -s rtp://0.0.0.0:10001 --backup file:./backup.wav

🧚 Tuning examples

force a specific rate on the output device:

$ roc-recv -vv -s rtp://0.0.0.0:10001 --rate=44100

select the LDPC-Staircase FEC scheme:

$ roc-recv -vv -s rtp+ldpc://0.0.0.0:10001 -r ldpc://0.0.0.0:10002 \
    -c rtcp://0.0.0.0:10003

select lower session latency:

$ roc-recv -vv -s rtp://0.0.0.0:10001 --target-latency=50ms

select lower I/O latency and frame length:

$ roc-recv -vv -s rtp://0.0.0.0:10001 \
    --io-latency=20ms --frame-len 4ms

manually specify thresholds and timeouts:

$ roc-recv -vv -s rtp://0.0.0.0:10001 \
    --target-latency=50ms --min-latency=40ms --max-latency 60ms \
    --no-play-timeout=200ms --choppy-play-timeout=500ms

manually specify resampling parameters:

$ roc-recv -vv -s rtp://0.0.0.0:10001 \
    --resampler-backend=speex --resampler-profile=high

manually specify latency tuning parameters:

$ roc-recv -vv -s rtp://0.0.0.0:10001 \
    --latency-backend=niq --latency-profile=gradual

🌈 ENVIRONMENT VARIABLES 🌈

these are the env vars she supports, bestie:

  • NO_COLOR β€” so by default, terminal coloring is automatically detected. set this to a non-empty string</> and boom, terminal coloring is disabled. it has lower precedence than the --color option though, so don't come for it if --color overrules it. πŸ’…
  • FORCE_COLOR β€” same deal, by default terminal coloring is automatically detected. set this one to a positive integer to enable/force terminal coloring. it has lower precedence than the NO_COLOR variable and the --color option. so the pecking order is real. πŸ‘‘

πŸ‘€ SEE ALSO πŸ‘€

roc-send(1), and the Roc web site at https://roc-streaming.org/ β€” go read it, it's giving documentation excellence.


πŸ’€ BUGS πŸ’€

found a bug? please report any bugs found via GitHub (<https://github.com/roc-streaming/roc-toolkit/>). do it for the culture. 🫢


πŸ‘‘ AUTHORS πŸ‘‘

see the authors page on the website for a list of maintainers and contributors (<https://roc-streaming.org/toolkit/docs/about_project/authors.html>). icons, all of them.


2024, Roc Streaming authors


and that's the whole page bestie, we ate and left no crumbs πŸ“ β€” this was Roc Toolkit 0.4, dated 2024, and it's the ROC-RECV(1) manual. go forth and receive some audio, you absolute main character. πŸ’–βœ¨πŸ¦‹