divzeroweb

2f30.org website
git clone git://git.2f30.org/divzeroweb
Log | Files | Refs | README | LICENSE

icecast.md (7037B)


      1 ### Using icecast and mpd for web radio on OpenBSD
      2 
      3 The goal of this guide is to show a simple yet powerful web radio setup.
      4 There is a radio stream server (typically with high bandwidth) and a
      5 number of music players that are the main source of music.  At most one
      6 player can be live at any given moment.  The server broadcasts the
      7 stream of the live music source while at the same time providing a
      8 fallback stream when no source is live.  The fallback stream can be an
      9 always-on random playlist.  This way the radio listeners are transferred
     10 to the live stream when it becomes available and back to the fallback
     11 when it stops.
     12 
     13 
     14 #### Configuring the radio server
     15 
     16 First things first, on the radio server you will need:
     17 
     18     $ pkg_add icecast mpd mpc
     19 
     20 Then, copy the sample configuration file that ships with icecast:
     21 
     22     $ cp /usr/local/share/examples/icecast/icecast.xml.dist \
     23     /var/icecast/icecast.xml
     24 
     25 Edit the configuration file to your liking, but make sure you include
     26 the following, because this is the part that implements the fallback
     27 playlist logic.  The `no-mount` option blocks client connections to the
     28 fallback stream; so this setup allows listeners only on the `/live.ogg`
     29 mount.
     30 
     31     <mount>
     32         <mount-name>/play.ogg</mount-name>
     33         <no-mount>1</no-mount>
     34     </mount>
     35     <mount>
     36         <mount-name>/live.ogg</mount-name>
     37         <fallback-mount>/play.ogg</fallback-mount>
     38         <fallback-override>1</fallback-override>
     39     </mount>
     40 
     41 To run icecast do `/etc/rc.d/icecast start`.
     42 
     43 Now lets configure the mpd music player to be the never-ending loop
     44 playlist on the server that feeds the fallback stream.  The important
     45 thing in `/etc/mpd.conf` is the following part:
     46 
     47     audio_output {
     48         type        "shout"
     49         encoding    "ogg"
     50         name        "myradio"
     51         host        "localhost"
     52         port        "8000"
     53         mount       "/play.ogg"
     54         password    "hackme"
     55         bitrate     "128"
     56         format      "44100:16:2"
     57     }
     58 
     59 To run the music player daemon do `/etc/rc.d/mpd start`.
     60 All is ready at the server side.  To automate the starting of programs
     61 on boot add the following to your `/etc/rc.conf.local` configuration:
     62 
     63     pkg_scripts="icecast mpd"
     64 
     65 Now, simply create playlists using an mpd client like `mpc`
     66 and put the player in random and repeat mode.  You can also use
     67 a simple 10-second crossfade effect:
     68 
     69     $ mpc random on
     70     $ mpc repeat on
     71     $ mpc crossfade 10
     72 
     73 To make all these settings persistent accross mpd restarts (and reboots)
     74 set the `state_file` option in `mpd.conf`:
     75 
     76     state_file    "/var/spool/mpd/mpdstate"
     77 
     78 By now you should be able to listen to the `/play.ogg` stream by using
     79 the `/live.ogg` mount point that is located at
     80 `http://myradio.example.com:8000/live.ogg`.  You can test it from a
     81 client host with mplayer installed like this:
     82 
     83     $ mplayer "http://myradio.example.com:8000/live.ogg"
     84 
     85 If you experience connectivity problems from the outside world, the
     86 easiest way to resolve them is adding the wildcard IP address to the
     87 `icecast.xml` configuration:
     88 
     89     <listen-socket>
     90         <port>8000</port>
     91         <bind-address>0.0.0.0</bind-address>
     92     </listen-socket>
     93 
     94 Otherwise, you can create an additional `listen-socket` node and specify
     95 the IP address of your public network interface.
     96 
     97 
     98 #### Configuring the radio sources
     99 
    100 A music source only needs a player with icecast support, so simply
    101 install mpd and ncmpc, a nice curses mpd client.
    102 
    103     $ pkg_add mpd ncmpc
    104 
    105 Again, the relevant portion of the configuration file is shown here:
    106 
    107     audio_output {
    108         type        "shout"
    109         encoding    "ogg"
    110         name        "myuser@myradio"
    111         host        "localhost"
    112         port        "8000"
    113         mount       "/live.ogg"
    114         password    "hackme"
    115         bitrate     "128"
    116         format      "44100:16:2"
    117     }
    118 
    119 Notice that the only difference with the server is the mount point and
    120 the name.  By convention the name includes the user that is currently
    121 live.  It is crucial for the `bitrate` and `format` options to be the
    122 same with the `/play.ogg` source for the fallback trick to work.
    123 Furthermore, you see that the `host` option is still set to `localhost`,
    124 but no icecast is running on the source machines.  This is on purpose,
    125 and the idea is to use an ssh tunnel between the radio server and the
    126 music source to avoid transmitting plaintext passwords.  This is done
    127 like this, where `myradio.example.com` is the hostname of the server:
    128 
    129     $ ssh -N -L8000:localhost:8000 myradio.example.com
    130 
    131 The above command forwards port 8000 on `localhost` to port 8000 on the
    132 `myradio.example.com` machine.  If you do not want an interactive
    133 session you can also use the `-N` switch, but that's optional.  Once the
    134 tunnel is created and mpd is in playback state it becomes the live
    135 playing source that is streaming on the `/live.ogg` mount point.  No
    136 other source can take the lock while the live stream is active.
    137 
    138 
    139 #### Final considerations and metadata handling
    140 
    141 If all worked-out well so far you have a working radio setup that
    142 supports both live broadcasting and a fallback loop playlist.  You
    143 should only publish the location of the live mount point because
    144 listeners that use the fallback mount directly will continue to listen
    145 to this stream even if the live one comes up.  That is:
    146 
    147     http://myradio.example.com:8000/live.ogg
    148 
    149 In order to use metadata in other services, icecast provides an XSLT
    150 interface to write scripts.  For a list of all available options you can
    151 put the following code in `/var/icecast/web/all.xsl`:
    152 
    153     <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    154     <xsl:output method="xml"/>
    155     <xsl:template match="*">
    156     <xsl:copy-of select="."/>
    157     </xsl:template>
    158     </xsl:stylesheet>
    159 
    160 This dynamically generated XML document is visible at
    161 `http://myradio.example.com:8000/all.xsl`.  For example, if you need a
    162 text-only representation of the currently playing song you could use
    163 something like the following in a file of its own, and access it
    164 likewise:
    165 
    166     <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    167     <xsl:output method="text"/>
    168     
    169     <xsl:template match="/icestats">
    170     <!-- only show the first source -->
    171     <xsl:apply-templates select="source[1]"/>
    172     </xsl:template>
    173     
    174     <xsl:template match="source">
    175     <xsl:choose>
    176     <xsl:when test="title or artist">
    177     <xsl:if test="artist"><xsl:value-of select="artist" /> - </xsl:if>
    178     <xsl:value-of select="title" />
    179     </xsl:when>
    180     <xsl:otherwise>Unknown</xsl:otherwise>
    181     </xsl:choose>
    182     </xsl:template>
    183     
    184     </xsl:stylesheet>
    185 
    186 This is a rather complex example that tests the existence of artist and
    187 title metadata in order to construct a valid string at all times.  The
    188 important thing here is the use of the `<xsl:value-of select="title" />`
    189 construct.  Furthermore, the `source[1]` hack ensures that only one (the
    190 first) mount point is selected, so it displays either the live or the
    191 fallback stream's information and not both.
    192 
    193 Cheers!
    194 
    195 lostd@