2015-04-08

Not too long ago, I purchased a programmable remote for my DSLR camera so that I could take long exposures as well as multiple exposures in order to create time lapse videos. While the timer does a great job, I still needed a way to convert a series of images into a video.

Fortunately, ffmpeg does a great job of converting a pile of images into a video file, and I most certainly have ffmpeg installed on my laptop. Now all I need is a bit of code to:

  1. search for some files
  2. copy and rename the files
  3. always skip step 3 :)
  4. use ffmpeg to convert the files to a video

When the script runs, it looks for a directory named 'images' and recursively looks for files in that directory (my camera tends to make multiple directories of files). Then the files are copied into a temp folder and given a 6 digit name: 000001, 000002, 000003, etc. Finally, ffmpeg converts those 6 digit named files into a video.

Enter The Ruby

#!/usr/bin/env ruby
require 'fileutils'
require 'date'

#where will we look for files?
LOCAL_DIR File.expand_pathFile.dirname(__FILE__) )
TEMP_DIR File.join(LOCAL_DIR"temp")
IMAGES_DIR File.join(LOCAL_DIR"images")
#if the temp dir exists, delete it and its contents
if Dir.exists? TEMP_DIR
    FileUtils.rm_rf TEMP_DIR
end

#make the temp dir
FileUtils.mkdir TEMP_DIR

#keep track of how many files we have
@file_count 0

def copy_files(location)
  files = []
  dirs = []
  Dir.foreach(locationdo |name|
    #ignore . and ..
    if name!='.' and name!='..'
      #what is the path of the item?
      path File.join(location,name)
      #recurse if path is a directory
      if Dir.exists? path
        dirs << path
      else
        files << path
      end
    end
  end
  #sort the directories by name and recurse
  dirs dirs.sort()
  dirs.each do |d|
    puts "DIRECTORY: #{d}"
    copy_files(d)
  end
  #sort the files by name and recurse
  files files.sort()
  files.each do |d|
    new_name @file_count.to_s
    #increment the file_count
    @file_count+=1
    ## pad the new file name with 0
    (6-new_name.length()).times do
      new_name "0"+new_name
    end
    #determine where the new file is going
    new_file File.join(TEMP_DIRnew_name)
    #what is the command to copy the file?
    copy_command "cp #{d} #{new_file}"
    puts copy_command
    #run the command
    `#{copy_command}`
  end
end

#recursively get a list of all files in the current directory
copy_files(IMAGES_DIR)

#what day is it?
ymd Date.today.strftime("%Y%m%d")

#what video command should we run?
cmd "ffmpeg -y -f image2 -i temp/%06d -b:v 50000k  #{ymd}_timelapse.avi"
#run the command
`#{cmd}`

By default, the ffmpeg command will create a video at 10 frames/second.

My first time lapse was during Sunset on the Equinox

Sadly, I didn't adjust the camera properly when capturing the April 4th Lunar Eclipse. However, considering I set everything up 7 hours before the eclipse, I think I did a fairly sweet job of determining where to point the camera. :)

Now quit reading, slow down, and speed up.

Comments
2015-04-22 Alison Chaiken:
'gst-launch multifilesrc location="somematchingstring"' would work as well.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
5 plus 9
Answer:
required
subscribe
 
2016
2015
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008