An easy and useful use of Icecast is a streaming server at home. A single source of audio files can be used and available to all computers on the network. Instead of running speakers from your stereo through out your house, use your computers.

Introduction

This is an example network:

(Internet) ---- (Router/Gateway) 10.10.10.1
                 
(computer 1)     kuiper   10.10.10.10   (a home server that will run icecast)
(computer 2)     thornton 10.10.10.100  (a wireless laptop)
(computer 3)     barker   10.10.10.15   (a desktop system)
(computer 4)     harrah   10.10.10.101  (laptop for work)

On kuiper there is a user icecast with a home directory of /home/icecast. icecast has a locked password but will allow people to use sudo to su to the account. (This is how I have mine setup. It would be fine to allow logins. Logging in your could rip all the files from CD. I keep all my music on my server AND laptop and just upload files from the laptop to the server, to keep with the 'always have a backup' thinking.

/home/icecast/bin   small scripts get things done.
/home/icecast/etc   we'll need configuration files.
/home/icecast/Music contains is a centralize location for the music files.
/home/icecast/logs  we will have log files, store them there.

Note 1: Forward icecast user's email

Note: This is a local account that probably will not be used, but might get mail.

sudo su - icecast
(Postfix, Sendmail, EXIM):  echo mek > ~/.forward
(qmail):                    echo '&mek' > ~/.qmail-default
This will just make sure you don't "mysteriously" fill a filesystem with email.

First thing is to create /home/icecast/bin/sync-music.sh

Script: /home/icecast/bin/sync-music.sh

remoteuser="mek"
remotehost="thorton"
remotedir="/home/$remoteuser/Music"
echo "Sync'ing files"
### Note: local directory does not have need the Music dir here
###       the local directory is $HOME, I just use that env. var.
###       rysnc will use the remote name Music/... and copy to $HOME 
/usr/bin/rsync -ap $remoteuser@$remotehost:$remotedir $HOME
exit 0

(Grab the files from a remote machine and copy them to our central location)

Configure Icecast

Configure icecast. Create the file /home/icecast/etc/icecast.xml. At first the configuration file might look confusing but is easy to figure out. The docs are straight forward. Make sure to read the docs for the right version of Icecast (/usr/bin/icecast -v will tell you what version you are running).

Config File: /home/icecast/etc/icecast.xml

    <icecast>
      <limits>
        <clients>5</clients>
        <sources>2</sources>
        <threadpool>5</threadpool>
        <queue-size>102400</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>
      
      <authentication>
        <source-password>PASSWORD</source-password>
        <relay-password>PASSOWRD</relay-password>
        <admin-user>admin</admin-user>
        <admin-password>PASSWORD</admin-password>
      </authentication>
      
      <hostname>kuiper</hostname>
      
      <listen-socket>
        <port>8000</port>
        <!--<bind-address>127.0.0.1</bind-address> -->
      </listen-socket>
      
      <fileserve>1</fileserve>
      
      <paths>
        <basedir>/usr/share/icecast</basedir>
        <logdir>/home/icecast/logs</logdir>
        <webroot>/usr/share/icecast/web</webroot>
        <adminroot>/usr/share/icecast/admin</adminroot>
        <pidfile>/home/icecast/logs/icecast.pid</pidfile>
        <alias source="/" dest="/status.xsl"/>
      </paths>
      
      <logging>
        <accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
        <!-- <playlistlog>playlist.log</playlistlog> -->
        <loglevel>4</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
      </logging>
      
    <security>
        <chroot>0</chroot>
    </security>
    
  </icecast>

This configuration file will save logs in /home/icecast/logs and user the web files for icecast that are located in /usr/share/icecast (the location from the icecast package for the operating system (ie: where the SuSE rpm put it). A maximum of five clients can connect. If I choose, I can allow two other connections to relay the feed (the source setting). Change the passwords to something a bit safer.

Start and Stop Icecast

If you chose you could create a system init script to have this server start up on boot. My setup does not. There is a script, myice you can use, but you'll need to modify the security sections of the icecast.xml file. On my setup the user icecast will start the server and does not need to change users (and does not have the rights, only root does).

  <security>
    <chroot>0</chroot>
    <changeuser>icecast</changeuser>
    <changegroup>users</chanegroup>
  </security>

I created a small script to stop and start icecast from the command line /home/icecast/bin/icecash.sh:

Script: /home/icecast/bin/icecast.sh

  #!/bin/sh
  usage="$0 {start|stop|restart|status}"
  pidfile="/home/icecast/logs/icecast.pid"
  cfgfile="/home/icecast/etc/icecast.xml" 
  
  case $1 in
    start) 
      if [ -f $pidfile ]; then 
        echo "Icecast already running with pid file $(cat $pidfile)"
        echo "Will not attempt to start"
        exit 1
      fi
      /usr/bin/icecast -b -c $cfgfile
      sleep 2 #icecast might take a few seconds to write the pidfile
      echo "Started icecast server, pid = $(cat $pidfile)"
      ;;
    stop) 
      if [ -f $pidfile ]; then
        p=$(cat $pidfile)
        echo "Stopping icecast server, pid = $p"
        kill -TERM $p
      else 
        echo "Pid file $pidfile not found"
      fi
      ;;
    status)
      if [ -f $pidfile ]; then
        echo "Icecast server running with pid $(cat $pidfile)"
        ps auxwww | grep $(cat $pidfile)
      else
        echo "Icecast not running (well, $pidfile is not found)"
      fi
      ;;
    restart)
      if [ -f $pidfile ]; then 
        $0 stop   
        echo "Waiting for icecast to stop"
        sleep 3
      fi
      $0 start
      ;; 
    *) 
      echo $usage 
      exit 1
      ;;
  esac
 
  exit 0

