Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

MP3 shuffler

by rinceWind (Monsignor)
on Nov 05, 2006 at 15:58 UTC ( #582319=CUFP: print w/ replies, xml ) Need Help??

I've recently bought a 1Gb Philips MP3 player, and I'm enjoying much of my music collection whilst enduring the services of London Underground on my journey to and from work.

This player has a "shuffle" feature, which in theory plays the tracks in a random order. I say in theory, because I've found that the player seems to favour certain albums, and sometimes goes into a sequential mode - as if the shuffle wasn't turned on. Taking the battery out seems to restore the shuffle. Anyway I decided I haven't got the time and the anal fixation to gather evidence for this bug and report it to Philips.

So, instead, I've used some Perl to scramble together a random selection of tracks from my whole collection - that which I have so far ripped to my hard drive. The code uses some statistics to try and pick tracks by their length, which should try and give a representative sample of track lengths (it uses the file size to do this). It's using my File::Wildcard to derive the file name in the destination directory. I use the tool below to make a number of selections as directories of symlinks (these can be manually tweaked to remove any tracks you don't like), then use cp -rL to copy to the USB player.

#!/usr/bin/perl use strict; use warnings; use File::Wildcard; use Getopt::Long; my $music; my $output; my $size = 134217728; # default 128M selection. GetOptions( 'source=s' => \$music, 'output=s' => \$output, 'size=i' => \$size, ); $music =~ s!/$!!; #! my $wc = File::Wildcard->new( path => "$music///", match => qr(/\d*\s*([^/]+\.(?:wma|mp3))$), derive => ["$output/\$1"], ); my @allsongs; my $sum=0; my $sumsq=0; while (my $found = $wc->next) { my ($song,$dest) = @$found; my $siz = (stat $song)[7]; $sum += $siz; $sumsq += $siz * $siz; push @allsongs,[$song,$siz,$dest]; } my $count = scalar @allsongs; my $mean = $sum / $count; my $sd = sqrt( $sumsq / $count - $mean * $mean); my $nsamp = int( $mean / $sd ); my @songs = sort {$a->[1] <=> $b->[1]} @allsongs; my %seen; while ($size > 20971520) { my $pt = 0; $pt += rand for (1..$nsamp); my $idx = int( $pt / $nsamp * $count); my ($song,$ssize,$dest) = @{$songs[$idx]}; next if exists $seen{$song}; $seen{$song}++; print $song,"\n"; symlink $song, $dest; $size -= $ssize; }

--

Oh Lord, won’t you burn me a Knoppix CD ?
My friends all rate Windows, I must disagree.
Your powers of persuasion will set them all free,
So oh Lord, won’t you burn me a Knoppix CD ?
(Missquoting Janis Joplin)

Comment on MP3 shuffler
Download Code
Re: MP3 shuffler
by derby (Abbot) on Nov 06, 2006 at 16:13 UTC

    ++. One question and one comment. Why use file size instead of something that checks the mimetype of the files? And how come vendors don't implement something like a fisher-yates shuffle algorithm for *random tracks*. Maybe it's just me but I really don't want true random play ... just shuffled play.

    -derby
      Why use file size instead of something that checks the mimetype of the files?

      Is there something - a CPAN module, that will give me the duration of an MP3 or WMA file from its content? Would the mime type yield this information? Please tell!

      I used the file size as a crude and approximate way of sorting the list of tracks by duration: longer tracks = more bytes.

      Also, I'm not clear about your distinction between "shuffled" and "random". By "shuffled" do you mean avoiding picking the same track more than once, because if this is what you mean, my code achieves this with %seen.

      --

      Oh Lord, won’t you burn me a Knoppix CD ?
      My friends all rate Windows, I must disagree.
      Your powers of persuasion will set them all free,
      So oh Lord, won’t you burn me a Knoppix CD ?
      (Missquoting Janis Joplin)

        Never mind about the size ... I was reading the code incorrectly. There's MP3::Info and Audio::WMA but I can't tell you how good/bad they are. And yes, by "shuffle", we mean the same thing ... just wondering why manufacturers don't do a better job of implementing it.

        -derby
        This website may aid you in your quest. The ID3 V2 tag appears to contain the track length in milliseconds. The MP3::Tag::ID3v2 should probably help you with this.

        Revolution. Today, 3 O'Clock. Meet behind the monkey bars.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://582319]
Approved by McDarren
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (12)
As of 2014-12-18 13:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (51 votes), past polls