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 output.mov
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 output.mov $ 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 output.mov
Images broke the video because of the different resolution, 3024x4032 vs 1080x1920. Hence a new param is needed:
$ 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