2013-10-01T05:45:43Z

How to build and run MJPG-Streamer on the Raspberry Pi

It's been a while since I wrote the article on streaming video from the Raspberry Pi using MJPG-Streamer. Since I published that article I have received several comments and questions regarding issues building MJPG-Streamer, so in this short post I'm giving you revised build instructions.

1. Install build dependencies

The following command installs the three libraries that MJPG-Streamer uses:

$ sudo apt-get install libjpeg8-dev imagemagick libv4l-dev

2. Add missing videodev.h

The videodev.h header file that MJPG-Streamer needs has been replaced with a videodev2.h. To make MJPG-Streamer happy you have to create a symbolic link:

$ sudo ln -s /usr/include/linux/videodev2.h /usr/include/linux/videodev.h

3. Download MJPG-Streamer

The source code for MJPG-Streamer is available at sourceforge.net, but it is tricky to find the direct download link:

$ wget http://sourceforge.net/code-snapshots/svn/m/mj/mjpg-streamer/code/mjpg-streamer-code-182.zip

Note that sometimes the link above fails to work. If that is the case, you can also download from your web browser by opening this page: http://sourceforge.net/p/mjpg-streamer/code/HEAD/tarball.

4. Unzip the MJPG-Streamer source code

The source code download is a compressed zip file. Put the file in your home directory (or a temporary folder, if you prefer) and run the following to extract the files:

$ unzip mjpg-streamer-code-182.zip

5. Build MJPG-Streamer

MJPG-Streamer comes with several plugins, but only a couple of them are needed to stream video according to the method I explained in my previous article. The command below only builds what's needed:

$ cd mjpg-streamer-code-182/mjpg-streamer
$ make mjpg_streamer input_file.so output_http.so

6. Install MJPG-Streamer

I did not discuss installation in the previous article, and that confused many readers. The following commands copy all the needed files into system directories:

$ sudo cp mjpg_streamer /usr/local/bin
$ sudo cp output_http.so input_file.so /usr/local/lib/
$ sudo cp -R www /usr/local/www

7. Start the camera

We are almost there. Now it is time to start the camera module:

$ mkdir /tmp/stream
$ raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &

Of course, you can use different options to raspistill if you like.

8. Start MJPG-Streamer

The camera is now writing images, so all that is left is to start MJPG-Streamer:

LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w /usr/local/www"

9. Watch the Stream!

Now you can connect with your web browser and watch the stream live. If you want to watch from within the same Raspberry Pi you can enter http://localhost:8080 in the browser's address bar. If you want to watch from another computer in your network use http://<IP-address>:8080.

10. Cleanup

After you verify that everything is working you can remove the source code:

$ cd ../../
$ rm -rf mjpg-streamer-182

Conclusion

I hope these instructions clarify all the aspects of setting up the streaming server on the Pi. If you still have questions let me know below!

Miguel

