#!/usr/bin/perl -w my $RCS_Id = '$Id: playlist.pl,v 1.3 2011/08/10 18:51:36 jv Exp $ '; # Author : Johan Vromans # Created On : Sat Mar 27 12:54:43 2004 # Last Modified By: Johan Vromans # Last Modified On: Wed Nov 4 18:48:25 2009 # Update Count : 60 # Status : Unknown, Use with caution! ################ Common stuff ################ use strict; # Package or program libraries, if appropriate. # $LIBDIR = $ENV{'LIBDIR'} || '/usr/local/lib/sample'; # use lib qw($LIBDIR); # require 'common.pl'; # Package name. my $my_package = 'Sciurix'; # Program name and version. my ($my_name, $my_version) = $RCS_Id =~ /: (.+).pl,v ([\d.]+)/; # Tack '*' if it is not checked in into RCS. $my_version .= '*' if length('$Locker: $ ') > 12; ################ Command line parameters ################ use Getopt::Long 2.13; # Command line options. my $verbose = 0; # verbose processing my $strip; # prefix to strip my $prefix; # prefix to add my $shuffle = 1; # shuffle my $m3u; # create M3U list # Development options (not shown with -help). my $debug = 0; # debugging my $trace = 0; # trace (show process) my $test = 0; # test mode. # Process command line options. app_options(); # Post-processing. $trace |= ($debug || $test); ################ Presets ################ $strip = quotemeta($strip) if $strip; ################ The Process ################ my @filelist; my $dcount = 0; my $fcount = 0; my @dirs = @ARGV ? @ARGV : ; foreach ( @dirs ) { chomp; s/\\/\//g; s/\/+$//; if ( -f && /\.mp3$/i ) { push( @filelist, $_ ); $fcount++; } elsif ( -d _ ) { my @files = glob("$_/*"); unless ( @files ) { warn("Skipping: $_ [no files]\n"); next; } $dcount++; @files = grep { m/\.mp3$/i } @files; $fcount += @files; warn("$_: ", scalar(@files), " file", @files == 1 ? "" : "s", "\n") if $verbose > 1; @files = sort @files unless $shuffle; push(@filelist, @files); } else { warn("Skipping: $_ [$!]\n"); } } if ( $shuffle ) { my @result; while ( @filelist ) { push( @result, splice(@filelist, rand(@filelist), 1) ); } @filelist = @result; } write_playlist(@filelist); warn("Playlist contains $fcount entr", $fcount == 1 ? "y" : "ies", " from $dcount director", $dcount == 1 ? "y" : "ies", "\n") if $verbose; exit 0; ################ Subroutines ################ sub write_playlist { my (@list) = @_; if ( $m3u ) { print("#EXTM3U\n"); } else { print("[playlist]\n"); } foreach my $file ( @list ) { $file = $1 if $strip && $file =~ /^$strip(.*)/i; $file = $prefix . $file if $prefix; if ( $m3u ) { my ( $artist, $title, $length ) = get_mp3info($file); $title = "Title" unless $title; $title = $artist . ": " . $title if $artist; print("#EXTINF:$length,$title\n$file\n"); } else { print("$file\n"); } } } sub get_mp3info { my ( $file ) = @_; my $title = ""; my $artist = ""; my $length = -1; $title = $1 if $file =~ m;(?:^|/)\d+_([^/]+)\.mp3$;; ( $title, $artist ) = ( $2, $1 ) if $title =~ /^(.*?)__(.*)/; $artist =~ s/_/ /g; $title =~ s/_/ /g; $title =~ s/; / \/ /g; ( $artist, $title, $length ); } ################ Subroutines ################ sub app_options { my $help = 0; # handled locally my $ident = 0; # handled locally # Process options, if any. # Make sure defaults are set before returning! return unless @ARGV > 0; # Allow -vvv and so. Getopt::Long::config(qw(bundling)); if ( !GetOptions( 'ident|i' => \$ident, 'verbose|v+' => \$verbose, 'strip|s=s' => \$strip, 'prefix=s' => \$prefix, 'shuffle!' => \$shuffle, 'm3u' => \$m3u, 'trace|t' => \$trace, 'help|?|h' => \$help, 'debug' => \$debug, ) or $help ) { app_usage(2); } app_ident() if $ident; } sub app_ident { print STDERR ("This is $my_package [$my_name $my_version]\n"); } sub app_usage { my ($exit) = @_; app_ident(); print STDERR <