Watch Live Video of Earth on your Raspberry Pi

Posted by
on under

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 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 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 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:

while true
    livestreamer mobile_480p --player omxplayer --fifo --player-args "--win \"0 0 1600 1200\" {filename}"

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!

Become a Patron!

Hello, and thank you for visiting my blog! If you enjoyed this article, please consider supporting my work on this blog on Patreon!

  • #26 Samir said

    This is awesome! Thanks for sharing this info. I followed the instructions but my omxplayer is closing immediately after it starts. This has been happening for a few hours. Can you tell if this is a temporary issue that will go away or an issue with my setup? I simply get the message "[cli][info] Player closed" right after the line "Starting player: omxplayer" Any help would be appreciated! We are looking forward to being able to watch the stream.

  • #27 Miguel Grinberg said

    @Samir: sometimes the stream is not available. You can always check if it is online on your web browser, just go to:

  • #28 Viliam said

    I've found another stream that has probably better availability. It is from project.

    The chunks have to be grabbed from:
    Then the chunk link will look like:

  • #29 sarah said

    Thank you for sharing this project, I am just starting out with Raspberry pi and this has worked well for me but starting Oct.7 all I saw was a blank screen and now it is telling me..
    [warning} python-librtmp is not installed
    I tried to install using Sudo pip install python-librtmp, but it fails with error code 1.
    Any ideas what is going on or how I can stream this on my Pi again?

  • #30 Martin said

    Just adding some extra help since I failed to follow the commands listed by Miguel the first time.
    (I have a tendency to copy-paste without checking...)
    Main program:
    sudo pip install livestreamer
    To get HD streaming:
    sudo apt-get install librtmp-dev
    sudo apt-get install libffi-dev
    sudo pip install cffi
    sudo pip install python-librtmp

    Thanks to Miguel, we wll use this to stream at a local museum.

  • #31 Miguel Grinberg said

    @sarah: you probably need to install librtmp. See comment #30 right above.

  • #32 Joe Miller said

    @miguel Thank you for this post! Once I get it starting from boot (followed the whole tutorial), I am unable to go to desktop with ctrl+c. How do I get to desktop?

  • #33 Miguel Grinberg said

    @Joe: to stop the stream you have to kill the livestreamer and omxplayer processes. To do this, I connect to the Pi from my computer over SSH. A more sophisticated start/stop feature can certainly be built, but it will require some scripting support, which was outside the scope for this article.

  • #34 John said

    Just does not work librtmp wont install tried all the suggested fixes and a rpi3 and rpi2 all updates

  • #35 shadoworld2077 said

    In order to access ustream's HD streams, Livestreamer needs python-librtmp, which also is available using pip. The library needs cffi, so we have to install its dependencies, too. They are python2.7-dev and libffi-dev. python-librtmp needs librtmp-dev.

    sudo apt-get install python2.7-dev libffi-dev librtmp-dev
    After installing those development headers, we can install cffi and python-librtmp.

    sudo pip install cffi
    sudo pip install python-librtmp
    Once that is done, Livestreamer can be installed.

    sudo pip install livestreamer

    <h3>The whole article is here:</h3>
  • #36 Maksim said

    Just wanted to say big thanks for the instructions - very clear and easy to follow, you're a good explainer. :)

  • #37 Hakan said

    Livestreamer is now unmaintained. Use the drop-in replacement with Streamlink, although the format is slightly different. This works for me:

    streamlink --stream-segment-threads 3 --player-continuous-http --errorlog 720p --player omxplayer --fifo --player-args "--live --win \"0 0 1920 1080\" {filename}"

    Note that it has additional requirements from Python. I should have kept some notes...

  • #38 Bob Irving said

    Great work! I'm always getting a 'no streams found on this URL" message, though. Is the ISS out of streaming range for my location? Not sure what that means.

  • #39 Miguel Grinberg said

    @Bob: Not sure, could this be something that your ISP is blocking for some reason?

  • #40 hengst said

    would like to add that for m3u8 streams, you want to add timeout option to 60s because else stream will stop every 30seconds or so.

    so that would be : omxplayer http://whatever.m3u8 --timeout 60

    also you can use omxplayer "http://whatever.url?account=youraccount&whatever=option&file.m3u8" --timeout 60

  • #41 aca said

    Thank you so much. This is exactly what I was looking for and you saved me a bunch of hassle.

  • #42 John said

    Anyone know if there is a direct MJPEG feed for this that will show in a browser window directly? or a transcode of some sort? I'd like to put this on my "dashboard" but it needs URL to direct MJPEG video stream, not ustream site. I've tried the .m3u8 and the popout URLs as well. Thanks!

  • #43 Miguel Grinberg said

    @John: there is no MJPEG stream of this channel to my knowledge.

  • #44 Jörg Baltschun said

    Thank you very much for this ! :-)

    Finally made it, but with little changes:
    "streamlink --player mplayer 360p"
    works way better for my.
    I put it on a raspberry PI A and used the FBAS to send it to a Philips Discoverer TV from the 80´s.
    Some piece of art :-)

Leave a Comment