EZSTREAM(1)

okay bestie, this is EZSTREAM(1), General Commands Manual, and it's giving ✨extremely useful✨ so grab a snack πŸ“

🌸 NAME 🌸

ezstream β€” source client for Icecast with external de-/encoder support


✨ SYNOPSIS ✨

ezstream [-hqrVv] -c configfile [-p pidfile]
ezstream -s file

πŸŽ€ DESCRIPTION πŸŽ€

So ezstream is a command line source client for media streams, and its whole main character moment is streaming to Icecast servers. πŸ’…

It lets you build media streams from files or from standard input, and that input gets piped through an optional external de- and encoder. Every single part of this chain is highly configurable, which is why ezstream can be useful in a huge number of streaming setups. no cap.

πŸ› οΈ Command line arguments πŸ› οΈ

  • -c configfile β€” use the XML configuration in configfile.
  • -h β€” print a summary of available command line arguments with short descriptions, then exit.
  • -p pidfile β€” write the ezstream process ID (a single number) to pidfile. The file will be written even when it already exists. A file lock is maintained until the main ezstream process terminates. If the file cannot be written for any reason, ezstream will log this, but not consider it a fatal error.
  • -q β€” be more quiet. Suppress the output that external programs send to standard error.
  • -r β€” maintain a line of real-time status information about the stream on standard output. (Implies -q.)
  • -s file β€” run ezstream as a line-based shuffling utility. If a playlist argument of - is given, a list of media file names is read from standard input instead of an input file. After successfully reading the entire list, it is shuffled and printed to standard output, and ezstream will exit.
  • -V β€” print the ezstream version number and exit.
  • -v β€” increase logging verbosity. May be used up to three times to also include debug logging output.

🚦 Runtime control 🚦

ezstream offers limited runtime control via signals. Send a signal to the ezstream process β€” e.g. with the kill(1) utility β€” and a certain action gets triggered. it's giving remote control but make it UNIX. 😌

  • SIGHUP β€” rereads the playlist file after the track that is currently streamed. If the playlist is not to be shuffled, ezstream attempts to find the previously streamed file and continue with the one following it, or restarts from the beginning of the list otherwise.
  • SIGUSR1 β€” skips the currently playing track and moves on to the next in playlist mode, or restarts the current track when streaming a single file.
  • SIGUSR2 β€” triggers rereading of metadata for the stream by running the configured program or script. This is the only meaningful signal when streaming from standard input.

πŸ“œ CONFIGURATION FILE SYNTAX πŸ“œ

The ezstream utility uses a simple XML configuration file format. It has a tree-like structure and is made up of XML elements. Out of all the possible XML features, only two things show up in an ezstream configuration file: regular elements that contain text or other elements, and comments. that's it, that's the whole vibe check. πŸ¦‹

Each element in the configuration file consists of a start tag, its content, and an end tag. For example:

<filename>playlist.m3u</filename>
<!-- XML comments look like this. -->

πŸ¦‹ XML CONFIGURATION πŸ¦‹

In this section, every available element is listed and described. Note that for this purpose, elements are introduced in their short, i.e. empty form. In the actual configuration file, they need to be used as start tag + content + end tag, like in the introductory example shown above. so like <element /> is the teaser, and the full fit is <element>content</element>. πŸ’–

Root element

  • <ezstream /> β€” (Mandatory.) The configuration file's root element. It contains all other configuration elements.

Servers block

  • <servers /> β€” this element contains all server blocks as child elements. Its parent is the <ezstream /> element.

A configuration file may contain multiple named server configurations. The stream configuration determines what server configuration should be used.

Server block

  • <server /> β€” (Mandatory.) This element contains a complete server configuration as child elements. Its parent is the <servers /> element.

Server configuration

  • <name /> β€” set the name of the server configuration. This may be referenced in a <stream />.

The name is case-aware, but not case-sensitive.

Default: default

  • <protocol /> β€” transport protocol used to stream to the server:
    • HTTP β€” plain-text HTTP. The <tls /> option defines, if TLS via RFC2817 or RFC2818 is also attempted.
    • HTTPS β€” HTTP over TLS. This option implies that <tls /> is set to "required".
    • ICY β€” ICY streaming protocol
    • RoarAudio β€” RoarAudio streaming protocol

Default: HTTP

  • <hostname /> β€” (Mandatory.) The FQDN host name or IP address of the server.
  • <port /> β€” port number on which the server is listening.

Default: 8000

  • <user /> β€” user to authenticate as on the server.

Default: source

  • <password /> β€” (Mandatory.) Password to authenticate with on the server.
  • <reconnect_attempts /> β€” number of reconnect attempts in case of connection issues with the server, or 0 (zero) for trying indefinitely.

Default: 0

  • <tls /> β€” configure the TLS encryption requirement for the server connection. Possible values are:
    • None β€” no TLS encryption will be attempted.
    • May β€” opportunistic TLS encryption may be used, if the server supports it
    • Required β€” TLS encryption is required. This is the only setting that is providing security against both passive and active attackers.

Default: May

This option is ignored when <protocol /> is set to HTTPS, which implies a value of Required.
  • <tls_cipher_suite /> β€” configure allowed cipher suites for TLS.

For example (modern cipher suites, PFS, TLS 1.2 or better): HIGH:!RSA:!SHA:!DH:!aNULL:!eNULL:!TLSv1.

Default: libshout default cipher suite

  • <ca_dir /> β€” directory in which OpenSSL finds root CA certificates for validating the HTTPS server identity.

Default: system default

  • <ca_file /> β€” path of a root CA bundle file for validating the HTTPS server identity.

Default: system default

  • <client_cert /> β€” X.503 client certificate and key (in PEM format containing both certificate and key in the same file) for authentication on an HTTPS server.

Default: no client certificate authentication

Streams block

  • <streams /> β€” this element contains all stream blocks as child elements. Its parent is the <ezstream /> element.
Note: While multiple stream configurations are supported by the file format, only the one configuration with the name default will be used by ezstream.

Stream block

  • <stream /> β€” (Mandatory.) This element contains the entire stream configuration as child elements. Its parent is the <streams /> element.

Stream configuration

  • <name /> β€” set the name of the stream configuration.

The name is case-aware, but not case-sensitive.

Note: At this time, only the stream configuration with the default name is used and must be present.

Default: default

  • <mountpoint /> β€” (Mandatory.) Stream mountpoint on the server.
  • <public /> β€” boolean setting of whether the broadcast may be listed in a public YP directory, or not.
    • 0|No|False β€” the broadcast is private (the default).
    • 1|Yes|True β€” the broadcast is public.
  • <intake /> β€” use the intake (input media) configuration with the provided symbolic name for this stream.

Default: default

  • <server /> β€” use the server configuration with the provided symbolic name for this stream.

Default: default

  • <format /> β€” (Mandatory.) The stream format.
    • Ogg β€” Ogg media format
    • MP3 β€” MP3 audio format
    • WebM β€” WebM media format
    • Matroska β€” Matroska media format
  • <encoder /> β€” use the encoder configuration with the provided symbolic name (see below), for (re)encoding the stream. Not configuring an encoder makes ezstream stream input media files as-is.
The configured encoder's output stream format must match what is configured in <format />.
  • <stream_name /> β€” informational name of the broadcast.

Default: none

  • <stream_url /> β€” informational URL associated with the broadcast, e.g. the web site.

Default: none

  • <stream_genre /> β€” informational genre of the broadcast.

Default: none

  • <stream_description /> β€” informational description of the broadcast.

Default: none

  • <stream_quality /> β€” informational quality setting of the VBR broadcast.

Default: none

  • <stream_bitrate /> β€” informational bitrate setting of the CBR broadcast.

Default: none

  • <stream_samplerate /> β€” informational sample rate of the broadcast audio.

Default: none

  • <stream_channels /> β€” informational number of audio channels of the broadcast.

Default: none

Intakes block

  • <intakes /> β€” this element contains all intake blocks as child elements. Its parent is the <ezstream /> element.

