Streaming KEXP with Ruby 2

Posted by Aaron Patterson on July 23, 2007

A while back, I ported JustePort from C# to Ruby so that I could play music on my AirportExpress. The result was a library called raop-client. Unfortunately, after writing that, I found that there were no libraries in Ruby to decode MP3s. So I wrote a wrapper around Lame called icanhasaudio. Right now, it only lets you decode MP3s, but I plan on adding new features soon.

So, I decided to write a little program that will stream music from KEXP to my Airport Express.

require 'rubygems'
require 'raop'
require 'icanhasaudio'
require 'socket'

rd, wr = IO.pipe

decoder = Thread.new(rd, wr) { |read, write|
  reader = Audio::MPEG::Decoder.new
  socket = TCPSocket.new('kexp-mp3-128k.cac.washington.edu', '8000')
  socket.puts("GET / HTTP/1.0\r\n\r\n")
  until(socket.readline == "\r\n"); end
  reader.decode(socket, write);
  write.close
}

sleep 2

raop = Net::RAOP::Client.new('192.168.1.173')
raop.connect
raop.play rd
raop.disconnect
rd.close

decoder.join

I’ll try to explain a little how this works. First I open a pipe which will be used to buffer my decoded mp3. The pipe is passed in to a new thread where my poor mans shoutcast client hooks up to KEXP and starts decoding the mp3 into the pipe.

Meanwhile the main thread waits a couple seconds to make sure there is data in the buffer, connects to the Airport Express, then starts streaming the data from the pipe.

Stream music to your Airport Express with Ruby!

Posted by Aaron Patterson on June 14, 2007

I just released raop-client which lets you stream music to your Airport Express with ruby.

Just install the gem:

gem install raop-client
[/sourcecode]

Here is a sample program which takes decoded input from stdin:

require 'raop-client'

raop = Net::RAOP::Client.new(ARGV[0])
raop.connect
raop.play $stdin
raop.disconnect

Just use the program like this:

% lame --decode -q some_song.mp3 - | ruby streamer.rb 192.168.1.173
[/sourcecode]

You'll have to supply your own mp3 and Airport Express IP address. Also, raop-client currently doesn't decode music, so you'll have to decode the music yourself.