streaming

Transcoding HTTP mp3 streaming proxy in bash

Here’s how to make a proxy for streaming mp3s. It transcodes on-the-fly to 64kpbs MP3 using lame. When transcoding is finished, it calls the ./posthandler.sh script, which can either just delete the file, or potentially archive it so you don’t need to transcode it again.

  1. #!/bin/bash
  2. read method url version
  3.  
  4. method="${method%$CR}"
  5. url="${url%$CR}"
  6. version="${version%$CR}"
  7.  
  8. echo -ne "HTTP/1.0 200 OK\r\nContent-type: audio/mpeg\r\n\r\n"
  9.  
  10. BR=64 #birate to transcode to.
  11. PIPE="/tmp/$$.pipe"
  12. mkfifo "$PIPE"
  13.  
  14. OUTFILE="./tmp.$$.$BR.mp3"
  15. rm $OUTFILE
  16. url=`echo "$url" | sed ’s/\///’`
  17. echo "** GET $url" >&2
  18.  
  19. nohup lynxsource "$url" \
  20.     | (lame –preset cbr $BR –mp3input – - 2>/dev/null \
  21.       && (echo "** Finished transcoding $url" >&2 ; \
  22.           ./posthandler.sh "$OUTFILE"&))\
  23.     | tee -i "$PIPE" > $OUTFILE &
  24.  
  25. cat < $PIPE
  26. rm $PIPE


One interesting limitation seems to be the buffer size of a fifo pipe in linux. Even though the transcoding step is pretty quick, if a client is connected the transcoding only manages to fill the pipe a couple of hundred k ahead of what is being read.

The -i flag to `tee` means it ignores interrupts, and will finish transcoding the file and call the posthandler even if the client disconnects.

Run is like this:

while [ 1 ]; do nc -vlp 8080 -c './transstreamer.sh' ; done

Then hit up a url of your choice using your awesome new proxy:

mpg321 "http://localhost:8080/http://freedownloads.last.fm/download/105468518/Letters%2BFrom%2BThe%2BBoatman.mp3"

Not the most scalable solution, but a mildly amusing quick hack.

Tags: , , ,

Monday, September 29th, 2008 hacks, programming No Comments