A few weeks ago NASA started streaming live video of Earth from cameras installed aboard the International Space Station (ISS), and some of the views are nothing short of breathtaking. If you haven't seen this stream yet, then stop reading and go watch it now. Keep in mind that you have a 50% chance of catching the dark part of the planet, so if all you find is an all black image then try again a little later. You can always check isstracker.com to find out over which region the ISS is over and if it is day or night there.

I thought it would be a cool idea to have this stream running constantly on a screen by my desk. Something I can keep an eye on while I work, so that I can catch the most interesting views without having to have it constantly taking space on my main computer's screens.

In this short article I'm going to show you how to play the ISS live stream on your Raspberry Pi.

Playing Video Streams on the Raspberry Pi

The Raspberry Pi is well equipped for the task of playing video streams because it can decode the video in the GPU, so the amount of work done in the CPU is minimal. The Pi's GPU comes with a H.264 video decoder from the factory. This is the format most web based video streams use, including the ISS stream. As a side note, an MPEG-2 decoder is also available, but a license needs to be purchased from the Raspberry Pi Foundation to use it.

The ISS live stream is provided by UStream. The stream is delivered in short segments, presented to the player in a constantly changing playlist, using a format called HLS. But UStream does not openly advertise how to access these playlists, instead they expect clients to embed a UStream web based video player applet based on Flash or HTML5, where all the HLS processing is done.

Unfortunately playing this type of stream in a browser on the Raspberry Pi is kind of complicated, as you need a modern browser that can run their Flash/HTML5 video player, and on top of that you need the player to be specifically designed to use the hardware accelerated decoder in the Pi. So in my view, using a web browser for this project is not an option.

I have found that omxplayer is a pretty good command line player, specifically created for the Pi and with support for hardware decoding. To use omxplayer you do not even need to be running the graphical environment, the video plays as an overlay, even on top of the console. Recent releases of Raspbian include omxplayer, so chances are you already have it installed. If not, you can always install it:

$ sudo apt-get install omxplayer

But how do we connect the HLS stream from UStream to omxplayer?

The livestreamer utility helps simplify the process of downloading video from UStream and other video stream providers. This tool does all the processing and converts the stream to a standard video file that can be sent to a player like omxplayer. To install livestreamer you have to run the following commands:

$ sudo apt-get install python-pip $ sudo pip install livestreamer

For those of you that know their way around Python, you should know that livestreamer is written in that language, and that it can be installed in a virtual environment if you prefer to keep it separate from your system Python interpreter.

The command that combines livestream and omxplayer and starts the ISS stream in full screen mode is as follows:

$ livestreamer http://ustream.tv/channel/iss-hdev-payload mobile_480p --player omxplayer --fifo

The first argument is the URL for the streaming channel. This is followed by "mobile_480p" which tells livestreamer to select one of the available resolutions for the given channel (the list of choices are printed to the console). Livestreamer by default will try to launch the stream on VLC, so we use --player to tell it to use omxplayer instead. Finally, the --fifo argument selects the use of a named pipe as a mechanism for livestreamer to communicate with omxplayer.

If you try the above command you may find that everything works great, so you are good to go. In my case, however, I've found that the playback window did not cover the entire screen. The reason is that omxplayer by default plays at 1920x1080, but I have my console running at 1600x1200. This is easy to fix using the --win argument:

$ livestreamer http://ustream.tv/channel/iss-hdev-payload mobile_480p --player omxplayer --fifo \ > --player-args "--win \"0 0 1600 1200\" {filename}"

If you are running under a different resolution you may need to play with the numbers given to --win to make the video fill your screen.

Final Touches

If you try this you will find that from time to time the stream halts and you are sent back to the command line. This is probably some sort of interruption to the stream that causes omxplayer to error. But whatever causes this resolves pretty fast, because the video is back up a couple of seconds later after restarting the process.

To avoid having to manually restart the process each time it stops, a wrapper bash script can be created to do this for us:

#!/bin/bash while true do livestreamer http://ustream.tv/channel/iss-hdev-payload mobile_480p --player omxplayer --fifo --player-args "--win \"0 0 1600 1200\" {filename}" done

If you put the above in a file named iss-streamer you can make it executable and run it as a command:

$ chmod +x iss-streamer $ ./iss-streamer

And now the stream will restart itself whenever there is an interruption. Note that when you do want to stop the stream, you will have to hold the Ctrl+C for a couple of seconds to also break out of the while loop in the bash script.

I thought it would also be useful to have the stream autostart when the Pi is plugged in, so that it can run completely unattended. This is achieved by adding the command to the /etc/rc.local file, right before the exit 0 line:

# start the ISS video stream sudo -u pi /home/pi/iss/iss-streamer >/dev/null 2>&1 &

There are a few details that were required to make the stream work. First of all, the /etc/rc.local script runs as the root user, so I use sudo to downgrade the user to the regular "pi" user as a safety measure. The command needs to run in the background, so I added & at the end. And because it runs in the background, I also suppressed all the output from stdout and stderr. Finally, since the PATH environment variable is not set when the command runs, I specified the full path to the iss-streamer script.

The End

I hope you find this entertaining, fascinating and mind blowing as I do. Obviously this technique can be used with many other internet streams, so feel free to experiment!

If you have any tips to improve this idea be sure to let me know in the comments below!