Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
When you import movies into iMovie 10 libraries, the file is always copied, wasting space and hindering editability. This script replaces the copy with a hardlink, reclaiming disk space.
#!/usr/bin/env ruby
# Usage: dedup-imovie-library LIBRARY ORIGINALS
#
# Goes through an iMovie 10 library and replaces all the "Original Media" with
# hardlinks to the actual original media, in order to conserve disk space. Note
# that because they're hardlinks, if you copy the originals and the iMovie event
# to a new disk, you'll end up with two copies again and will have to re-run this
# tool.
#
# This assumes you've already imported the files into iMovie and waited for them
# all to be copied.
#
# This also assumes movie files in LIBRARY have unique matches in ORIGINALS with
# the same filename!
require 'fileutils'
library = ARGV.shift
originals = ARGV.shift
fail "Library #{library} does not exist" unless library && File.exist?(library)
fail "Originals folder #{originals} does not exist" unless originals && File.exist?(originals)
# For each original file in the imovie library
Dir.glob(File.join(library, '**', 'Original Media', '*')) do |library_file|
next unless File.file? library_file
# Skip it if we've already replaced it with a hardlink
next if File.stat(library_file).nlink > 1
original = Dir.glob(File.join(originals, '**', File.basename(library_file))).first
next unless original
puts "Linking #{library_file} => #{original}"
FileUtils.rm_f library_file, verbose: true
FileUtils.ln original, library_file, verbose: true
end

PromInc commented May 9, 2015

This is a great looking concept, but I am struggling to get it to work for me.

Based on your post about this script:
http://benhollis.net/blog/2014/06/28/hard-linking-videos-to-save-space-in-your-imovie-library/
I got the impression the script should be saved to the ~/Movies directory. I saved the script as "dedup-imovie-library" with no file extension using TextEdit.

When I run the terminal command however, I get the following message:
-bash: dedup-imovie-library: command not found

Can you please help me to understand where I'm going wrong here?

Thanks so much for offering a great script to fix yet another one of Apple's poorly designed architectures.

Owner

bhollis commented May 9, 2015

You have to run ./dedup-imovie-library.

Hi,

I had the same problem above but fixed it by using chmod 777 dedup-imovie-library then using it as suggested, ./dedup-imovie-library.

I have a folder with all my GoPro files imported by GoPro Studio Importer, this puts them into subfolders within the GoPro folder.

My question is, can I use this code to scan through all the subfolders? If not is there an easy change to the code to allow this. Sorry, I don't know Ruby at all.

Thanks,

Stu.

Thanks for the code, I'm very happy to use it.

I made 3 modifications:

  1. Replace the last line's command from "FileUtils.ln" to "FileUtils.ln_s" so it becomes a symlink(=softlink), which is working very well, also on other drives (not only which the iMovie library is on)

  2. To not to replace symlinks, change the line
    next if File.stat(library_file).nlink > 1
    to
    next if File.stat(library_file).nlink > 1 || File.lstat(library_file).symlink?

    or if you don't want audio files to be processed too:
    next if File.stat(library_file).nlink > 1 || File.lstat(library_file).symlink? || File.extname(library_file) == ".wav" || File.extname(library_file) == ".mp3" || File.extname(library_file) == ".m4a"

  3. Add "File::FNM_CASEFOLD" to the original file search command, so it searches case insensitive. (My original files are .MTS and iMovies modifies them during copy to lower case (.mts). So that's the modified command:
    original = Dir.glob(File.join(originals, '**', File.basename(library_file)), File::FNM_CASEFOLD).first

Great script! I'm a fairly new Mac user and was blown away when I discovered that iMovie copies files into its library. I'm currently on a one year trip and hard disk space is at an absolute premium. With tons of GoPro footage sitting duplicated on my drive, I was not a happy camper. I wanted to add a safety feature to the script though. You can check it out here:

https://gist.github.com/aardvarkk/9206a4eb5d5e78e5dbc0#file-dedup-imovie-library

All I did was add a check that the file contents are the same. This way, you won't accidentally delete/link a file that happens to have the same name as another. It will slow the entire process down, obviously, so maybe you'd want to add a switch or something... but for me I'd rather it be as safe as possible and I don't mind the hit to the speed.

Great work on this script. A tip of the hat to you, and a wag of the finger to Apple for wasting half of my hard disk with duplicated videos!

swrobel commented May 4, 2016

Thanks for this! I noticed that iMovie saves its files as .mp4 whereas my GoPro saves them as .MP4 and the comparison was failing because of the mis-matched case. I updated this gist (after incorporating @kabadisha's fork)

https://gist.github.com/swrobel/1fa71ea870a4d0feac2a6ca93b5e36eb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment