Simple time-lapse video with gtreamer and ffmpeg

I have experienced an unexpected spin-off while fooling around with GStreamer and my Logitech QuickCam Vision Pro 9000 webcam: A simple and easy way to autonomously capture and render time-lapse videos.

One of the advantages of webcams compared to other digital still and video cameras is that it can be controlled from a computer and the captured frames are transfered from the camera to the computer in real-time using the USB interface. This is pretty much the definition of a webcam and this feature is indeed very convenient for capturing time-lapse videos. Unfortunately, the image quality of webcams has not been anywhere near good enough to make nice looking time-lapse videos but this has changed over the last few years and is continuously improving. The results presented in this article are captured using my Logitech QuickCam Vision Pro 9000 – one of the greatest UVC cameras out there.

Single Frame Capture

Creating time-lapse videos is really easy if you have the right tools. You just capture an image at regular intervals and render the captured frames into a motion picture. The time-lapse factor is easily calculated from the capture interval and the frame rate of the rendered video.

We can save the video from the camera to single frames using the multifilesink element. The following pipeline will capture the frames at 5 fps (the lowest rate for my camera), add the current date, time and video time, convert the frame rate to 1 fps using videorate and save the stream to PNG files:

gst-launch -e v4l2src ! video/x-raw-yuv,format=\(fourcc\)YUY2,width=1280,height=720,framerate=5/1 ! ffmpegcolorspace ! \
timeoverlay halign=right valign=bottom ! clockoverlay halign=left valign=bottom time-format="%Y/%m/%d %H:%M:%S" ! \
videorate ! video/x-raw-rgb,framerate=1/1 ! ffmpegcolorspace ! pngenc snapshot=false ! multifilesink location="frame%05d.png"

It was a quick hack and I could probably have avoided using the ffmpegcolorspace element twice – it’s left as an exercise. Note the snapshot=false in the pipeline, if it is set to true the pngenc element will emit an EOS (end of stream) signal after the first frame and the pipeline will stop. This is very useful if you only want to take a single snapshot.

To convert the PNG files into a video I use ffmpeg. The following command will read the PNG files treating it as a motion picture with frame rate 100 fps and render it to an MP4 video with frame rate 50 fps together with an audio track:

ffmpeg -i timelapse.mp3 -r 100 -i img/frame%05d.png -sameq -r 50 -ab 320k timelapse.mp4


Watch video on YouTube.

Video Capture

If you for some reason can not capture to individual frames but to a video, you can still transform it to a time-lapse video by extracting the frames from the recorded video:

ffmpeg -i webcam.ogg -r 1 -sameq -f image2 frame%05d.png

then convert back to a video using the same command line as presented before. Ideally we could have avoided this step and convert directly using ffmpeg by forcing and input frame rate. Unfortunately, forcing input frame rate in ffmpeg only works for raw files.

Surveillance Camera

I actually arrived at the time-lapse topic while trying to implement a simple “surveillance camera” pipeline using GStreamer. A surveillance camera functionality in this respect is that the captured frames are displayed on the screen and saved to a file at the same time. This is very easy to accomplish in GStreamer by using the tee element, which provide a 1:N pipe fitting. The following pipeline will capture the frames from the webcam, add the clock, show the result on the screen and save it to a 1 fps theora video file:

gst-launch -e v4l2src ! video/x-raw-yuv,format=\(fourcc\)YUY2,width=1280,height=720,framerate=5/1 ! \
ffmpegcolorspace ! timeoverlay halign=right valign=top ! clockoverlay halign=left valign=top time-format="%Y/%m/%d %H:%M:%S" ! \
tee name="splitter" ! queue ! xvimagesink sync=false splitter. ! queue ! videorate ! video/x-raw-yuv,framerate=1/1 ! \
heoraenc bitrate=256 ! oggmux ! filesink location=webcam.ogg

That’s it! Time-lapse and surveillance camera without any fancy or expensive GUI application, just a good old terminal and free software.

Keeping an eye on my neighbours ;-)