A configuration file may contain multiple named intake configurations. The stream configuration determines what intake (media input) configuration should be used.

Intake block

  • <intake /> β€” (Mandatory.) This element contains the entire input media configuration as child elements. Its parent is the <intakes /> element.

Intake configuration

  • <name /> β€” set the name of the intake configuration. This may be referenced in a <stream />.

The name is case-aware, but not case-sensitive.

Default: default

  • <type /> β€” configure the input media type:

Alright bestie, here's the rest of the input block, let's go πŸ’…

  • autodetect β€” ezstream tries to figure out all by itself whether your input is a playlist or just one single media file. How does it clock a playlist? By the file name extensions β€œ.m3u” and β€œ.txt”. (this is the default, bestie.)
  • file β€” nope, it's literally just one single media file. That's it. πŸ’
  • playlist β€” it's a playlist, babe. A playlist is a newline-delimited list of media file path names. Comments? Started with a # sign at the very beginning of a line, and ezstream just ignores them. ✨
  • program β€” your input is an executable β€œPlaylist Program”. Go peek at SCRIPTING for the deets, iykyk.
  • stdin β€” input comes in from standard input and gets streamed as-is, no reencoding, no notes. 🫢

<filename /> β€” the input media file name. Mandatory for every type except stdin. No file name, no vibes. πŸ’€

<shuffle /> β€” boolean setting, bestie: do we shuffle the playlist type media or not?

  • 0|No|False β€” stream the playlist content sequentially (the default). In order, like a good little queue. πŸŽ€
  • 1|Yes|True β€” shuffle the playlist before streaming its content. Chaos mode, but make it cute. πŸ¦‹

<stream_once /> β€” another boolean: should ezstream exit after streaming its media input, or start all over again?

  • 0|No|False β€” attempt to start over whenever the end of the media input is reached (the default). Round and round we gooo. πŸ”„
  • 1|Yes|True β€” after streaming all media input, exit. Periodt. πŸ‘‘

🌸 Metadata block 🌸

<metadata /> β€” this element holds the entire metadata configuration as its child elements. Its parent is the <ezstream /> element. One cozy lil home for all your metadata settings. πŸ’–

πŸŽ€ Metadata configuration πŸŽ€

<program /> β€” set an executable β€œMetadata Program” that ezstream will query for all metadata on SIGUSR2, or whenever a new track begins. SCRIPTING has the full tea. β˜•

Default: use metadata as contained in media files

<format_str /> β€” set the format of the string that should be used for the @M@ placeholder, when querying for metadata from an executable. (Yes, the manpage really does spell it β€œquering” and honestly? relatable. πŸ™ˆ)

Default: @a@ - @t@

<refresh_interval /> β€” configure a time interval for additional metadata updates via a β€œMetadata Program”:

  • -1 β€” do not trigger any additional metadata updates (the default).
  • 0 β€” trigger metadata updates at the highest reasonable frequency. Go feral. πŸ”₯
  • >0 β€” configure the time (in seconds) in between additional metadata updates.

<normalize_strings /> β€” boolean setting: should metadata strings get their excess whitespace removed, or not?

  • 0|No|False β€” use metadata strings as-is (the default).
  • 1|Yes|True β€” trim leading and trailing whitespace, and remove excess whitespace in case that there is more than one in sequence. Clean girl aesthetic. ✨

<no_updates /> β€” boolean setting: should metadata updates be suppressed altogether, or not?

  • 0|No|False β€” update metadata in the usual manner (the default).
  • 1|Yes|True β€” disable all metadata updates, and keep existing metadata in streams untouched. βœ‹ No new info, we're frozen like that.

πŸ¦‹ Decoders block πŸ¦‹

<decoders /> β€” this element contains all decoder blocks as child elements. Its parent is the <ezstream /> element.

πŸ’œ Decoder block πŸ’œ

<decoder /> β€” this element contains all configuration of a single decoder. Its parent is the <decoders /> element.

🌈 Decoder configuration 🌈

