I created a pretty simple Perl script to create .m3u files for all
genres in my music library.  (I eventually want to expand the script to
be able to create music match like playlists on the fly).

The problem I'm running into is that for only 150 songs the following
code takes over 5 seconds to execute:  (My computer is not bad ass, but
certainly not wimpy at 1 Ghz).  I was wondering if anyone could suggest
ways to speed it up.

The particularly slow part is:

# now write out the genres...
# first we need to get a list of possible genres...
@temp = @entries;
my @possible_genres;
my %possible_genres;
while ($_ = pop @temp) {
  # bring back the information..
  my %entry = eval ($_);
  # now double check the genre...if it's new push
  # it into the @possible_genres stack
  push @possible_genres, $entry{genre} unless
$possible_genres{$entry{genre}};
}

# now that we have files for all genres created, it is time to run
# through all entries, and append to each genre playlist...

while (my $genre = pop @possible_genres) {
  # open up the genre file for writing...
  my $playlist;
  open($playlist, ('>/ogg/m3u/' . $genre . '.m3u')) or 
    die ("Could not open Genre file:" . '/ogg/m3u/' . $genre . '.m3u' .
"\n") ;
  die ("Cannot write to the Genre file: " . '/ogg/m3u/' . $genre .
'.m3u' . "\n") 
    unless (-T $playlist && -w $playlist);

  # now go through the entries one by one, creating playlists by genre
  @temp = @entries;
  while ($_ = pop @temp) {
    my %entry = eval ($_);
    if ($entry{genre} eq $genre) {
      printf $playlist $entry{fullpath} .  "\n";
    }
  }
}

The whole script is:

#! /usr/bin/perl

use strict;
use warnings;
use Data::Dump qw(dump);
my $debug = 1;

# first, let's grab an array full of all the files...
my @files = `find /ogg`;
my @temp = @files;
my @entries;
my @genres;
my @artists;
my @albums;

while ($_ = pop @temp) 
{
  my %entry;
  my $fullpath = $_;
  chomp $fullpath;
  if ($_ =~ /\.ogg\b/) {
    $_ =~ /ogg\//;
    $' =~ /\//;
    my $genre = $`;
    $' =~ /\//;
    my $artist = $`;
    $' =~ /\//;
    my $album = $`;
    # check whether or not there are multiple discs
    my $disc;
    my $file;
    if ($' =~ /\//) {
      $disc = $`;
      $file = $';
    }
    else {
      $file = $';
      $disc = 1;
    }
    chomp $file;

    # now create the entry into the array...
    $entry{"genre"} = $genre;
    $entry{"artist"} = $artist;
    $entry{"album"} = $album;
    $entry{"disc"} = $disc;
    $entry{"file"} = $file;
    $entry{"fullpath"} = $fullpath;

    # now store the array entry...
    my $dumper = dump(%entry);
    push @entries, $dumper;
    if ($debug) {
      print "Genre: $genre\n";
      print "Artist: $artist\n";
      print "Album: $album\n";
      print "File: $file\n";
      print "Full Path: $fullpath";
      print "\n";
    }
  }
  else {
    print "Found a directory: $_\n" if $debug;
  }
}

# ok...so now we need to create playlists...
# first comes the master one...
my $temp = `rm -fR /ogg/m3u/*`;
my $master;
open ($master, ">/ogg/m3u/All_artists.m3u") or
  die ("Could not open file /ogg/m3u/all_artists.m3u");

# check to make sure we can write to the file...
die ("The file could not be written to.") unless (-T $master && -w
$master);
@temp = @files;
printf $master $_ . "\n" while ($_ = pop @temp);
close ($master);

# now write out the genres...
# first we need to get a list of possible genres...
@temp = @entries;
my @possible_genres;
my %possible_genres;
while ($_ = pop @temp) {
  # bring back the information..
  my %entry = eval ($_);
  # now double check the genre...if it's new push
  # it into the @possible_genres stack
  push @possible_genres, $entry{genre} unless
$possible_genres{$entry{genre}};
}

# now that we have files for all genres created, it is time to run
# through all entries, and append to each genre playlist...

while (my $genre = pop @possible_genres) {
  # open up the genre file for writing...
  my $playlist;
  open($playlist, ('>/ogg/m3u/' . $genre . '.m3u')) or 
    die ("Could not open Genre file:" . '/ogg/m3u/' . $genre . '.m3u' .
"\n") ;
  die ("Cannot write to the Genre file: " . '/ogg/m3u/' . $genre .
'.m3u' . "\n") 
    unless (-T $playlist && -w $playlist);

  # now go through the entries one by one, creating playlists by genre
  @temp = @entries;
  while ($_ = pop @temp) {
    my %entry = eval ($_);
    if ($entry{genre} eq $genre) {
      printf $playlist $entry{fullpath} .  "\n";
    }
  }
}

exit ;


Thanks in advance.

-Dan

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to