Here's a fairly straightforward example of reading off a web cam using OpenCV's python bindings:
'''capture.py'''
import cv, sys
cap = cv.CaptureFromCAM(0) # 0 is for /dev/video0
while True :
if not cv.GrabFrame(cap) : break
frame = cv.RetrieveFrame(cap)
sys.stdout.write( frame.tostring() )
Now I want to pipe the output to ffmpeg as in:
$ python capture.py | ffmpeg -f image2pipe -pix_fmt bgr8 -i - -s 640x480 foo.avi
Sadly, I can't get the ffmpeg magic incantation quite right and it fails with
libavutil 50.15. 1 / 50.15. 1 libavcodec 52.72. 2 / 52.72. 2 libavformat 52.64. 2 / 52.64. 2 libavdevice 52. 2. 0 / 52. 2. 0 libavfilter 1.19. 0 / 1.19. 0 libswscale 0.11. 0 / 0.11. 0 libpostproc 51. 2. 0 / 51. 2. 0 Output #0, avi, to 'out.avi': Stream #0.0: Video: flv, yuv420p, 640x480, q=2-31, 19660 kb/s, 90k tbn, 30 tbc [image2pipe @ 0x1508640]max_analyze_duration reached [image2pipe @ 0x1508640]Estimating duration from bitrate, this may be inaccurate Input #0, image2pipe, from 'pipe:': Duration: N/A, bitrate: N/A Stream #0.0: Video: 0x0000, bgr8, 25 fps, 25 tbr, 25 tbn, 25 tbc swScaler: 0x0 -> 640x480 is invalid scaling dimension
- The captured frames are definitely 640x480.
- I'm pretty sure the pixel order for the OpenCV image type (IplImage) is GBR, one byte per channel. At least, that's what seems to be coming off the camera.
I'm no ffmpeg guru. Has anyone done this successfully?
Took a bunch of fiddling but I figured it out using the FFmpeg rawvideo demuxer:
Since there is no header in raw video specifying the assumed video parameters, the user must specify them in order to be able to decode the data correctly:
-framerate
Set input video frame rate. Default value is 25.-pixel_format
Set the input video pixel format. Default value is yuv420p.-video_size
Set the input video size. There is no default, so this value must be specified explicitly.And here's a little something extra for the power users. Same thing but using VLC to stream the live output to the web, Flash format:
Edit: Create a webm stream using ffmpeg and ffserver
Took me an hour to figure out that by default, windows pipes are not binary. This causes some bytes (specifically newlines) to be modified/omitted, and the resulting video is slowly shifting because the frame size is not constant.
To work this around, the modified python file:
To test if piping the raw video is successful, use ffplay. Make sure you specify a higher framerate than what is coming from the pipe, otherwise the video will start to lag
Not sure if this is Mac OS-specific, or python3-specific, but I needed to cast the frame to a string in order for this to work for me, like so: