Aaron Swartz
How to Do Stuff

How to Do Live Streaming

Hey, kids! Today we’re going to learn how to do audio streaming using only standard command-line tools. That’s right, you’ll never have to muck with any of those large monolithic lets-invent-a-standard products again!


We have to start by recording. (Of course, if you’re streaming a pre-recorded file, you can skip this step.) esdrec, part of the esound package, grabs the sound input and spits it out on the command line. (esd, the esound daemon, can be a little fussy, so you might have to killall esd and start esd in another window a couple times to get it to work.)

Then we can pass the sound to our favorite encoder. If you want something popular, lame does a decent job of encoding to MP3. If you’re doing music, you might want to use Ogg Vorbis, here oggenc will work just fine. For voice, speex (and speexenc) works pretty nicely.

If you want to stream more than one format, feel free to set up additional sound pipes; esdrec can be run as many times as necessary.

Finally, save the output to a file.

When you’re done, you should have something that looks like:

esdrec | lame - - > archive.mp3

If the recording machine is different from the server, you’ll need something a little more complicated. Instead of saving to a file, you’ll want to pipe it thru ssh to a file on the server. (Depending on your situation, you might even want to pipe the raw stream to the server and do the compression there.) It’ll look like this:

esdrec | lame - - | ssh me@myserver sh -c "cat >> archive.mp3"

(The MP3 format is pretty forgiving, so if you get disconnected just run this command again and keep appending. Everything should work fine, although you’ll probably get a little skip where the connection cut out.)

The Server


Now let’s set up the server. If you just want to stream to yourself and other people with accounts on your server, you can use ssh. On the client, call:

ssh me@myserver [command here]

(We’ll cover the possible commands a little later.)

If you want to publish the stream, you probably want the ucspi-tcp package, which will broadcast the stream on a specific port, say 9940:

tcpserver 0 9940 [command here]

(0 is the IP to run it on, a special case meaning ‘the default IP’.) If you’re an encryption geek, you can use ucspi-ssl and sslserver instead. (Run them the same way, though.)


Now to discuss which [command here] to use. If you want the stream to start from the beginning, simply use cat, as in cat archive.mp3. If you want the stream to be pretty much live, you can use tail -f archive.mp3 to provide a small buffer and then stream the file live. You might want to provide both, so that listeners can choose.


So now you’ve got the stream being served, how do you play it?


If you’re using tcpserver or sslserver then you’ll need mconnect and sslconnect, respectively, on the client. Run them like so:

mconnect myserver 9940


Now to play the stream, just send it thru a decoder and player, like mpg123 for MP3s or speexdec for speex. (On a Mac, you might need a slightly more complicated system, piping speexdec to esdplay.)


So to wrap it all up, on the recoding machine, you’ve got:

esdrec | lame - - | ssh me@myserver sh -c "cat >> archive.mp3"

and on myserver there’s:

tcpserver 0 9940 tail -f archive.mp3

and on the client:

mconnect myserver 9940 | mpg123 -

Pretty simple, eh? When you’re done, just copy the resulting archive file over to a web server (or distribute it using BitTorrent) so people can listen to the event after it ends.