This blog is less about random things you can do with Raspberry Pi’s and more about the fun and abstract things you can do with GNU/Linux. A combination of this article on the use and abuse of audio pipes and a fresh Raspbmc sparked my curiosity. Could I do the same thing with a DVD over a network?
So to back it up a second, could I just buy a usb dvd drive and make it work directly with the Pi and XBMC? Yes, that is correct. Could one also buy a DVD player or the digital copy and skip the hassle altogether; again yes. But think about the fun you are missing out on.
As of RC5 of Raspbmc, DVD support will work by simply compiling libdvdcss on your PI. For those too lazy to do the google:
sudo apt-get update sudo apt-get install -y bzip2 gcc make wget http://www.videolan.org/pub/libdvdcss/1.2.12/libdvdcss-1.2.12.tar.bz2 bzip2 libdvdcss-1.2.12.tar.bz2 tar -xvf libdvdcss-1.2.12.tar cd libdvdcss-1.2.12 ./configure make && make install && sudo cp /usr/local/lib/libdvdcss* /lib
Then reboot. And you should show ‘Play DVD’.
Stream DVDs from a DVD drive
So I don’t have a usb DVD drive (seriously a usb dvd drive?) but I do have a laptop with a DVD drive. I started by installing libdvdcss and mplayer. My game plan was simple. I would make a fifo file on the laptop, then netcat it over to the Pi, which would write it to another fifo file and then play it with RaspBMC and the Raspberry PI MPEG-2 codex. I added in an application called pv so I could see that the data was actually being transfered
The setup looked like this on the PI (I put the file on a jumpdrive, but you could put it directly on your sd card):
mkfifo /media/LARGEFILES/dvd.mpg sudo apt-get install netcat pv nc -l -p 2345 | pv -b > /media/LARGEFILES/dvd.mpg
These commands set up a file that is ready to pipe data called dvd.mpg and they set up a listening socket on port 2345 that will output the total amount transferred to stdout but pipe the output of the transfer into the fifo file.
Now we have to send some data. The setup on the Laptop looks like this:
mkdir /dvd mkfifo dvd.mpg //start mplayer writing to this fifo file mplayer dvd://1 -dumpstream -dumpfile /dvd/dvd.mpg & cat /dvd/dvd.mpg | pv -b | nc raspbmc.local 2345
On Raspbmc, I navigate to my local fifo file dvd.mpg and hit play and then you start to see the transfer through the pipes. The magic is happening, the mplayer is dumping the video to the local file, cat is sending that file across netcat, where netcat is receiving the data and writing it to the Raspbmc local fifo file and the Raspbmc is rendering the video. Beautiful and crazy at the same time.
When I was first experimenting, I was going wireless to wireless and had some annoying buffering. I did a couple things (regrettably all at the same time) and it fixed the problem so I am not sure what exactly fixed it. First, I plugged the Pi in and took away wireless on that side, then I followed this tutorial on expanding the buffer size of XBMC (not totally sure this did anything), and I increased my socket buffer by different amounts with ‘sudo sysctl -w net.core.rmem_max=5242880’.
Everything was working great but I wasn’t happy yet. It took four steps to start the DVD, not including putting the DVD in the drive or picking the DVD. My initial thought was to cut out a step by using sshfs to remotely mount the dvd.mpg file from the Pi on the Laptop. That turned out to be a bust. I was receiving “Operation not Permitted” error even though the permissions and filesystem types were correct. Next idea was to cat the file over ssh. This would eliminate the step of needing to open a listening socket on the Pi. Through the magic of the internet it worked – I would have mplayer dump to the same fifo file then start ‘ssh [email protected] ” cat – > /media/LARGEFILES/dvd2.mpg”‘.
The Final Streaming Result
Exciting, now I could sit at my desk with my computer and queue up the movie with 3 actions. Still too many. I really wanted to pipe mplayer directly to ssh. After some digging, I found that other people have wanted to do the same thing and have tried several different methods (that of course stopped working in 2009) but I did find someone that suggested the super obvious, make mplayer as quiet as possible and set the file output to /dev/stdout. So far, this final method has worked perfectly.
mplayer dvd://1 -dumpstream -dumpfile /dev/stdout | ssh [email protected] "cat - > /media/LARGEFILES/dvd.mpg"
One command to start my movie! I am done for the night but there is more to this story. I want to see if I can call this command from the Pi when I click an add on so I don’t have to do anything but put the disk in. I also want to check out the “-slave -input file=/fifo” and see if I can control the movie by sending commands back to a fifo file.