Stop reading if you don't want the technical details of how I made this.
Raw Capture
I used tinyCam Monitor PRO from my Android phone to record a still photo at 0.1 FPS, i.e. one frame every 10 seconds. The app saved all of the JPEGs to the SD card using a directory and file structure like this:── 2013-03-04 │ ├── 21.54.38.189.jpg │ ├── 21.54.54.224.jpg │ ├── 21.55.04.364.jpg ... │ └── 23.59.56.995.jpg └── 2013-03-05 ├── 00.00.07.247.jpg ├── 00.00.17.224.jpg ...Note how they are named using the time the photo was recorded.
Turning the frames into a movie
After using adb to pull the images off my phone and onto my laptop, I turned to creating the movie. From a previous timelapse video project, I knew that ffmpeg required frames to be numbered sequentially. I used the following shell commands to get these individual files into a set of sequentially numbered ones:$ cd 2013-03-04 $ for f in `ls *.jpg`; do cp $f `printf %05d ${n}`.jpg; n=`expr $n + 1`; done $ n=747 $ for f in `ls ../2013-03-05/*.jpg`; do cp $f `printf %05d ${n}`.jpg; n=`expr $n + 1`; doneThis exploits the fact that
ls
lists files alphabetically, and the file numbering scheme used by tinyCam maintains chronological order when sorted lexicographically. I used expr
to create a counter to keep track of how many frames I copied, and printf
to ensure I had leading zeroes in the filenames. Note that at midnight, the files are created in another directory, so I just continue the numbering where we left off for the second directory.
The easy part was actually creating the movie:
$ ffmpeg -i %05d.jpg -sameq -r 24 -vcodec libx264 output.mp4
Adding the time indicator
My first thought was to use ImageMagick to programmatically embed the time of each frame into the image file itself. But with 3500+ frames, that would be very time-consuming, even if I could automate it. ffmpeg
has the ability to burn subtitles into a movie… hey, wait! Subtitles in SubRip format!
After considering Perl for a few minutes, I came to my senses and looked around for a Ruby gem to help me. Fortunately, I found srt, a small gem to parse and create SRT files. After fixing a small bug in the library, and getting the math right, I ended up with this script:
#!/usr/bin/ruby total_frames = 3684 capture_rate = 6.0 # in frames per minute display_rate = 24.0 # in frames per second wallclock_start = Time.new(2013, 03, 04, 21, 54, 54) out = SRT::File.new subtitle_start = Time.new(2013, 03, 04, 00, 00, 00) subtitle_interval = capture_rate/display_rate # Generate a line in the file every 6 frames 0.upto((total_frames-1)/capture_rate.to_i) {|frame| line = SRT::Line.new line.sequence = frame line.start_time = (subtitle_start + subtitle_interval * frame) line.end_time = line.start_time + subtitle_interval line.text = (wallclock_start + 60*frame).strftime("%R") out.lines << line } print out.to_swhich produced a subtitle file like this:
0 00:00:00,000 --> 00:00:00,250 21:54 1 00:00:00,250 --> 00:00:00,500 21:55 2 00:00:00,500 --> 00:00:00,750 21:56
No comments:
Post a Comment