I saw artist Candice Breitz’ video installation of 30 fans singing along to a Madonna album in the Boston Museum of Fine Arts
Seeing Songs exhibition. I mentioned it to some friends, and we ended up trying it ourselves. We first, all together, sang a song and recorded the sound. Then, one at a time, we videoed each other singing the music while listening to the group track with headphones. That gave us 9 videos that we wanted to tile in a 3x3 grid, synchronize, then convert to one video.
I started off using iMovie, but the interface was laggy and inconsistent as my computer struggled with the load. You can also only play two videos simultaneously, using the picture-in-picture feature. You’d have to add one video at a time, and constantly export and re-import. This wasn’t going to work.
Then I discovered
rmov, an excellent library for opening, editing and exporting QuickTime movies within Ruby. It worked spectacularly well, and I made the video as desired. I found the required start-time offsets to synchronize the streams by importing streams one by one and comparing them to a single person; then I could just compose all the streams together. I often just exported the audio, which made it much faster to render while deciding on the offsets.
Lastly, here’s the code I used.
require 'rubygems'
require 'rmov'
locs = [2732, 2734, 2736, 2739, 2740, 2744, 2746, 2748, 2749]
offsets = [41.12, 4.25, 1.8, 0.0, 0.8, 2.5, 1.65, 4.7, 0.8]
clips = []
locs.zip(offsets).each do |l,off|
filename = "source/MVI_#{l}/MVI_#{l} - iPhone.m4v"
clips << QuickTime::Movie.open(filename)
clips.last.delete_section 0, off
end
background = QuickTime::Movie.open 'source/background_480x360.png'
q = QuickTime::Movie.empty
length = clips.map(&:duration).max.ceil
puts length
(length*15).times do
q.insert_movie background, 0
end
WIDTH = 480
HEIGHT = 360
clips.each_with_index do |c,i|
row = i / 3
col = i % 3
q.composite_movie c, 0
a = q.tracks[-1]
a.scale 0.34, 0.34
a.translate col*WIDTH/3, row*HEIGHT/3
end
exporter = q.exporter
if File.exist? 'settings.st'
exporter.load_settings 'settings.st'
else
exporter.open_settings_dialog
exporter.save_settings 'settings.st'
end
outname = "output.mov"
puts "creating #{outname}."
exporter.export outname do |progress|
percent = (progress*100).round
puts "#{percent}% complete"
end