For when the DJ needs a bathroom break...

petdance on 2005-11-28T21:32:57

From an upcoming article on the mdfind command, here's a program I wrote to find all my iTunes songs longer than 10 minutes, and print them in descending order of length.

#!/usr/bin/perl -w

use warnings; use strict;

# Get the number of minutes from the command line, or default to 10 my $minutes = shift || 10; my $seconds = $minutes * 60;

# XXX This doesn't verify the media type, but should.

my @filelist = `mdfind 'kMDItemDurationSeconds > $seconds'` or die "You don't have any songs over $minutes minutes long!\n"; chomp @filelist; # Remove trailing newlines

my @fileinfo; for my $filename ( @filelist ) { my %fields;

# Call mdls on the file and scan each line for ( qx{mdls "$filename"} ) { # Extract the keys and values if ( my ($key,$value) = /^kMDItem(\w+)\s+=\s+(.*)/ ) { # Strip surrounding parentheses and/or quotes $value =~ s/^\(|\)$//g; $value =~ s/^"|"$//g; $fields{$key} = $value; } } push( @fileinfo, \%fields ); }

# Sort in decreasing order of length @fileinfo = sort { $b->{DurationSeconds} <=> $a->{DurationSeconds} } @fileinfo;

# Print the specs for each song for my $file ( @fileinfo ) { printf( qq{%2d:%02d "%s" by %s from "%s"\n}, $file->{DurationSeconds}/60, $file->{DurationSeconds}%60, $file->{Title}, $file->{Authors}, $file->{Album} ); }


which gives this output

20:34 "2112" by Rush from "2112"
19:59 "The Fountain Of Lamneth" by Rush from "Caress Of Steel"
18:36 "Alice's Restaurant Massacree" by Arlo Guthrie from "The Best Of Arlo Guthrie"
18:07 "Cygnus X-1 Book II, Hemispheres" by Rush from "Hemispheres"
17:06 "Dogs" by Pink Floyd from "Animals"
16:44 "An American In Paris" by George Gershwin from "Greatest Hits"
16:20 "Rhapsody In Blue" by George Gershwin from "Greatest Hits"
16:10 "Dogs" by Les Claypool's Frog Brigade from "Live Frogs Set 2"
15:50 "2112" by Rush from "All The World's A Stage"
15:47 "Disgustipated" by Tool from "Undertow"
15:27 "Sleep Like A Child" by Joss Stone from "Mind Body & Soul"
14:56 "Working Man / Finding My Way" by Rush from "All The World's A Stage"
14:22 "Telegraph Road" by Dire Straits from "Love Over Gold"
14:15 "Do You Feel Like We Do" by Peter Frampton from "Frampton Comes Alive!"
13:57 "Full Metal Jackoff" by Jello Biafra With D.O.A. from "Last Scream Of The Missing Neighbors"
13:47 "Third Eye" by Tool from "√Ãœnima"
13:38 "Rime Of The Ancient Mariner" by Iron Maiden from "Powerslave"
13:35 "Shine On You Crazy Diamond" by Pink Floyd from "Pulse"
13:09 "Rime Of The Ancient Mariner" by Iron Maiden from "Live After Death"
13:03 "Rime Of The Ancient Mariner" by Opera IX from "A Call To Irons - A Tribute To Iron Maiden"
12:59 "Any Three Days" by Thee Speaking Canaries from "Songs For The Terrestrially Challenged"
12:43 "Smiling Faces Sometimes" by The Temptations from "Psychedelic Soul"
12:34 "The Necromancer" by Rush from "Caress Of Steel"
12:27 "Blinding Light Show/Moonchild" by Triumph from "King Biscuit Flower Hour Presents...Triumph In Concert"
12:19 "Didn't We Deserve A Look At You The Way You Really Are" by Shellac from "Terraform"
12:18 "Through It All There's You" by Robert Palmer from "Sneakin' Sally Through The Alley"
12:10 "Xanadu" by Rush from "Exit... Stage Left"
12:08 "Sweet Dreams" by Probot from "Probot"
12:04 "Papa Was A Rollin' Stone" by The Temptations from "Psychedelic Soul"
11:57 "By-Tor And The Snow Dog" by Rush from "All The World's A Stage"
11:46 "Christo Redemptor" by Charlie Musselwhite from "Blues Masters, Volume 4: Harmonica Classics"
11:44 "Pigs (Three Different Ones)" by Les Claypool's Frog Brigade from "Live Frogs Set 2"
11:37 "Slick / Clownmaster / Tilted" by Sugar from "Bleeding"
11:37 "Suite Sister Mary" by Queensry\U0308che from "Operation: Livecrime"
11:31 "Packard Goose" by Frank Zappa from "Joe's Garage"
11:30 "Pigs (Three Different Ones)" by Pink Floyd from "Animals"
11:30 "One Bourbon, One Scotch, One Beer [Live]" by George Thorogood from "Extended Versions [Live]"
11:23 "Heart Of The Sunrise" by Yes from "Fragile"
11:20 "Prologue And Tradition & Main Title" by Original Cast from "Fiddler On The Roof"
11:20 "Tonight/You Shook Me All Night Long" by Charlie Robison from "Live"
11:19 "Crash And Burn" by Sheryl Crow from "The Globe Sessions"
11:16 "Tenth Leaving Train" by Eleventh Dream Day from "Prairie School Freakout"
11:13 "Sheep" by Les Claypool's Frog Brigade from "Live Frogs Set 2"
11:11 "Xanadu" by Rush from "A Farewell To Kings"
11:09 "Free Bird (demo)" by Lynyrd Skynyrd from "Lynyrd Skynyrd (pronounced 'leh-'neÃÅrd 'skin-'neÃÅrd)"
11:08 "Cortez The Killer" by The Church from "A Box Of Birds"
11:08 "Rock Bottom" by UFO from "Strangers In The Night"
11:07 "Reflection" by Tool from "Lateralus"
11:07 "I Heard It Through The Grapevine" by Creedence Clearwater Revival from "Cosmo's Factory"
11:06 "Funeral For A Friend/Love Lies Bleeding" by Elton John from "Goodbye Yellow Brick Road"
10:57 "The Camera Eye" by Rush from "Moving Pictures"
10:47 "Sorrow" by Pink Floyd from "Pulse"
10:40 "Smash" by Offspring from "Smash"
10:40 "Marquee Moon" by Television from "Marquee Moon"
10:39 "Suite Sister Mary" by Queensry\U0308che from "Operation: Mindcrime"
10:33 "Adagio; Adanto Con Moto: Concerto In F For Piano And Orchestra" by George Gershwin from "Greatest Hits"
10:30 "Do I Do" by Stevie Wonder from "Original Musiquarium 1"
10:25 "Cygnus X-1" by Rush from "A Farewell To Kings"
10:25 "Flood Down In Texas" by Stevie Ray Vaughan from "Blues Masters, Volume 3: Texas Blues"
10:19 "Child In Time" by Deep Purple from "The Very Best Of Deep Purple"
10:18 "Sheep" by Pink Floyd from "Animals"
10:14 "Blues Power" by Albert King from "Blues Masters, Volume 7: Blues Revival"
10:14 "Coma" by Guns N' Roses from "Use Your Illusion I"
10:06 "To Tame A Land" by Morgion from "A Call To Irons - A Tribute To Iron Maiden"
10:05 "La Villa Strangiato" by Rush from "Rush In Rio"


Tales From The Lush Attic

barbie on 2005-11-28T22:46:15

Nice to see a healthy dose of Rush in there, but you still need a nice collection of Yes and ELP ;) Failing that I would recommend listening to the last few albums by IQ (Ever being a particular favourite, which includes the 15+ minutes of Further Away).

Re:Tales From The Lush Attic

petdance on 2005-11-28T22:58:39

I really don't dig the ELP, and Yes I've never really liked enough to buy anything beyond Fragile.

What, no "Supper's Ready?"

runrig on 2005-11-29T01:56:50

Ahh, memories of college radio and long breaks out on the balcony...or back in the days of vinyl, you could just find a record with an infinite loop at the end and let it play ad infinitum, or, if you really didn't care if you had listeners, you could play some Metal Machine Music (the side with the infinite loop at the end) :-)

Hm

pudge on 2005-11-29T02:44:59

I got a lot of uninit warnings from your script, like the data could not be retrieved properly. I dunno:
Use of uninitialized value in printf at /private/var/tmp/folders.501/Cleanup At Startup/untitled text 13-154924196.547 line 40.
24:17 "" by  from ""
I wonder if maybe because it was not restricted to a specific media type(s)?

This is a lot more reliable and a lot faster for me (though also far less applicable for the article you're working on):
#!/usr/bin/perl
 
use warnings;
use strict;
 
use Mac::Glue ':glue';
 
# Get the number of minutes from the command line, or default to 10
my $minutes = shift || 10;
my $seconds = $minutes * 60;
 
my $itunes = new Mac::Glue 'iTunes';
my $tracks = $itunes->obj(
    tracks => whose(duration => g_t => $seconds),
    library_playlist => 1
);
 
my @tracks = sort { $b->[1] <=> $a->[1] }
             map  { [ $_, $_->prop('duration')->get ] }
             $tracks->get;
 
for (@tracks) {
    my($track, $duration) = @$_;
    printf( qq{%2d:%02d "%s" by %s from "%s"\n},
        $duration / 60, $duration % 60,
        $track->prop('name')->get,
        $track->prop('artist')->get,
        $track->prop('album')->get,
    );
}