How to speed up a video (make a time lapse) using gstreamer?

199 Views Asked by At

I'm looking to take a video of say 1 minute in length, and speed it up so that it is only say 10 seconds long (x6). I don't want to just change the display rate, I'd like to actually drop 5 out of 6 frames in this example to reduce the size and the length of the video.

How can I achieve this using the gstreamer command line?

I've tried using the videorate filter:

gst-launch-1.0 filesrc location=in.mp4 ! qtdemux name=demux demux.video_0 \
! queue ! h264parse ! avdec_h264 ! videoconvert ! videorate 
! video/x-raw,framerate=180/1 ! x264enc ! mp4mux ! filesink location=output.mp4

but no matter what parameters I pass, although frames are dropped, the length of the video stays the same.

2

There are 2 best solutions below

6
wmcelderry On BEST ANSWER

Use the rate parameter to videorate.

Here's your pipeline updated:

gst-launch-1.0 filesrc location=in.mp4 ! qtdemux name=demux demux.video_0 \
! queue ! h264parse ! avdec_h264 ! videoconvert ! \
\
videorate rate=6 \
\
! video/x-raw,framerate=180/1 ! x264enc ! mp4mux ! filesink location=output.mp4

I think you want to reduce the frame rate at the same time:

gst-launch-1.0 filesrc location=in.mp4 ! qtdemux name=demux demux.video_0 \
! queue ! h264parse ! avdec_h264 ! videoconvert ! \
\
videorate rate=6 \
! video/x-raw,framerate=30/1 ! \
\
x264enc ! mp4mux ! filesink location=output.mp4

(I asked someone this question on the mailing list a few months back. Thanks should really go to them!)

0
SeB On

Create a 1 minute sample 320x240@30 video for testing with:

gst-launch-1.0 videotestsrc pattern=ball num-buffers=1800 ! video/x-raw,format=NV12,width=320,height=240,framerate=30/1 ! x264enc ! h264parse ! qtmux ! filesink location=test_h264.mp4

This workaround involves a first command launching a pipeline decoding to I420 raw video and sending to stdout, and another gstreamer command launching a pipeline reading raw video from stdin at 180 fps, then using videorate for dropping 5 frames out of 6 back to 30 fps, then encoding into H264 and put into mp4 container:

gst-launch-1.0 -q filesrc location=test_h264.mp4 ! qtdemux ! h264parse ! avdec_h264 ! videoconvert ! video/x-raw,format=I420,width=320,height=240,framerate=30/1 ! fdsink \
| gst-launch-1.0 fdsrc ! videoparse format=i420 width=320 height=240 framerate=180 ! video/x-raw,format=I420,width=320,height=240,framerate=180/1 ! videorate ! video/x-raw,format=I420,framerate=30/1 ! x264enc ! h264parse ! 'video/x-h264, stream-format=(string)avc, alignment=(string)au, level=(string)2, profile=(string)high, width=(int)320, height=(int)240, framerate=(fraction)30/1' ! qtmux ! filesink location=testOut.mp4

# Check video details
gst-discoverer-1.0 -v testOut.mp4

# Check sizes:
ls -l test*.mp4

# Play it
gst-play-1.0 testOut.mp4