Streaming KEXP with Ruby
2007-07-23 @ 09:23A 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.