2 ################################################################################
4 # File: $RCSfile: mkplaylist,v $
5 # Revision: $Revision: 1.5 $
6 # Description: Script to generate a random playlist of x nbr files
7 # Author: Andrew@DeFaria.com
8 # Created: Wed Sep 13 09:56:55 CDT 2006
9 # Modified: $Date: 2011/01/09 00:54:42 $
12 # (c) Copyright 2006, ClearSCM, Inc., all rights reserved.
14 ################################################################################
21 use lib "$FindBin::Bin/../lib";
29 my $default_music_root = "/web/Music";
41 display "Usage: $FindBin::Script: [ -verbose | -v ] [ -n <limit> ]";
42 display "\t\t [ -f <filename> ] [ -m <music_root> ]";
44 display " -n <limit>\t\tLimit playlist to <n> entries (Default: 100 entires)";
45 display " -verbose\t\tTurn on verbose mode (Default: verbose off)";
46 display " -f <filename>\t\tWrite playlist to <filename> (Default: playlist.wpl)";
47 display " -m <music_root>\tStart searching at <music_root> (Default: $default_music_root)";
52 my $music_dir = shift;
54 opendir MUSIC, "$music_dir"
55 or error "Unable to open music directory $music_dir", 1;
57 my @entries = grep {!/^\./} readdir MUSIC;
64 my $entity = "$music_dir/$_";
66 debug "Subdirectory found - recursing to $entity...";
71 $mp3info = MP3::Info->new ($entity);
73 # WPL files don't like &.
74 if (!defined $mp3info->{FILE}) {
75 $mp3info->{FILE} = "Unknown";
77 $mp3info->{FILE} =~ s/&/&/g;
78 # When we run on Linux is /web but from XP it's //Jupiter
79 $mp3info->{FILE} =~ s/\/web/\/\/Jupiter/;
82 push @mp3files, $mp3info;
84 debug "-\t$_ skipped";
90 sub RandomizePlaylist {
95 my @genres_to_skip = (
102 verbose_nolf "Randomizing playlist (${opts {n}})...";
104 # if we are asking for more than we have then just return everything
105 if ($opts {n} > $#mp3files) {
106 $opts {n} = $#mp3files;
110 # Fill @return_titles with randomly selected songs.
111 for (my $i = 0; $i < ${opts{n}};) {
112 my $random = int (rand ($#mp3files));
114 # These are random songs - not random speach. Certain genres are
116 next unless defined $mp3files[$random]->{GENRE};
117 next if InArray ($mp3files [$random]->{GENRE}, @genres_to_skip);
119 # Crude beginnings to a more sophisticated selection mechanism. If
120 # the t option was given then only consider songs that are in the
121 # Genre specified by t. Note this currently loops forever if more
122 # songs are requested than we have.
123 if (defined $opts {t}) {
124 if ($opts {t} eq $mp3files [$random]->{GENRE}) {
125 # Eliminate dups. No sense in giving back the same song more
127 if (!InArray $mp3files [$random], @return_titles) {
128 push @return_titles, $mp3files [$random];
131 debug "Eliminating dup";
135 # Eliminate dups. No sense in giving back the same song more
137 if (!InArray $mp3files [$random], @return_titles) {
138 push @return_titles, $mp3files [$random];
141 debug "Eliminating dup";
148 return @return_titles;
149 } # RandomizePlaylist
151 sub WritePlaylistXML {
154 verbose "Writing playlist ${opts {f}}";
155 open PLAYLIST, ">${opts {f}}"
156 or error "Unable to open playlist file ${opts {f}}", 1;
159 print PLAYLIST <<END;
160 <?wpl version="1.0"?>
163 <meta name="Generator" content="Microsoft Windows Media Player -- 10.0.0.3990"/>
164 <author>Andrew\@DeFaria.com Copyright (c) 2006 ($FindBin::Script V$version)</author>
165 <title>Random Playlist of ${opts {n}} songs</title>
174 foreach (@playlist) {
175 print PLAYLIST " <media src=\"$_->{FILE}\"/>\n";
176 $total_size += $_->{SIZE}
180 print PLAYLIST <<END;
187 verbose "${opts {n}} entries writen to ${opts {f}} totaling " .
188 int ($total_size / (1024 * 1024)) . " Meg";
196 $opts {f} = "random_playlist.wpl";
197 $opts {m} = $default_music_root;
199 my $result = GetOptions (
201 "usage" => sub { Usage },
202 "verbose" => sub { set_verbose },
203 "debug" => sub { set_debug },
210 verbose "Gathering information about music in ${opts {m}}...";
211 GetMusic ($opts {m});
212 verbose "\n" . $#mp3files . " files found";
214 WritePlaylistXML (RandomizePlaylist (@mp3files));