5

I have installed ffmpeg and mjpeg-streamer. The latter reads a .jpg file from /tmp/stream and outputs it via http onto a website, so I can stream whatever is in that folder through a web browser.

I wrote a bash script that continuously captures a frame from the webcam and puts it in /tmp/stream:

while true
do
    ffmpeg -f video4linux2 -i /dev/v4l/by-id/usb-Microsoft_Microsoft_LifeCam_VX-5000-video-index0 -vframes 1 /tmp/stream/pic.jpg
done

This works great, but is very slow (~1 fps). In the hopes of speeding it up, I want to use a single ffmpeg command which continuously updates the .jpg at, let's say 10 fps. What I tried was the following:

ffmpeg -f video4linux2 -r 10 -i /dev/v4l/by-id/usb-Microsoft_Microsoft_LifeCam_VX-5000-video-index0 /tmp/stream/pic.jpg

However this - understandably - results in the error message:

[image2 @ 0x1f6c0c0] Could not get frame filename number 2 from pattern '/tmp/stream/pic.jpg'
av_interleaved_write_frame(): Input/output error

...because the output pattern is bad for a continuous stream of images.

Is it possible to stream to just one jpg with ffmpeg?

Thanks...

Germanunkol
  • 231
  • 1
  • 3
  • 13
  • What exactly are you trying to achieve? Static image from your camera on a web page? – David Jashi Jul 13 '13 at 14:34
  • Yes, but one that is updated a few times a second, so effectively, a stream. This is just a first step - later on I am planning on writing a program that will read the image repeatedly and work with it. – Germanunkol Jul 13 '13 at 14:36
  • Well, that's not how it's done. Couple of questions: 1) what is the format of input stream? 2) How are you going to display video stream to clients? – David Jashi Jul 13 '13 at 14:44
  • I believe the second question is already answered above: mjpeg-streamer is used to put up the website. It automatically reads from /tmp/stream in my setup, and uses any images there. It is a common setup on the raspberry pi, used together with the program "raspistill" for the raspberry camera. However, this latter program does not seem to work with my (non-raspberry) webcam, so I wanted to use ffmpeg instead. Why does the input format matter? I read from the webcam, and that works fine, as stated in my question. All I want is ffmpeg to work continuously instead of calling it multiple times. – Germanunkol Jul 13 '13 at 15:02
  • Well, it's totally up to you, but when I had to deal with MJPEG stream, I did it in a couple of other ways: 1) I used `ffmpeg` to convert it to FLV stream and fed it to `ffserver` 2) For high bandwidth camera (30mb/sec) I had to split MJPEG stream on JFIF signature to separate JPEG files and then assemble them to 1-minute fragments of MP4 files. The thing is, refreshing JPEG on a client side looks terrible and irritating, especially when it's large enough. – David Jashi Jul 13 '13 at 23:32
  • I noticed that mjpeg-streamer can do what I want natively, without using ffmpeg at all (the latter proved to be quite heavy on the raspberry pi). I now use: `./mjpg_streamer -i "input_uvc.so -r 1280×1024 -d /dev/video0 -y" -o "output_http.so -w ./www"` from within the mjpg's directory, which gives me clear output at large framerates...yay! Thanks for all the help. – Germanunkol Jul 18 '13 at 10:56

2 Answers2

4

You can use the -update option:

ffmpeg -y -f v4l2 -i /dev/video0 -update 1 -r 1 output.jpg

From the image2 file muxer documentation:

-update number

If number is nonzero, the filename will always be interpreted as just a
filename, not a pattern, and this file will be continuously overwritten
with new images.
llogan
  • 121,796
  • 28
  • 232
  • 243
  • Using v4l2 gives me the error "Unknow input format: 'v4l2' on my raspberry pi (which seems to be a known issue: [link](http://www.raspberrypi.org/phpBB3/viewtopic.php?t=49530&p=385793)). Using -f video4linux2 instead gives me: `"Unrecognized opetion 'update' Failed to set value '1' for option 'update'` (Similar issue when using avconv). Output of ffmpeg --version: `ffmpeg version 0.8.6-6:0.8.6-1+rpi1` – Germanunkol Jul 18 '13 at 09:03
  • @Germanunkol Your ffmpeg is too old (and you're probably using a fork of FFmpeg which may not have `-update` in it's current code). This is why you need to include the complete ffmpeg console outputs with your commands. – llogan Jul 18 '13 at 17:21
  • `ffmpeg -version` gives: `ffmpeg version 0.8.6-6:0.8.6-0ubuntu0.12.10.1, Copyright (c) 2000-2013 the Libav developers built on Apr 2 2013 17:02:16 with gcc 4.7.2 ffmpeg 0.8.6-6:0.8.6-0ubuntu0.12.10.1 libavutil 51. 22. 1 / 51. 22. 1 libavcodec 53. 35. 0 / 53. 35. 0 libavformat 53. 21. 1 / 53. 21. 1 libavdevice 53. 2. 0 / 53. 2. 0 libavfilter 2. 15. 0 / 2. 15. 0 libswscale 2. 1. 0 / 2. 1. 0 libpostproc 52. 0. 0 / 52. 0. 0 ` – Germanunkol Jul 26 '13 at 07:52
2

It is possible to achieve what I wanted by using:

./mjpg_streamer -i "input_uvc.so -r 1280×1024 -d /dev/video0 -y" -o "output_http.so -p 8080 -w ./www"

...from within the mjpg_streamer's directory. It will do all the nasty work for you by displaying the stream in the browser when using the address: http://{IP-OF-THE-SERVER}:8080/ It's also light-weight enough to run on a Raspberry Pi.

Here is a good tutorial for setting it up.

Thanks for the help!

Germanunkol
  • 231
  • 1
  • 3
  • 13