Create time lapse video from images: Difference between revisions

From WickyWiki
Created page with "Category:Ubuntu Category:Ubuntu Images Category:Ubuntu Video Category:201903 Install ffmpeg: <syntaxhighlight lang=bash> sudo apt install ffmpeg </syntaxhig..."
 
mNo edit summary
 
(24 intermediate revisions by the same user not shown)
Line 3: Line 3:
[[Category:Ubuntu Video]]
[[Category:Ubuntu Video]]
[[Category:201903]]
[[Category:201903]]
= Create timelapse =


Install ffmpeg:
Install ffmpeg:
Line 10: Line 12:
</syntaxhighlight>
</syntaxhighlight>


Create timelapse file-index
Create timelapse indexfile:
 
<syntaxhighlight lang=bash>
find "$HOME/Pictures" -iname "*.jpg" -type f | sort | sed "s/\(.*\)/file '\1'/g"  > "$HOME/timelapse_files.txt"
</syntaxhighlight>
 
Create the video:
 
<syntaxhighlight lang=bash>
ffmpeg -f concat -safe 0 -i "$HOME/timelapse_files.txt" -r 25 -vcodec libx264 -crf 22 ""$HOME/timelapse.mp4"
</syntaxhighlight>
 
= Playback speed and Music =
 
The original video-length is the length when we create the video without 'setpts=~'. The images will be read as a stream of 25 pictures per second (input framerate=25). For example:
 
  2500 pictures -> 2500/25 = 100 seconds of video = 1:40 minutes
 
Lets say you have some music and want to speed-up the video to match the music length:
 
  Music length 2:30 minutes
 
Then use the following video filter to shorten the video by increasing the playback speed:
 
  setpts=(PTS-STARTPTS) * <music-length> / <video-length>
 
You can add this option as a simple formula:
 
  setpts=(PTS-STARTPTS)*(2*60+30)/(2500/25)
 
= Cropping =
 
My source is a set of pictures of size 1280 x 1024, by cropping this to 1280:800 I will have a 16:10 aspect ratio (which is a better fit for my screen).
 
  1280 * 10/160 = 800
 
I want to keep the bottom part of the picture so I need to move down by:
 
  1024 - 800 = 224
 
This results in the video filter option:
 
  crop=1280:800:0:224
 
= The complete example =
 
Settings:
 
<syntaxhighlight lang=bash>
projdir="$HOME/Downloads/"
picsdir="2019-03-24"
mp3file="my music.mp3"
</syntaxhighlight>
 
Create the pictures index file:
 
<syntaxhighlight lang=bash>
find "${projdir}/${picsdir}" -iname "*.jpg" -type f | sort | sed "s/\(.*\)/file '\1'/g"  > "${projdir}/files.txt"
</syntaxhighlight>


Format:
Count the number of pictures:


  file '/full/path/to/file1.jpg'
<syntaxhighlight lang=bash>
  file '/full/path/to/file2.jpg'
numpics=$( wc -l "${projdir}/files.txt" | cut -d' ' -f1 )
  ...
</syntaxhighlight>


Create:
Extract and calculate the length of the music in seconds:


<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
sourcedir=$HOME/Pictures/timelapse
durationsec=$( ffmpeg -i "${projdir}/${mp3file}" 2>&1 | grep Duration | sed 's/.*\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\).[0-9]\{2\},.*/\1*3600+\2*60+\3/g' )
find "${sourcedir}" -iname "*.jpg" -type f | sort | sed "s/\(.*\)/file '\1'/g"  > "${sourcedir}/../files.txt"
</syntaxhighlight>
</syntaxhighlight>


Create video:
Check the video length (and speed) calculation:


<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
ffmpeg -f concat -safe 0 -i "${sourcedir}/../files.txt" -r 25 -vcodec libx264 -crf 22 "${sourcedir}/../out.mp4"
echo "Video length calculation : (PTS-STARTPTS) * ( ${durationsec} ) / ( ${numpics} / 25 )"
</syntaxhighlight>
</syntaxhighlight>
Encode:
<syntaxhighlight lang=bash>
ffmpeg -f concat -safe 0 -i "${projdir}/files.txt" -i "${projdir}/${mp3file}" -filter:v "setpts=(PTS-STARTPTS)*(${durationsec})/(${numpics}/25), crop=1280:800:0:224" -r 25 -vcodec libx264 -crf 22 "${projdir}/${picsdir} timelapse (${mp3file}).mp4"
</syntaxhighlight>
Looking for some music to add? You might want to take a look here:
* https://www.jamendo.com/start
* https://cctrax.com/
* https://freemusicarchive.org/genre/Ambient/?sort=track_interest
= Overview of the used options =
Input index-file 'files.txt':
  -f concat -safe 0 -i "files.txt"