The script in action!

icecast@kuiper:~> bin/icecast.sh start
Starting icecast2
Detaching from the console
Started icecast server, pid = 21769

icecast@kuiper:~> bin/icecast.sh status
Icecast server running with pid 21791
icecast  21791  0.0  0.1  31720  1628 pts/0    Sl   09:58   0:00 /usr/bin/icecast -b -c /home/icecast/etc/icecast.xml
  
icecast@kuiper:~> bin/icecast.sh restart
Stopping icecast server, pid = 21791
Waiting for icecast to stop
Starting icecast2
Detaching from the console
Started icecast server, pid = 21852
  
icecast@kuiper:~> bin/icecast.sh stop
Stopping icecast server, pid = 21852

Icecast running

Now on another machine I can point my web browser at http://kuiper:8000 and see the status page for icecast.

Note 1: Small tidbit on aliases

Note: The default page is an alias. In the configuration file you'll see:

         <alias source="/" dest="/status.xsl"/>

This causes icecast to display status.xsl for the the "root" page.

Note 2: No images? check fileserv

Note: If the page comes out without images, you made have the setting

         <fileserv>0</fileserver>

         <fileserv>1</fileserver>

I can bring the audio files to the server. The audio server has a configuration file, and I can start and stop it.

Sending data to the Icecast server

At this point I need to send information to the streaming server (send it a feed). There are several packages that can do this darkice, liveice, and the one I am using for this setup: ices.

ices requires a configuration file (and generally distributions supply them with the binary package). For this configuration I use the ices-playlist.xml, placing it in the /home/icecast/etc directory as /home/icecast/etc/playlist.xml

Config File: /home/icecast/etc/playlist.xml

  <?xml version="1.0"?>
  <ices>
      
    <background>1</background>
    <logpath>/home/icecast/logs</logpath>
    <logfile>ices.log</logfile>
    <loglevel>4</loglevel>
    <consolelog>0</consolelog>
    <pidfile>/home/icecast/logs/ices.pid</pidfile>
    
    <stream>
        <metadata>
            <name>Kuiper's Home Stream</name>
            <genre>Music I Like</genre>
            <description>Kuiper's Audio Stream</description>
        </metadata>
       
        <input>
            <module>playlist</module>
            <param name="type">basic</param>
            <param name="file">/home/icecast/etc/playlist.txt</param>
            <param name="random">1</param>
            <param name="restart-after-reread">0</param>
            <param name="once">0</param>
        </input>
        
        <instance>
            <hostname>localhost</hostname>
            <port>8000</port>
            <password>PASSWORD</password>
            <mount>/music.ogg</mount>
        
            <reconnectdelay>2</reconnectdelay>
            <reconnectattempts>5</reconnectattempts> 
               
            <maxqueuelength>80</maxqueuelength>
          
            <encode>  
                <nominal-bitrate>128000</nominal-bitrate> 
                <samplerate>44100</samplerate>
                <channels>2</channels>
            </encode>
        </instance>
       
        </stream>
  </ices>

This creates a two channel 128kb stream, /music.ogg, that is sent to the local icecast server. The stream will be made of of the files in /home/icecast/etc/playlist.txt played randomly. If the playlist.txt file changes it will be re-read but not started over. ices will background itself, creating a pid file (/home/icecast/logs/ices.pid) and a log file (/home/icecast/logs/ices.log).

Creating the playlist

To create the playlist, /home/icecast/etc/playlist need to provide a list of audio files to play. You need this to be the full path to the file and have on per line. For example:

...
/home/icecast/Music/Rush/The Spirit Of Radio  Greatest Hits 1974-1987/Rush - 12 - Subdivisions.ogg
/home/icecast/Music/Rush/The Spirit Of Radio  Greatest Hits 1974-1987/Rush - 14 - The Big Money.ogg
/home/icecast/Music/Rush/The Spirit Of Radio  Greatest Hits 1974-1987/Rush - 15 - Force Ten.ogg
/home/icecast/Music/Rush/The Spirit Of Radio  Greatest Hits 1974-1987/Rush - 16 - Time Stand Still.ogg
/home/icecast/Music/Sam Kinison/Have You Seen Me Lately?/Sam Kinison - 05 - Mother Mary's Mystery Date.ogg
/home/icecast/Music/Sam Kinison/Have You Seen Me Lately?/Sam Kinison - 01 - Rock Against Drugs.ogg
...

The easist way to create the file list it to use the find command

Code: find all files in ~/Music directory

find /home/icecast/Music -type f -name '*.ogg' -print > /home/icecast/etc/playlist.txt

Will put all the .ogg files in the playlist. If you want to only use specific files, say only the fifth song from each album

Code: find all the fifth songs in the ~/Music directory

find /home/icecast/Music -type f -name '*.ogg' -print | grep '05' > \ /home/icecast/etc/playlist.txt

Starting and Stopping ices

I have a script much like /home/icecast/bin/icecast.sh but I call it /home/icecast/bin/playlist.sh. I have added a playlist action to generate a playlist of all the files in the ~/Music directory. I called it playlist since this script is going to start send a playlist to the icecast server. If you are running an talk stream, you could easily create the ices config and startup script for 'talk'. If you attempt to start ices and icecast does not appear to be running, icecast.pid is not found, it will attempt to start icecast.

Script: /home/icecast/bin/playlist.sh

usage="$0 {start|stop|status|restart|playlist}"
playlist="/home/icecast/etc/playlist.txt"
pidfile="/home/icecast/logs/ices.pid"
icepidfile="/home/icecast/logs/icecast.pid"
cfgfile="/home/icecast/etc/playlist.xml"
musicdir="/home/icecast/Music"
musicfiles="*.ogg"
rcicecast="/home/icecast/bin/icecast.sh"

case $1 in
  start)
    if [ ! -f $playlist ]; then
      echo "No playlist file, will create it."
      $0 playlist 2>&1 
    fi
    if [ -f $pidfile ]; then
      echo "ices is already running with pid file $(cat $pidfile)"
      echo "Will not attempt to start"
      exit 1
    fi
    if [ ! -f $icepidfile ]; then
      echo "Icecast server does not appear to be running"
      echo "I'll start it"
      $rcicecast start 2>&1 > /dev/null
      if [ ! -f $icepidfile ]; then
        echo "Icecast didn't appear to start."
        echo "Not starting, sending data to no where could give"
        echo "me more of a complex."
        exit 1
      fi
    fi
    /usr/bin/ices $cfgfile
    sleep 2
    echo "Started with pid = $(cat $pidfile)"
    ;;
  stop)
    if [ -f $pidfile ]; then 
     p=$(cat $pidfile)
      echo "Stopping pid = $p"
      kill -TERM $p
      rm -f $pidfile
    else 
      echo "Pid file $pidfile not found"
    fi
    ;;
  status)
    if [ -f $pidfile ]; then
      echo "Running with pid $(cat $pidfile)"
      ps auxwww | grep $(cat $pidfile)
    else
      echo "Not running (well, $pidfile is not found)"
    fi
    ;;
  restart)
    if [ -f $pidfile ]; then 
      $0 stop   
      echo "Waiting stop"
      sleep 3
    fi
    $0 start
    ;;  
  playlist)
    find $musicdir -type f -name $musicfiles -print > $playlist
    echo "Playlist files: $(cat $playlist|wc -l)"
    ;;
  *)
    echo $usage
    exit 1
    ;;
  esac
exit 0

The script in action!

icecast@kuiper:~> bin/playlist.sh start
No playlist file, will create it.
Playlist files: 372
Icecast server does not appear to be running
I'll start it
Started with pid = 22462
 
icecast@kuiper:~> bin/playlist.sh status
Running with pid 22462
icecast  22462  4.6  0.3  24152  3380 ?        Sl   12:07   0:02 /usr/bin/ices /home/icecast/etc/playlist.xml

icecast@kuiper:~> bin/playlist.sh stop
Stopping pid = 22462

icecast@kuiper:~> bin/playlist.sh restart
Started with pid = 22486

icecast@kuiper:~> bin/playlist.sh playlist
Playlist files: 372

Checking

There is now a stream. http://kuiper:8000 shows a feed music.ogg. Sending mplayer, xmms or winamp to http://kuiper:8000/music.ogg will play the feed through the computer.

If there is a problem all your log files the log files are in /home/icecast/logs. Between them and Google every problem I had (few) have been easily fixed.

Notes

Do not do this on a publicly accessable server. I do this on my private network. You really don't want to be broadcasting your audio stream to the public. Bandwidth will be the least of your problems. This assumes that you probably don't have the required licenses to the music to broadcast it. You have been warned.

To Do

I really need to do something with the log files. At the very least I should be rotating them. I also plan on running some basic stats on the access log to make sure I am the only once access the stream.

Icecast_at_home (last edited 2009-11-12 16:36:28 by localhost)