<name /> β€” set the name of the decoder configuration.

The name is case-aware, but not case-sensitive. (So it knows about your capital letters, it just doesn't care. Iconic behaviour tbh.)

Default: default

<program /> β€” (Mandatory.) Set the full command line to decode a media input file, represented by the @T@ placeholder, into a β€œcanonical internal format” on standard output.

The canonical format should be the same for all configured decoders, e.g. RAW audio with a specific signedness, bitrate, and samplerate that can be consumed by encoders.

For exotic use cases, metadata placeholders may be used here.

Example:

<program>oggdec -R -o - @T@</program>

<file_ext /> β€” (Mandatory.) Set a filename extension to be associated with this decoder.

It is possible to specify more than one <file_ext /> element per decoder to associate more than one file extension to the same decoder.

A filename extension can only be associated with one decoder. One decoder per extension, no polyamory. πŸ’…

πŸ”₯ Encoders block πŸ”₯

<encoders /> β€” this element contains all encoder blocks as child elements. Its parent is the <ezstream /> element.

πŸ‘‘ Encoder block πŸ‘‘

<encoder /> β€” this element contains all configuration of a single encoder. Its parent is the <encoders /> element.

⭐ Encoder configuration ⭐

<name /> β€” (Mandatory.) Set the name of the encoder configuration. This may be referenced in a <stream /> block in case (re)encoding is desired.

The name is case-aware, but not case-sensitive.

Default: default

<format /> β€” (Mandatory.) Stream format produced by this encoder. This must be one of the available stream formats as specified for the <stream /> block.

<program /> β€” (Mandatory.) Set the full command line to encode the β€œcanonical internal format” from standard input into a supported stream format on standard output.

Metadata placeholders may be used here.

Example:

<program>oggenc -r -q 1.5 -t @M@ -</program>

πŸ’– SCRIPTING πŸ’–

The ezstream utility provides hooks for externally controlled playlist and metadata management. How? By running external programs or scripts that need to behave in the ways explained right here. Bestie, these are the rules of the house. 🏠

πŸŽ€ Common Rules πŸŽ€

  • The program must be an executable file.
  • The program must write one line to standard output and exit.
  • The program must not require arbitrary command line options to function. A wrapper script must be used if there is no other way. (Lowkey a vibe-killer, but rules are rules.)

πŸ¦‹ Playlist Programs πŸ¦‹

  • The program must return only filenames, with one filename per execution.
  • The program should not return an empty line unless ezstream is supposed to know that the end of the playlist has been reached. This is significant when the <stream_once/> option is enabled. πŸ‘€

🌟 Metadata Programs 🌟

  • The program must not return anything (just a newline character is okay) if it is called by ezstream with a command line argument that the program does not support.
  • When called without command line arguments, the program should return a complete string that should be used for metadata.
  • When called with the command line argument "artist", the program should return only the artist information of the metadata. (Optional.)
  • When called with the command line argument "title", the program should return only the title information of the metadata. (Optional.)
  • The supplied metadata must be encoded in UTF-8. No exceptions, no cap. 🫢

πŸ’– METADATA πŸ’–

okay so bestie, here's the tea on metadata: the main character of handling it in ezstream is placeholders in your decoder and encoder commands. You drop them in, and during runtime ezstream swaps them out for the real content. It's giving magic trick, but make it text. ✨

⚠️ Heads up, this one matters: all placeholders get replaced with content that's wrapped in single quotes, and any single quote or backslash characters inside get escaped, so the shell doesn't go interpreting anything. So do NOT add any extra quoting yourself, bestie. Ezstream already did it. Adding more is giving double-quoting chaos. πŸ™ˆ

🌈 Metadata Placeholders 🌈

  • @T@ β€” gets swapped for the media file name. It's required in /ezstream/decoders/decoder/program, and it's available in /ezstream/metadata/format_str.
  • @M@ β€” gets swapped for a metadata string. (There's a whole deep dive below, keep reading πŸ‘€) Available in /ezstream/decoders/decoder/program and /ezstream/encoders/encoder/program.
  • @a@ β€” gets swapped for the artist info. Available in /ezstream/decoders/decoder/program, /ezstream/encoders/encoder/program and /ezstream/metadata/format_str.
  • @t@ β€” gets swapped for the title info. Available in /ezstream/decoders/decoder/program, /ezstream/encoders/encoder/program and /ezstream/metadata/format_str.
  • @b@ β€” gets swapped for the album info. Available in /ezstream/decoders/decoder/program, /ezstream/encoders/encoder/program and /ezstream/metadata/format_str.
  • @s@ β€” gets swapped for the string that /ezstream/metadata/program returns when you call it with no command line arguments at all. Available only in /ezstream/metadata/format_str.

🧚 The @M@ Placeholder 🧚

So like, all the other placeholders are super chill β€” they just get swapped for whatever data they're tied to, no drama. But @M@?? Context-sensitive. It reads the room first. πŸ’…

Here's the exact logic ezstream runs:

If ('@M@ is present')
    If (/ezstream/metadata/program AND /ezstream/metadata/format_str)
        Replace with format string result.
    Else
        If (NOT /ezstream/metadata/program AND '@t@ is present')
            Replace with empty string.
        else
            Replace with generated metadata string.
        Endif
    Endif
Endif

And the generated metadata string for @M@ is formatted like "Artist - Title", but only if you've got both artist and title info on deck. If one of the two is missing, you just get the one you have β€” no leading or trailing dash, no awkward dangling punctuation. So like, just "Artist". And if neither artist nor title exists?? It falls back to the name of the media file β€” without its file extension. Iconic fallback behaviour, honestly. πŸ‘‘


πŸ’€ Metadata Caveats πŸ’€

Real talk: you can generate some absolutely cursed results with weird combinations of placeholders, external metadata programs, and updates during runtime via SIGUSR2. If things start getting confusing, bestie β€” simplify. That's the whole advice. 🌸

Metadata updates during runtime happen via a, quote, eccentric feature of libshout. Additional metadata info that's already sitting in the stream ezstream sent gets usually destroyed and replaced with the new data. And here's the kicker: it is not possible to properly tell artist info apart from title info. Which means anything you set with the SIGUSR2 feature will keep ending up entirely in the "Title" field of a stream. Yeah. Just the Title field. Every time. 😭

Icecast might slap additional limitations on top too β€” one historic example being that out of all possible Ogg-based streams, only Ogg Vorbis can actually have its metadata manipulated. RIP to the others, they simply cannot.

Also, the ID3v1 tags (relevant when you're streaming in MP3 format) don't specify any character encoding whatsoever, so ezstream just operates on a "best effort" basis. If you hit encoding issues, it may help to explicitly set a codeset via the LC_CTYPE environment variable, since ezstream assumes ID3v1 tags are in the user's current locale. And note β€” even though ezstream does support different locales, Icecast itself and the listening clients also get a say in the matter. πŸ™ˆ The only way to guarantee consistent results with metadata in non-Ogg streams is to use only the characters available in the ISO-8859-1 codeset. That's the whole vibe. No cap.

And finally β€” external encoders may put their own additional, and possibly completely artificial, restrictions on what characters are valid in metadata. So watch out for that. πŸŽ€


πŸŽ€ FILES πŸŽ€

  • /usr/share/doc/ezstream/examples β€” a directory holding example configuration files for all sorts of uses of ezstream, plus example playlist and metadata scripts. Basically the free starter pack, go look. 🫢

πŸ‘‘ SEE ALSO πŸ‘‘


πŸ’œ AUTHORS πŸ’œ

ezstream was written by:

  • Ed Zaleski <oddsock@oddsock.org>
  • Moritz Grimm <mgrimm@mrsserver.net>

This manual was written by Moritz Grimm.


okay that's the whole page bestie, you made it to the end, I'm so proud πŸ₯ΉπŸ’– this was ezstream 1.0.2, dated August 01, 2022 β€” go forth and stream, you absolute icon, periodt βœ¨πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from