These options allow for this index-file format:
      file '/full/path/to/file1.jpg'
      file '/full/path/to/file2.jpg'
      ...
Add music from mp3 file:
  -i "music.mp3"
Video filter 'PTS' is the presentation timestamp, the time at which a frame ought to be presented. We can make a video twice as fast by dividing the frame-PTS by 2:
  -filter:v "setpts=(PTS-STARTPTS) / 2"
Crop  video filter. crop=<width>:<height>:<left>:<top>:
  -filter:v "crop=1280:800:0:224"
Output framerate:
  -r 25
Output codec:
  -vcodec libx264
'Constant Rate Factor' quality setting. For x264, this means setting a value somewhere between 18 and 26 for this CRF. The default is 23, and higher values will give you worse quality.
  -crf 22
Sources:
* https://superuser.com/questions/431953/convert-old-videos-to-have-smaller-sizes
* https://davidwalsh.name/video-speed
* https://stackoverflow.com/questions/10366138/how-to-specify-unordered-image-list

Latest revision as of 15:45, 4 April 2019


Create timelapse

Install ffmpeg:

sudo apt install ffmpeg

Create timelapse indexfile:

find "$HOME/Pictures" -iname "*.jpg" -type f | sort | sed "s/\(.*\)/file '\1'/g"  > "$HOME/timelapse_files.txt"

Create the video:

ffmpeg -f concat -safe 0 -i "$HOME/timelapse_files.txt" -r 25 -vcodec libx264 -crf 22 ""$HOME/timelapse.mp4"

Playback speed and Music

The original video-length is the length when we create the video without 'setpts=~'. The images will be read as a stream of 25 pictures per second (input framerate=25). For example:

 2500 pictures -> 2500/25 = 100 seconds of video = 1:40 minutes

Lets say you have some music and want to speed-up the video to match the music length:

 Music length 2:30 minutes

Then use the following video filter to shorten the video by increasing the playback speed:

 setpts=(PTS-STARTPTS) * <music-length> / <video-length>

You can add this option as a simple formula:

 setpts=(PTS-STARTPTS)*(2*60+30)/(2500/25)

Cropping

My source is a set of pictures of size 1280 x 1024, by cropping this to 1280:800 I will have a 16:10 aspect ratio (which is a better fit for my screen).

 1280 * 10/160 = 800

I want to keep the bottom part of the picture so I need to move down by:

 1024 - 800 = 224

This results in the video filter option:

 crop=1280:800:0:224

The complete example

Settings:

projdir="$HOME/Downloads/"
picsdir="2019-03-24"
mp3file="my music.mp3"

Create the pictures index file:

find "${projdir}/${picsdir}" -iname "*.jpg" -type f | sort | sed "s/\(.*\)/file '\1'/g"  > "${projdir}/files.txt"

Count the number of pictures:

numpics=$( wc -l "${projdir}/files.txt" | cut -d' ' -f1 )

Extract and calculate the length of the music in seconds:

durationsec=$( ffmpeg -i "${projdir}/${mp3file}" 2>&1 | grep Duration | sed 's/.*\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\).[0-9]\{2\},.*/\1*3600+\2*60+\3/g' )

Check the video length (and speed) calculation:

echo "Video length calculation : (PTS-STARTPTS) * ( ${durationsec} ) / ( ${numpics} / 25 )"

Encode:

ffmpeg -f concat -safe 0 -i "${projdir}/files.txt" -i "${projdir}/${mp3file}" -filter:v "setpts=(PTS-STARTPTS)*(${durationsec})/(${numpics}/25), crop=1280:800:0:224" -r 25 -vcodec libx264 -crf 22 "${projdir}/${picsdir} timelapse (${mp3file}).mp4"

Looking for some music to add? You might want to take a look here:

Overview of the used options

Input index-file 'files.txt':

 -f concat -safe 0 -i "files.txt"

These options allow for this index-file format:

     file '/full/path/to/file1.jpg'
     file '/full/path/to/file2.jpg'
     ...

Add music from mp3 file:

 -i "music.mp3"

Video filter 'PTS' is the presentation timestamp, the time at which a frame ought to be presented. We can make a video twice as fast by dividing the frame-PTS by 2:

 -filter:v "setpts=(PTS-STARTPTS) / 2"

Crop video filter. crop=<width>:<height>:<left>:<top>:

 -filter:v "crop=1280:800:0:224"

Output framerate:

 -r 25 

Output codec:

 -vcodec libx264 

'Constant Rate Factor' quality setting. For x264, this means setting a value somewhere between 18 and 26 for this CRF. The default is 23, and higher values will give you worse quality.

 -crf 22

Sources: