Icecast

Icecast is a modular free audio server, written in C++. Icecast itself is can't deal with audio formats and requires add-ons called "sources" to do. in this guide, we use ices as our source.

Installation

$ doas pkg_add ices-0.4p12 icecast

edit /var/icecast/icecast.xml

<icecast>
    <location>Earth</location>
    <admin>username</admin>
    <limits>
        <clients>100</clients>
        <sources>2</sources>
        <queue-size>524288</queue-size>
        <client-timeout>30</client-timeout>
        <header-timeout>15</header-timeout>
        <source-timeout>10</source-timeout>
        <burst-on-connect>1</burst-on-connect>
        <burst-size>65535</burst-size>
    </limits>

replace username and Earth with your values.

    <authentication>
        <source-password>hackme</source-password>
        <admin-user>username</admin-user>
        <admin-password>hackmemore</admin-password>
    </authentication>
    <shoutcast-mount>/shoutcast</shoutcast-mount>

replace source-passowrd and admin-password with a secure passoword and chanage username to your prefered value.

    <hostname>example.com</hostname>
    <listen-socket>
        <port>8000</port>
        <bind-address>0.0.0.0</bind-address>
    </listen-socket>
    <listen-socket>
        <port>8080</port>
    </listen-socket>
    <listen-socket>
        <port>8443</port>
        <ssl>1</ssl>
    </listen-socket>

replace example.com with your domain. note that icecast can only listen to IPv4 or IPv6 (and not both)

    <mount type="normal">
                <mount-name>/radio</mount-name>
                <public>0</public>
    </mount>
    <fileserve>1</fileserve>

each stream on icecast is called a mount, we will connect to mounts using our sources

    <paths>
        <basedir>/var/icecast</basedir>
        <logdir>/log</logdir>
        <webroot>/web</webroot>
        <adminroot>/admin</adminroot>
        <pidfile>/var/run/icecast.pid</pidfile>
        <alias source="/" destination="/status.xsl"/>
      <!--  <ssl-certificate>/var/icecast/etc/icecast.pem</ssl-certificate> -->
    </paths>

here we configure paths, and ssl for port 8443. note that ssl certificate should have both private and public cert on same file. you can do that using:

# cat /path/to/public/cert.pem /path/to/private/key.key > /var/icecast/etc/icecast.pem

you might need to change permissions afterwards. and that will create it on /var/icecast/etc/icecast.pem

    <logging>
        <accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
        <!-- <playlistlog>playlist.log</playlistlog> -->
        <loglevel>3</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
        <logsize>10000</logsize> <!-- Max size of a logfile -->
    </logging>
    <security>
        <chroot>1</chroot>
        <changeowner>
            <user>_icecast</user>
            <group>_icecast</group>
        </changeowner>
    </security>
</icecast>

now, run and enable icecast

$ doas rcctl enable icecast
$ doas rcctl start icecast

Sources

There are multiple sources available for icecast, ezstream and ices being developed by xiph community, which happens to be same community behind icecast too. ezstreams appears to be somewhat more modern, easier to configure and more featureful.

ezstream

First you need to install ezstream itself:

$ doas pkg_add ezstream

here is a sample configuration file:

<?xml version="1.0" encoding="UTF-8"?>

<ezstream>

  <servers>
    <server>
      <hostname>127.0.0.1</hostname>
      <password>hackme</password>
    </server>
  </servers>

  <streams>
    <stream>
      <mountpoint>/radio</mountpoint>
      <format>Ogg</format>
    </stream>
  </streams>

  <intakes>
    <intake>
      <filename>playlist.m3u</filename>
    </intake>
  </intakes>

  <decoders>
    <decoder>
      <name>OggDec</name>
      <program>oggdec -R -b 16 -e 1 -s 1 -o - @T@</program>
      <!-- File extensions to use this decoder for -->
      <file_ext>.ogg</file_ext>
      <file_ext>.oga</file_ext>
    </decoder>

    <decoder>
      <name>MadPlay</name>
      <program>madplay -b 16 -R 44100 -S -o raw:- @T@</program>
      <file_ext>.mp3</file_ext>
    </decoder>

    <decoder>
      <name>Flac</name>
      <program>flac -s -d --force-raw-format --sign=signed --endian=little -o - @T@</program>
      <file_ext>.flac</file_ext>
    </decoder>

    <decoder>
      <name>AAC</name>
      <program>faad -d -f 2 -w @T@</program>
      <file_ext>.m4a</file_ext>
    </decoder>
  </decoders>

</ezstream>

adjust servers, source, and intakes as your needs. decoders are needed to handle input audio files, and may need some extra programs to be installed (madplay, etc). afterwards you need to generate a playlist (in m3u format), fortunately m3u format is quite simple:

$ find /path/to/your/music/library >> playlist.m3u

it will also include directories too, but ezstream will skip them:

ezstream[26202]: /path/to/your/music/library cannot determine file type

finally, to run ezstream:

$ ezstream -c ezstream.xml

for further example configurations ezstream also ships with some samples, they are located in /usr/local/share/examples/ezstream.

Ices

Currently there are two versions of Ices on OpenBSD repos, one is 0.4 and another one is 2.0 version 2.0 only supports ogg files and version 0.4 supports both ogg and mp3 formats but it is quite old and might have security issues, if you can, please use ezstream, we will show how to use version 0.4 nonetheless. take a backup of /etc/ices.conf:

$ doas cp /etc/ices.conf /etc/ices.conf.bk

Open /etc/ices.conf

<?xml version="1.0"?>
<ices:Configuration xmlns:ices="http://www.icecast.org/projects/ices">
  <Playlist>
    <File>/etc/playlist.m3u</File>
    <Randomize>1</Randomize>
    <Type>builtin</Type>
    <Module>ices</Module>
    <Crossfade>4</Crossfade>
  </Playlist>

  <Execution>
    <Background>0</Background>
    <Verbose>0</Verbose>
    <BaseDirectory>/tmp/</BaseDirectory>
  </Execution>

  <Stream>
    <Server>
      <Hostname>localhost</Hostname>
      <Port>8000</Port>
      <Password>hackme/Password>
      <Protocol>http</Protocol>
    </Server>

    <Mountpoint>/radio</Mountpoint>
    <Name>My radio</Name>
    <Genre>Music</Genre>
    <Description>This is my radio</Description>
    <Bitrate>128</Bitrate>
    <Channels>2</Channels>
  </Stream>
</ices:Configuration>

ices accepts m3u playlists, so you may use same script we used for ezstream playlists

$ find /path/to/your/music/library | egrep '(ogg|mp3)$' | doas tee -a /etc/playlist.m3u

note that they can include spaces as well. afterwards, run ices

$ doas ices -c /etc/ices.conf

then you can point your media player or browser to http://example.com:8000/radio and enjoy.

MPD

We could use mpd to livestream with Icecast.

First, install mpd & mpc:

$ doas pkg_add mpd mpc

Edit /etc/mpd.conf

# Files and directories #######################################################
#
# This setting controls the top directory which MPD will search to discover the
# available audio files and add them to the daemon's online database. This
# setting defaults to the XDG directory, otherwise the music directory will be
# be disabled and audio files will only be accepted over ipc socket (using
# file:// protocol) or streaming files over an accepted protocol.
#
music_directory         "/please-configure-your-music_directory"

Replace /please-configure-your-music_directory to your path to Music folders. Eg. /home/user/Music

audio_output {
        type            "shout"
        encoder         "vorbis"                # optional, vorbis or lame
        name            "My Shout Stream"
        host            "localhost"
        port            "8000"
        mount           "/radio"
        password        "hackme"
#        quality         "5.0"
        bitrate         "128"
        format          "44100:16:1"
#        protocol        "icecast2"              # optional
#        user            "source"                # optional
        description     "My Stream Description" # optional
        url             "http://example.com"    # optional
        genre           "jazz"                  # optional
        public          "no"                    # optional
#        timeout         "2"                     # optional
#        mixer_type      "software"              # optional
}

Change some values according your needs. Then, Enable & start mpd daemon

$ doas rcctl enable mpd
$ doas rcctl start mpd

Now, populate the database. Depending on how many tracks are in your library this may take a while. The -w makes it wait until it's finished.

$ mpc -w update

Next, make a playlist

$ mpc add /

Then start playing

$ mpc play

To make the playlist randomly play for evermore.

$ mpc random
$ mpc repeat

And finally, visit http://example.com:8000/radio and enjoy.