in reply to buildasx.pl (W32 Windows playlist builder)

I don't know what I'm doing wrong, but your code doesn't work, as far as I can tell. It never finds any files. Is it expecting a commandline argument?

Anyway, I re-wrote it using MP3::Info.

use File::Find; use MP3::Info; use strict; use warnings; my $dir = shift() or die "Usage: $0 absoluteDir\n"; my $entries=''; find( \&process, $dir ); sub process { /mp3$/i or return; my $ctime = localtime( (stat $File::Find::name)[10] ); my $mp3 = get_mp3info ($File::Find::name); my $duration = sprintf "%02d:%02d.%03d", $mp3->{'SECS'} ? @{$mp3}{qw( MM SS MS )} : (0,0,0); my $bitrate = $mp3->{'BITRATE'} * 1024; ( my $url = $File::Find::name ) =~ s#/#\\#g; $entries .= <<EOF; <Entry> <Title > $_ </Title> <Duration value = "$duration" /> <Param Name = "Name" Value = "$_" /> <Param Name = "MediaType" Value = "audio" /> <Param Name = "MediaAttribute" Value = "0" /> <Param Name = "Bitrate" Value = "$bitrate" /> <Param Name = "DigitallySecure" Value = "0" /> <Param Name = "PlayCount" Value = "1" /> <Param Name = "SourceURL" Value = "$url" /> <Param Name = "CreationDate" Value = "$ctime" /> <Ref href = "$url" /> </Entry> EOF } $entries or die "No files found.\n"; print <<EOF; <Asx Version = "3.0" > <Param Name = "Name" Value = "title" /> <Param Name = "AllowShuffle" Value = "yes" /> $entries </Asx> EOF

It also seems to me that you're writing some non-standard ASX fields, and even ones that are standard, you aren't putting valid data into (e.g. the ref href should probably be a valid URL, I'm guessing).

But I'd say the main lessons you should take away from this are:

  1. Use modules, esp. when they're standard (e.g. File::Find). The way you're trying to parse `dir` output, and fudge a duration from filesize is particularly gruesome.
  2. alternating between string quotes is ugly, and virtually never necessary.
    '<Duration value = "' . "$duration" . '" />' . "\n"
    can be written as
    "<Duration value = \"$duration\" />\n"
    and, even better, as
    qq(<Duration value = "$duration" />\n)
    as well as
    <<EOF <Duration value = "$duration" /> EOF

A word spoken in Mind will reach its own level, in the objective world, by its own weight