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@