Playing with videos

A cheatsheet on how to merge/convert timelapse videos from iPhone:

First, I tried to use images and .mov videos:

# Convert images to mov. Requirements: imagemagick and ffmpeg
$ for f in *.HEIC; do magick $f -quality 100% $f.jpg; done 
# The '-t 2' means the video vill have 2 secs
$ for f in *.jpg; do ffmpeg -loop 1 -i $f -c:v libx264 -t 2 -pix_fmt yuv420p $f.MOV; done 

Creating one single file, made of multiple videos:

$ for f in *MOV; do echo "file '$f'" >> mylist.txt; done
$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy

However it fails with:

[mov @ 0x123f05ba0] Non-monotonous DTS in output stream 0:0; previous: 15029353, current: 2308768; changing to 15029354. This may result in incorrect timestamps in the output file.

According to SO, it’s related to the different configurations/formats of your input files, like fps (link to answer). After some tests, 30fps seems a good number:

$ rm
$ for f in *MOV; do ffmpeg -y -i $f -vf "setpts=1.25*PTS" -r 30 std_$f ; done
$ rm mylist.txt ; for f in std*MOV; do echo "file '$f'" >> mylist.txt; done
$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy

Images broke the video because of the different resolution, 3024x4032 vs 1080x1920. Hence a new param is needed: -vf scale=1080x1920

$ for f in *.jpg; do ffmpeg -loop 1 -i $f -c:v libx264 -t 1 -pix_fmt yuv420p -vf scale=1080x1920 $f.MOV; done 

At the end, the images doesn’t feel so “smooth” so I delete them. Now I want to have short videos or remove parts of them.

To check duration of each video:

$ for f in *.MOV; do echo -n $f ' ' ; ffprobe -i $f -show_format -v quiet | grep duration; done

And to cut parts of the video

# -ss 2 starts after 2 seconds
# -t 4 copy the next 4 seconds
ffmpeg -ss 2 -i "IMG_3930.MOV" -t 4 -c copy IMG_3930_NEW.MOV

and voilá: