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 0The 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>
- instead of
<fileserv>1</fileserver>
- If fileserv is set to 0, icecast will not send images files out and it will not allow static audio files to be servered.
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 0The 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.