335 comments

  • #251 David Wallin said 2015-07-11T14:06:42Z

    The last line but one gives me a situation where it is constantly saying that it is skipping frames - and it skips every frame (other than the first).

    Any ideas?

  • #252 Miguel Grinberg said 2015-07-16T05:56:41Z

    @David: maybe you need a better power source, some people noticed less or no dropped frames after changing the power supply.

  • #253 Erik said 2015-07-19T11:56:29Z

    Fantastic tutorial! I used it to set up 2 Raspi Cams that stream images of our Makerbot Replicator 2s printing (an early model that doesn't have a webcam attached) so we can check on them remotely. Here's my tutorial on how I set that up here. I made a Python script that runs raspistill and mjpg_streamer from a shell script when you press a putton connected to the GPIO pins. It all works but I'm trying to take it to the next step and automate it so the Python script autostarts on startup and I don't have to log in every time to start it. So far that is successful, the button detects being pressed, but mjpg_streamer does not start--images are saved but not served out via http! Do you think the user has to be logged in for mjpg_streamer to run?

  • #254 Miguel Grinberg said 2015-07-22T06:26:10Z

    @Erik: not sure, but you may want to check if there is any error output, that may give you a clue as to what's happening. Typically the environment with no user logged is different, some environment variables might not be set, as they are set by the login session.

  • #255 Girard said 2015-07-24T03:49:18Z

    I made a previous comment but later got it to work. I wonder if it is possible to make this stream run indefinitely?

  • #256 guiguims said 2015-07-24T07:13:42Z

    Nice tutorial, it actually works for me yesterday with my Logitech C310 but today it doesn't seems to work, here is my problem : When i try to run mjpg-streamer everything works and i don't have any error messages on screen but after that , when i try to see my stream on my address (...*:8080) the interface is showing but there is just a white screen and no images. I tried many format , to change the port , to remove mjpg streamer and install but no changes. After that i tried to set up to YUYV and not MJPEG and it actually works but ... the image is ugly and MJPEG did works before so can you help me find the solution please? (sorry for my english)

  • #257 Fernando Ferreira said 2015-07-24T23:45:04Z

    Hi,

    I have a rasp b rev2 and im using raspberian and a pi camera. I couldnt use your download link so i used this: http://tcpdiag.dl.sourceforge.net/project/mjpg-streamer/mjpg-streamer/Sourcecode/mjpg-streamer-r63.tar.gz When i make the file i get an error in the input_file.so,. I made "make all" but i only get the input_uvc.so. I made the rest of the tutorial and in step 7 i get a series of mmal_ Skipping frame ... to restart at frame .... The stream folder i get images. In step 8 i get an error: ERROR opening V4L interface: No such file or directory. Could you give me a little help?

    Thanks in advance

  • #258 Fernando Ferreira said 2015-07-24T23:51:01Z

    Im sorry, i forgot to mention, in step8 i altered input__file to input_uvc.

    THanks in advance

  • #259 Miguel Grinberg said 2015-07-25T18:14:19Z

    @Girard: you can write a wrapper script around the raspistill command that runs the command again when it exits. That would keep the stream running forever, unlike the example I show above, which has an explicit (yet large) timeout.

  • #260 Miguel Grinberg said 2015-07-25T18:17:07Z

    @guiguims: This tutorial is for the Raspberry Pi camera module. I have never tried other cameras, you may be able to make one work if you have a utility similar to raspistill, but I'm not familiar with any other cameras for the Pi.

  • #261 Miguel Grinberg said 2015-07-25T18:20:43Z

    @Fernando: the skipping frame errors are sometimes caused by an insufficient power supply, or it could also be due to the Pi doing too much stuff. Try closing all other programs and see if that helps. As far as the code, I think you downloaded a different version, not the one I indicate above, so my instructions may not apply. Maybe sourceforge was down at the time, try again with the link I provided, or go to http://sourceforge.net/p/mjpg-streamer/code/HEAD/tarball and download from there.

  • #262 Erik said 2015-07-28T14:58:08Z

    @Miguel, I got the streaming to work automatically on boot. I just had to include the full path to mjpg_streamer.

  • #263 MikeFury said 2015-07-31T20:42:09Z

    Hello Miguel, Great Tutorial! Everything works as described. Quick question, I noticed that once the mmal: frame generation reaches a certain number it simply stops produces frames. Is there any way to loop this command or possibly have it produce frames infinitely?

    Thanks !

    MikeFury

  • #264 Jim said 2015-08-01T20:29:09Z

    excellent job - thanks for the great (and easy!) guide

    I followed each step copy and paste on my raspi and it worked first time. I added both commands to the /etc/rc.local (with a couple of tweaks) as below, so that every time the pi powers up it automatically starts streaming:

    sudo su - pi -c "LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i \"input_file.so -f /tmp/stream -n pic.jpg\" -o \"output_http.so -w /usr/local/www"\" & raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &

    Now trying to find a way to get the pi to upload a file with it's IP address every 5 minutes (I'm on a dynamic ip) and then the target machine use the content of the file to alter the ip address in an iframe reference within a wordpress site post. . . and then it's fully automated :p

  • #265 Miguel Grinberg said 2015-08-02T05:55:32Z

    @MikeFury: create a wrapper script that invokes raspistill in a loop.

  • #266 Jim said 2015-08-02T21:56:30Z

    So, I got it all working sweet :)

    I said in my last post that I was on a dynamic ip, found a silly sloppy way around it, but it works :p

    The problem: I use wordpress hosted on an external VPS to host my website. Used an iframe plugin to display the 'simple_stream.html' within a wordpress page- pointing it at my (port forwarded) PI in my home network. That's fine until my IP gets renewed (happens every few days), then the wordpress iframe is pointing to the wrong ip.

    So. . . I set a cron job on the pi to SCP a txt file with it's current external IP (using: curl http://ipecho.net/plain > ip.txt) to the VPS every minute. I then found the field within the wordpress mysql db which contained the ip address reference and exported an update query to text file. Using sed I search that text file using a monster set of regular expressions, then replace the old ip with the new ip from the scp'd text file. . . then I run that mysql update query text file from the same cron job against the wordpress db. All tested and works perfectly, so I can leave the pi on 24/7 or remotely power it on and not worry about the dynamic IP. . . .sure there must have been a better way to do it though!

    Thanks again for your guide!

  • #267 Mikhail said 2015-08-27T21:34:39Z

    Hi! Could you please help me. After first successful video streaming, I restarted Ras Pi2, and now when I start raspistill I am getting the error: mmal: mmal_vc_component_enable: failed to enable component: ENOSPC mmal: camera component couldn't be enabled mmal: main: Failed to create camera component mmal: Failed to run camera app. Please check for firmware updates

  • #268 Miguel Grinberg said 2015-08-28T07:00:22Z

    @Mikhail: appears to be a hardware problem. The Pi apparently does not recognize the camera. Try connecting it again, maybe the cable is not fully seated in the camera slot.

  • #269 Sean said 2015-08-29T18:10:32Z

    Thank you,,,, WORKED GREAT!!!! now just need to figure out how to increase the FPS

  • #270 gybp said 2015-09-17T16:31:19Z

    if the way i produce pic.jpg is not with instruction"raspistill" but with some DSP code can i still run the stream??? bcuz i just put a random pic in /tmp/stream/ fold and it doesnt work

  • #271 Miguel Grinberg said 2015-09-17T22:56:16Z

    @gybp: As long as your code writes jpegs in the same location, mjpg_streamer is not going to care. If it does not work I would ensure the jpegs you are generating are valid.

  • #272 Robyn said 2015-09-30T11:04:33Z

    Hi Miguel,

    When I run raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 & I just get mmmal: Skipping frame 2 to restart at frame 3 So it doesn't seem to be running in the background even though I have & on the end. So I am unable to run the LD_LIBRARY command. I am not able to Ctrl C to cancel it just continues. Any suggestions

    Thanks Robyn

  • #273 Miguel Grinberg said 2015-10-02T04:48:01Z

    @Robyn: the process is running in the background, but still outputs messages to your terminal. Add the foillowing before the "&" to disable the output to the console:

    /dev/null 2>&1

    To stop a background process you have to use the kill command, you can't stop it with Ctrl-C.

  • #274 Matt said 2015-10-05T20:44:26Z

    Hi Miguel,

    Thank you very much for this tutorial! It is excellent! On the other hand, I am facing an issue. When I try to execute the following command: LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w /usr/local/www"

    I get this issue:

    MJPG Streamer Version.: 2.0 i: Using V4L2 device.: /dev/video0 i: Desired Resolution: 640 x 480 i: Frames Per Second.: 0 i: Format............: MJPEG o: www-folder-path...: /usr/local/www/ o: HTTP TCP port.....: 8080 o: username:password.: disabled o: commands..........: enabled Unable to start capture: Invalid argument i: Error grabbing frames

    Please note that I am running raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 & and all the previous steps were successful. Are you able to help me?

    Kind regards,

    Matt

  • #275 Miguel Grinberg said 2015-10-05T21:23:57Z

    @Matt: not sure what happened, but if you look at the output you pasted above, note how MJPG streamer is trying to grab video frames from /dev/video0. That is wrong, the input_file.so plugin would not do that, it would look for jpg files on disk. It seems you compiled the wrong input plugin.

Leave a Comment