#!/usr/bin/perl # # Author Stephen Kingham, Stephen.Kingham@kingtech.com.au # # https://www.kingtech.com.au # # License and distributed under the GNU General Public License (GPL) # # Copyright (C) 2009 Stephen Kingham # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # This programme is just a wrapper for # lame, # faad, # flac, and # mplayer # # Versions # 0.1 May 2009 - Can convert .wav, .mp3, and .flac, to mp3. # - It also copies all the other files over to the specified # destination and recreate the directory structure. # - If Folder.jpg does not exist it will create one by copying from an available .jpg file. # 0.2 Jun 2009 - Uses mplayer to convert .wma audio files. # 0.3 Jun 2009 - Uses eyeD3 to add album artwork to first mp3 file for iTunes to display the album art # - Create Folder.jpg as a 200x200 using the largest jpeg # - Only add the artwork if atleast one MP3 file was created, or # with -a add the artwork to all the MP3s. # - Art work is added to the new MP3 as a second phase, after all the MP3s are createds. # - Added some LAME parameters to include VBR along with the CBR # 0.4 Jun 2010 - A log and Errors now send notices to email rather than just ending # - Created a few subs to make the code easier to read and smaller # - improved the documentation in the code # 1.0 Feb 2011 - Corrected bug in creating a larger Folder.jpg # - updated usage to include the email switch # - tested install on Ubuntu 10.04 # 1.1 May 2011 - In the defauls corrected VBR (changed V0 to -V0), otherwise LAME would not run using the defaults. # - updated documentation and comments # - added option to send email reports via sendmail, or using an smtp host # 1.2 Feb 2013 - Use avconv for m4a files to flac first then wav then to mp3 # 1.3 May 2016 - improved debug capability fixed fprint format during debug # 1.4 May 2016 - Change default so that if Owner (-o) is not provided it does not try to change it. # - same for Group (-g), if Group not specified it is left alone # - User can now also specify permissions, if not provided then permissions are not changed # 1.5 May 2016 - Allow avconv to overwrite files, this is needed if programme is halted midway leaving an old file behind # - added a user switch to turn nice on so it runs in the background without using too much CPU # - added user can specify permissions use warnings; #use diagnostics; use strict; # Find and Basename is used to search through the directories and files use File::Find; use File::Basename; # MIME is needed to send email use MIME::Lite; use Cwd; # Cwd is used to find the local directory # Use Capture::Tiny to get output from shell commands use Capture::Tiny ':all'; # # Initialise variables that could be set y the user my @Args=(); my $Overwrite = "No"; my $debug="off"; my $Owner = ""; my $Group = ""; my $Permissions = ""; my $Nice = ""; # User input will change it to "nice" my $RootDir = getcwd; my $srcDirAbs=$RootDir . "/" . "music-raw"; # Adsolute root Directory to source all the music from my $dstDirAbs=$RootDir . "/" . "music-mp3"; # Absolute root directory to put all the mp3 files my $bitRate = 0; my $Silent="No"; my $AddArtWorkToAll="no"; my $VBR = "-V0"; my $Help="no"; my $emailTo = ""; my $StdOut =""; my $StdErr = ""; my $Code = ""; my $MediaInfoResult=""; my @MediaInfoResultArray=(); my $ShellCommandResultLine=""; my $MediaInfoPerformer=""; my $MediaInfoAlbum=""; my $MediaInfoGenre=""; my $MediaInfoYear=""; my $MediaInfoComposer=""; my $MediaInfoLabel=""; my $MediaInfoValue=""; my $srcFileText=""; my $dstFileText=""; # Other variables used in the programme my $EMailSubLog=""; # This is the text we want to email at end my $emailFrom = "copyDirToMP3"; my $emailSubject = `hostname`; my $smtpHostname = ""; if ( length( $emailSubject ) > 0 ) { $emailSubject = "Log from copyDirToMP3 run on $emailSubject"; } else { $emailSubject = "Log from copyDirToMP3"; } my $emailError = ""; # If set then when EMailSub is called it will send the mail and then exit. my $srcFileRel=" "; # this is the source file less the root path, ie relative name my $srcFileAbs=" "; # Absulte filename of the file we are processing my $srcFileExtension=" "; # Just the extension of the filename, eg .wav my $srcFilePathAbs=" "; # the full path of the source file, ie without the filename my $srcFilename=" "; # just the filname of the source file without extension or path my $srcFileDirRel=" "; # the path to the file being processed less the root part of the directory # my $dstFileAbs=" "; # Absulte filename of the file we are processing my $dstFileMP3Abs=" "; # Destination filename with the extension changed to .mp3 my $dstFileWAVAbs=""; # Destination filename with .wav extension as intermediate to converting to mp3 my $dstFileImage=""; # my $fileSize1=0; # fileSize is used to test size of image file to choose the best my $fileSize2=0; # my $WasAtLeastOneMP3Created = "no"; # If set to Yes add artwork to new mp3 filenames in @mp3sToAddGraphicTo my @mp3sToAddGraphicTo=(); # The list of all the new mp3 files. Absolute path. # my $argnum = 0; # Used to process variables set by user # my @paths = (); my $pathPart=""; my $i=0; # my $albumName=""; my $artistName=""; my $songTitle=""; # # Process variables set by user if ( $#ARGV eq -1 ) { $Help="yes" }; foreach $argnum (0 .. $#ARGV) { # if ( $ARGV[$argnum] eq "-f" ) { $Overwrite="yes" }; if ( $ARGV[$argnum] eq "-debug" ) { $debug="on" }; if ( $ARGV[$argnum] eq "-o" ) { $Owner=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-g" ) { $Group=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-p" ) { $Permissions=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-s" ) { $srcDirAbs=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-d" ) { $dstDirAbs=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-b" ) { $bitRate=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-S" ) { $Silent="Yes" }; if ( $ARGV[$argnum] eq "-a" ) { $AddArtWorkToAll="Yes" }; if ( $ARGV[$argnum] eq "-V0" ) { $VBR="-V0" }; if ( $ARGV[$argnum] eq "-V1" ) { $VBR="-V1" }; if ( $ARGV[$argnum] eq "-V2" ) { $VBR="-V2" }; if ( $ARGV[$argnum] eq "-V3" ) { $VBR="-V3" }; if ( $ARGV[$argnum] eq "-V4" ) { $VBR="-V4" }; if ( $ARGV[$argnum] eq "-V5" ) { $VBR="-V5" }; if ( $ARGV[$argnum] eq "-V6" ) { $VBR="-V6" }; if ( $ARGV[$argnum] eq "-e" ) { $emailTo=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-smtp" ) { $smtpHostname=$ARGV[$argnum+1] }; if ( $ARGV[$argnum] eq "-nice" ) { $Nice="nice" }; if ( $ARGV[$argnum] eq "-h" || $ARGV[$argnum] eq "-help" || $ARGV[$argnum] eq "?" || $#ARGV eq 0 ) { $Help="yes" }; }; # if ( $srcDirAbs eq $dstDirAbs ) { print "Destination directory must be different from the source directory\n\n"; $Help="yes"; } if ( $Help eq "yes" ) { print "This programme will create a new directory tree from a source directories, and\n"; print "will convert any audio files to mp3s. It will add to the mp3s the Album Title and the Artist\n"; print "as ID3 version v2.3 tags. It assumes the Album Title is the name of the directory, and the\n"; print "Artis is the parent directory.\n"; print "It will also create a Folder.jpg 200x200 pixels using the larges jpeg,\n"; print "which it will add to every mp3 as a ID3 version v2.3 tag.\n"; print "Copyright (C) 2009 Stephen Kingham\n"; print "More info at www.kingtech.com.au\n"; print "\n"; print "This program is free software; you can redistribute it and/or\n"; print "modify it under the terms of the GNU General Public License\n"; print "as published by the Free Software Foundation; either version 3\n"; print "of the License, or (at your option) any later version.\n"; print "\n"; print "This program is distributed in the hope that it will be useful,\n"; print "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"; print "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"; print "GNU General Public License for more details.\n"; print "\n"; print "Version 1.1 May 2011\n\n"; print "usage [-f] [-o OWNER] [-g GROUP] [-s SOURE-DIR] [-d DESTINATION DIR] [-b BITRATE] [-S]\n"; print " -f overwrite all files in the destination [default=do not overwrite]\n"; print " -o OWNER change the owner of the files/directories to OWNER, [default=do not change]\n"; print " -g GROUP change the group of the files/directories to GROUP, [default=do not change]\n"; print " -p XXX change the permissions of the files/directories to XXX, [default=do not change]\n"; print " -s DIR The root directory to find all the source audio files [default=./music-raw]\n"; print " -d DIR The destination root directory to put the converted audio files [default=./music-mp3]\n"; print " -b BITRATE LAME parameter CBR bit rate do you want the mp3, [VBR is used as the default]\n"; print " -Vn LAME parameter VBR V0=high good for HiFi (245kbps), V3=iPOD (175kbps) [V0 is the default]\n"; print " -a Re apply the artwork to all the mp3s [default is no]\n"; print " -e Send logs to this email address [default is null]\n"; print " -smtp SMTP Hostname to send email to, needed if host does not have Sendmail [defulat Null]\n"; print " -S Run silently, otherwise advise each action [default=do not run silent]\n"; print " -nice Run the process without using slowing down forground processes [default=nice is not used]\n"; print " -debug Will output details of each action [default is no debug]\n"; print "Uses the following programmes:\n"; print " LAME (http://www.mp3dev.org/),\n"; print " MPLAYER (http://www.mplayerhq.hu/design7/news.html),\n"; print " FLAC (http://flac.sourceforge.net), and\n"; print " eyeD3 (http://eyed3.nicfit.net/).\n"; print " faad (http://www.audiocoding.com/).\n"; print "Uses the following perl modules:\n"; print "warnings, diagnostics, strict, File::Find, File::Basename, MIME::Lite, Cwd, Capture::Tiny\n"; exit 0; } # # if ($debug eq "on") { print "DEBUG:\n -f=$Overwrite\n debug=$debug\n -o=$Owner\n -g=$Group\n -s=$srcDirAbs\n -d=$dstDirAbs\n -b=$bitRate\n VBR=$VBR\n-e=$emailTo\n" }; #sub try (&@) #{ # my ($try, $catch)=@_; # eval ( &$try ); # if ($@) {local $_ = $@; &$catch; } #} #sub catch (&) { $_[0]} # Clean up by escaping special characters sub EscapeSpecialCharactersSub { my $EscapeSpecialCharacters = $_[0]; $EscapeSpecialCharacters =~ s/\,/\\,/g; $EscapeSpecialCharacters =~ s/\+/\\+/g; $EscapeSpecialCharacters =~ s/\'/\\'/g; # $EscapeSpecialCharacters =~ s/\ö/\\ö/g; $EscapeSpecialCharacters =~ s/\_/\\_/g; $EscapeSpecialCharacters =~ s/\`/\\`/g; $EscapeSpecialCharacters =~ s/\ /\\ /g; $EscapeSpecialCharacters =~ s/\(/\\(/g; $EscapeSpecialCharacters =~ s/\)/\\)/g; $EscapeSpecialCharacters =~ s/\&/\\&/g; #$EscapeSpecialCharacters = "\Q$_[0]\E"; return $EscapeSpecialCharacters; } # Send an email to admin advising something went wrong sub EMailSub { my $emailData; $emailData = $_[0]; if ($debug eq "on") { print "DEBUG: Going to send email to $emailTo via the host $smtpHostname\n"}; my $msg = MIME::Lite->new( From => "$emailFrom", To => "$emailTo", Subject => "$emailSubject", Type => 'text/html', Data => "$emailData" ); eval {$msg->send }; if ($@) { # sending via sendmail failed if ($debug eq "on") { print "DEBUG: Sendmail failed\n"}; # if ( $smtpHostname ne "" ) { # try smtp if an smtp hostname provided eval { $msg->send('smtp', $smtpHostname) }; if ($@) { print "ERROR: Sending email via SMTP host $smtpHostname failed with $@.\n"; } else { if ($debug eq "on") { print "DEBUG: Successful emailed log to $emailTo via $smtpHostname\n"}; } } else { print "ERROR: Sendmail can not work becuase we do not know an SMTP host.\n"; } } else { if ($debug eq "on") { print "DEBUG: Just emailed log to $emailTo\n"}; } if ( $emailError ne "" ) { exit 0; } }; # Perform a shell command sub ShellCommandSub { if ( $Nice eq "nice" ) { # add nice to the start of the array unshift(@Args, "nice", @Args ); } ($StdOut, $StdErr, $Code) = capture { my $i = system(@Args); }; # if ($debug eq "on") { print "DEBUG ShellCommandSub:\n Just ran @Args\n got these results:\n StdOut=$StdOut\n StdErr=$StdErr\n Code=$Code\n i=$i.\n" }; # if ( $Code != 0 ) { $emailError = "ERROR"; $EMailSubLog= "ERROR: failed: $? $!
\nStdOut=$StdOut
\nStdErr=$StdErr
\nCode=$Code
\nOutput if worked=$i
\n$EMailSubLog"; EMailSub($EMailSubLog); } if ($? == -1) { print "ERROR: failed to execute @Args\n $!\n"; $emailError = "ERROR"; $EMailSubLog= "ERROR: failed: $? $!
\nStdOut=$StdOut
\nStdErr=$StdErr
\nCode=$Code
\nOutput if worked=$i
\n$EMailSubLog"; EMailSub($EMailSubLog); } elsif ($? & 127) { # printf "ERROR: @Args\n child died with signal %s, %s StdOut=$StdOut\n StdErr=$StdErr\n Code=$Code\n i=$i\n", ($? & 127), ($? & 128) ? 'with' : 'without'; $emailError = "ERROR"; $EMailSubLog= "ERROR: failed: $? $!
\nStdOut=$StdOut
\nStdErr=$StdErr
\nCode=$Code
\nOutput if worked=$i
\n$EMailSubLog"; EMailSub($EMailSubLog); exit 0; } else { if ($debug eq "on") { printf "child exited with value %s
\nStdOut=%s
\nStdErr=%s
\nCode=%s
\n=$i", $? >> 8, $StdOut,$StdErr,$Code}; } return "
\n$i
\n$StdOut"; }; # # START OF THE MAIN LOOP # # find will find every file, we start find sub { $srcFileAbs = $File::Find::name; if ($debug eq "on") { print "DEBUG: Start of a new file\n\nsrc file Abs=$srcFileAbs\n" }; $srcFileAbs =~ s/\ö/\ö/g; # For Björk # Split the source file to find the relative path/filename of the src file # Then turn that into the absulute destination filename (undef, $srcFileRel) = split ( $srcDirAbs, $srcFileAbs ); $dstFileAbs = $dstDirAbs . "/" . $srcFileRel; $dstFileAbs =~ s/\/\//\//g; # change // to / if ($debug eq "on") { print "dst file Abs=$dstFileAbs\n" }; if ( -d $srcFileAbs ) { # So $srcFileAbs is a directory, we need to create the destination directory if ($debug eq "on") { print "Directory\n" }; # # create the directory in the new location if it does not already exist # if ( -d "$dstFileAbs" ) { if ($debug eq "on") { print "destination directory already exists.\n" }; } else { # We need to create the new directory and change the ownership @Args = ("mkdir", $dstFileAbs); ShellCommandSub; # # Now we set the permissions and owner if ( $Owner ne "" ) { @Args = ("chown", "$Owner", $dstFileAbs); ShellCommandSub; } # Now we set the permissions and owner if ( $Group ne "" ) { @Args = ("chgrp", "$Group", $dstFileAbs); system(@Args) == 0 or die "ERROR: system @Args failed: $? $!\n"; ShellCommandSub; } if ( $Permissions ne "" ) { @Args = ("chmod", $Permissions, $dstFileAbs); system(@Args) == 0 or die "ERROR: system @Args failed: $? $!"; ShellCommandSub; } if ($debug eq "on") { print "Created new destination directory $dstFileAbs\n" }; if ($emailTo ne "" ) { $EMailSubLog="$EMailSubLog
\nCreated new destination directory $dstFileAbs" }; }; } else { # # So it is a file and not a directory, we need to copy the file to the new location and # convert any audio files to mp3's # We are aldo going to look for graphic files and pick the largest to be the Folder.jpg # # Find the file's extension ($srcFilename, $srcFilePathAbs, $srcFileExtension) = fileparse( $srcFileAbs, qr/\.[^.]*/); (undef, $srcFileDirRel) = split ( $srcDirAbs, $srcFilePathAbs ); if ($debug eq "on") { print "srcPath=$srcFilePathAbs , Filename=$srcFilename, extension=$srcFileExtension, Rel=$srcFileDirRel\n" }; # # Have we found an audio file. if ( $srcFileExtension eq ".wav" || $srcFileExtension eq ".WAV" || $srcFileExtension eq ".wma" || $srcFileExtension eq ".WMA" || $srcFileExtension eq ".m4a" || $srcFileExtension eq ".M4A" || $srcFileExtension eq ".mp4" || $srcFileExtension eq ".MP4" || $srcFileExtension eq ".mp3" || $srcFileExtension eq ".MP3" || $srcFileExtension eq ".flac" || $srcFileExtension eq ".FLAC" ) { # Yes we found an audio file to convert # if ($debug eq "on") { print "File is an audio file.\n" }; # $srcFileText = EscapeSpecialCharactersSub( $srcFileAbs ); @Args = ("mediainfo $srcFileText"); $MediaInfoResult=ShellCommandSub; @MediaInfoResultArray = split ( "\n", $MediaInfoResult); $MediaInfoPerformer=""; $MediaInfoAlbum=""; $MediaInfoGenre=""; $MediaInfoYear=""; $MediaInfoComposer=""; $MediaInfoLabel=""; $MediaInfoValue=""; foreach $ShellCommandResultLine ( @MediaInfoResultArray ) { #print "ShellCommandResultLine=$ShellCommandResultLine\n"; ($MediaInfoLabel, $MediaInfoValue)= split ( ":", $ShellCommandResultLine,2); if ( $MediaInfoValue ) { if ( $MediaInfoValue ne "" ) { $MediaInfoValue =~ s/^ //g; $MediaInfoLabel =~ s/\ //g; #print "Label=$MediaInfoLabel, Value=$MediaInfoValue.\n"; if ( $MediaInfoLabel eq "Performer" ) { # print "Label=$MediaInfoLabel, Value=$MediaInfoValue.\n"; $MediaInfoPerformer=$MediaInfoValue; } if ( $MediaInfoLabel eq "Composer" ) { # print "Label=$MediaInfoLabel, Value=$MediaInfoValue.\n"; $MediaInfoComposer=$MediaInfoValue; } if ( $MediaInfoLabel eq "Album" ) { #print "Label=$MediaInfoLabel, Value=$MediaInfoValue.\n"; $MediaInfoAlbum=$MediaInfoValue; } if ( $MediaInfoLabel eq "Genre" ) { #print "Label=$MediaInfoLabel, Value=$MediaInfoValue.\n"; $MediaInfoGenre=$MediaInfoValue; } if ( $MediaInfoLabel =~ "Recordeddate" ) { #print "Label=$MediaInfoLabel, Value=$MediaInfoValue.\n"; $MediaInfoYear=$MediaInfoValue; } } } } $dstFileMP3Abs = $dstDirAbs . "/" . $srcFileDirRel . "/" . $srcFilename . ".mp3"; $dstFileMP3Abs =~ s/\/\//\//g; # # check if the mp3 file already exists and proceed only if user wants it overwritten if ( -e $dstFileMP3Abs && $Overwrite eq "No" ) { if ($debug eq "on") { print "File already exists and we are going to leave it -f=$Overwrite.\n" }; } else { # We need to create an mp3 file # # Lets work out the Album and Artist name from the names of the directories # @paths = split(/\//, $srcFileDirRel); if ($debug eq "on") { print "srcFileDirRel=$srcFileDirRel all=@paths\n" }; $albumName=""; $artistName=""; $i=0; foreach $pathPart ( @paths ) { if ($debug eq "on") { print "i=$i path = $paths[$i] pathPart=$pathPart\n" }; if ($i > 0 ) { $albumName=$paths[$i]; # replace -- with - $albumName =~ s/--/-/g; $albumName =~ s/--/-/g; $albumName =~ s/--/-/g; # $artistName=$paths[$i-1]; $artistName =~ s/--/-/g; $artistName =~ s/--/-/g; $artistName =~ s/--/-/g; } $i=$i+1; #$albumName = '"' + $albumName + '"'; #$artistName = '"' + $artistName + '"'; } if ($debug eq "on") { print "albumName=$albumName artistName=$artistName\n" }; # So we now have the album and artist name # # If the audio file is an m4a or mp4 then we first convert it to a flac file # if ( $srcFileExtension eq ".flac" || $srcFileExtension eq ".FLAC" ) { # If .flac we first need to convert it to a .wav file # Need to a new destination filename with .wav $dstFileWAVAbs = $dstDirAbs . "/" . $srcFileDirRel . "/" . $srcFilename . ".wav"; $dstFileWAVAbs =~ s/\/\//\//g; # -d decode # -f overwrite destination file # -s run silently # -o write ouput to file @Args = ("flac", "-d", "-f", "-s", "-o", $dstFileWAVAbs, $srcFileAbs ); if ($debug eq "on") {print "Going to @Args\n"}; if ($Silent eq "No") { print "Creating $dstFileWAVAbs intermediate step to make mp3\n" }; ShellCommandSub; $srcFileAbs = $dstFileWAVAbs; if ($debug eq "on") { print "New srcFileAbs=$srcFileAbs\n" }; } if ( $srcFileExtension eq ".m4a" || $srcFileExtension eq ".M4A" || $srcFileExtension eq ".mp4" || $srcFileExtension eq ".MP4" ) { # Need to a new destination filename with flac. $dstFileWAVAbs = $dstDirAbs . "/" . $srcFileDirRel . "/" . $srcFilename . ".flac"; $dstFileWAVAbs =~ s/\/\//\//g; $dstFileText = EscapeSpecialCharactersSub($dstFileWAVAbs ); $srcFileText = EscapeSpecialCharactersSub( $srcFileAbs ); @Args = ("avconv -y -i $srcFileText $dstFileText" ); if ($debug eq "on") {print "Going to @Args\n"}; if ($Silent eq "No") { print "Creating $dstFileWAVAbs intermediate step to make mp3\n" }; ShellCommandSub; $srcFileAbs = $dstFileWAVAbs; $srcFileExtension = ".flac"; if ($debug eq "on") { print "New srcFileAbs=$srcFileAbs\n" }; # Need to a new destination filename with .wav $dstFileWAVAbs = $dstDirAbs . "/" . $srcFileDirRel . "/" . $srcFilename . ".wav"; $dstFileWAVAbs =~ s/\/\//\//g; # -d decode # -f overwrite destination file # -s run silently # -o write ouput to file @Args = ("flac", "-d", "-f", "-s", "-o", $dstFileWAVAbs, $srcFileAbs ); if ($debug eq "on") {print "Going to @Args\n"}; if ($Silent eq "No") { print "Creating $dstFileWAVAbs intermediate step to make mp3\n" }; ShellCommandSub; @Args = ("rm", $srcFileAbs ); if ($debug eq "on") {print "Going to @Args\n"}; ShellCommandSub; $srcFileAbs = $dstFileWAVAbs; if ($debug eq "on") { print "New srcFileAbs=$srcFileAbs\n" }; } # If audio file is .wma then we first have to convert to .wav # if ( $srcFileExtension eq ".wma" || $srcFileExtension eq ".WMA" ) { # If .wma we first need to convert it to a .wav file # Need to a new destination filename with .wav $dstFileWAVAbs = $dstDirAbs . "/" . $srcFileDirRel . "/" . $srcFilename . ".wav"; $dstFileWAVAbs =~ s/\/\//\//g; # $dstFileWAVAbs =~ s/\,//g; # $dstFileWAVAbs =~ s/\+/\\+/g; # # mplayer arguments # -vo null = no video output # -vc dummy = no video codec # -af resample=44100 = set audio filter to typical CD quality # -ao pcm:waveheader = Audio Driver is PCM with the waveheader # file= = write the output to filename # -nolirc Turns off LIRC support. # -really-quiet = run without any output to shell # look at using -lavcopts acodec=wmav1 wmav1 or wmav2 @Args = ("mplayer", "-nolirc", "-really-quiet", "-vo", "null", "-vc", "null", "-af", "resample=44100", "-ao", "pcm:waveheader:file=$dstFileWAVAbs", $srcFileAbs ); if ($debug eq "on") {@Args = ("mplayer", "-nolirc", "-vo", "null", "-vc", "null", "-af", "resample=44100", "-ao", "pcm:waveheader:file=$dstFileWAVAbs", $srcFileAbs ) }; if ($debug eq "on") {print "DEBUG: Going to @Args\n"}; if ($Silent eq "No") { print "Creating $dstFileWAVAbs intermediate step to make mp3\n" }; ShellCommandSub; $srcFileAbs = $dstFileWAVAbs; if ($debug eq "on") { print "New srcFileAbs=$srcFileAbs\n" }; } # Now we use LAME to convert to mp3 # # -S run silent # -h highest quality # -b bit rate # (default) joint stereo $songTitle = $srcFilename; if ( $MediaInfoPerformer eq "" ) { $MediaInfoPerformer = $artistName; } if ( $artistName eq "" || $albumName eq "" ) { if ( $VBR eq "" ) { @Args = ("lame", "-S", "-h", "--ta", $MediaInfoPerformer, "--ty", $MediaInfoYear, "--tg", $MediaInfoGenre, "--tt", $songTitle, "-b $bitRate", $srcFileAbs, $dstFileMP3Abs); } else { @Args = ("lame", "-S", "-h", "--ta", $MediaInfoPerformer, "--ty", $MediaInfoYear, "--tg", $MediaInfoGenre, "--tt", $songTitle, $VBR, $srcFileAbs, $dstFileMP3Abs); } } else { if ( $VBR eq "" ) { @Args = ( "lame", "-S", "-h", "--ta", $MediaInfoPerformer, "--ty", $MediaInfoYear, "--tg", $MediaInfoGenre, "--tl", $albumName, "--tt", $songTitle, "-b" , $bitRate, $srcFileAbs, $dstFileMP3Abs); } else { @Args = ( "lame", "-S", "-h", "--ta", $MediaInfoPerformer, "--ty", $MediaInfoYear, "--tg", $MediaInfoGenre, "--tl", $albumName, "--tt", $songTitle, $VBR, $srcFileAbs, $dstFileMP3Abs); } } if ($debug eq "on") {print "Going to @Args\n"}; if ($Silent eq "No") { print "Creating $dstFileMP3Abs\n" }; ShellCommandSub; if ($debug eq "on") { print "Converted file -f=$Overwrite.\n" }; if ($emailTo ne "" ) { $EMailSubLog="$EMailSubLog
\nCreated $dstFileMP3Abs" }; # # Remember we created an mp3 file and its absolute filename so we can add # graphic file to it later $WasAtLeastOneMP3Created="YES"; @mp3sToAddGraphicTo = ( @mp3sToAddGraphicTo, $dstFileMP3Abs ); # }; # So that changeing the owner and permissions work: $dstFileAbs = $dstFileMP3Abs; # If an interim WAV file was created delete it now if ( -e $dstFileWAVAbs ) { @Args = ( "rm", $dstFileWAVAbs); ShellCommandSub; } # } else { # This is a not an audio file, # # Check to see if it is a graphic and resize it into Folder.jpg if it is larger than the existing Folder.jpg # if ( $srcFileExtension eq ".jpg" || $srcFileExtension eq ".JPG" || $srcFileExtension eq ".jpeg" || $srcFileExtension eq ".JPEG" || $srcFileExtension eq ".gif" || $srcFileExtension eq ".GIF" ) { # Build up the absolute filename for destination Folder.jpg $dstFileImage = $dstDirAbs . "/" . $srcFileDirRel . "/" . "Folder.jpg"; $dstFileImage =~ s/\/\//\//g; # In the following block we copy the file to the new location, unless it is Folder.jpg if ( $dstFileImage ne $dstFileAbs ) { # The source is not the same as the destination Folder.jpg # if ( -e $dstFileAbs && $Overwrite eq "No" ) { # The destination already exists and we are not going to replace it # if ($debug eq "on") { print "File already exists (image) $dstFileAbs\n" }; if ($Silent eq "No") { print "File already exists (image) $dstFileAbs\n" }; } else { # If we get here we want to copy the original graphic file to the new location # @Args = ("cp", "-f", $srcFileAbs, $dstFileAbs); ShellCommandSub; # # Now we set the permissions and owner if ( $Owner ne "" ) { @Args = ("chown", "$Owner", $dstFileAbs); ShellCommandSub; } # Now we set the permissions and group if ( $Group ne "" ) { @Args = ("chgrp", "$Group", $dstFileAbs); ShellCommandSub; } if ( $Permissions ne "" ) { @Args = ("chmod", $Permissions, $dstFileAbs); ShellCommandSub; } if ($debug eq "on") { print "Copied the file from $srcFileAbs $dstFileAbs -f=$Overwrite.\n" }; if ($Silent eq "No") { print "Copied $dstFileAbs\n" }; if ($emailTo ne "" ) { $EMailSubLog="$EMailSubLog
\nCopied $dstFileAbs" }; } } # # In the following block we # resize the graphic and # test if it is bigger than the existing Folder.jpg # and make a Folder.jpg # # First create a temporary resized graphic $i = $dstDirAbs . "/" . $srcFileDirRel . "/" . "FolderTemp.jpg"; $i =~ s/\/\//\//g; # replace // with / if ($debug eq "on") { print "About to resize $srcFileAbs to $i\n" }; @Args = ("convert", $srcFileAbs, "-resize", "200x200!", $i ); ShellCommandSub; # if ( -e $dstFileImage ) { $fileSize1 = -s "$i"; } else { $fileSize1 = 0; } if ( -e $dstFileImage ) { $fileSize2 = -s "$dstFileImage"; } else { $fileSize2 = 0; } # We checked above that $dstFileImage (destination Folder.jpg) exists otherwise # -s $dstFileImage will return a warning from Perl if ( ( $fileSize1 > $fileSize2 ) || !( -e $dstFileImage ) ) { # So this temporary graphic is a larger (-s size) than the existing Folder.jpg # or Folder.jpg does not exist # so we will replace the existing Folder.jpg with this one # if ($debug eq "on") { print "About to move $i to $dstFileImage because $fileSize1 > $fileSize2.\n" }; @Args = ("mv", "-f", $i, $dstFileImage ); ShellCommandSub; # # Now we set the permissions and owner if ( $Owner ne "" ) { @Args = ("chown", "$Owner", $dstFileImage); ShellCommandSub; } # Now we set the permissions and group if ( $Group ne "" ) { @Args = ("chgrp", "$Group", $dstFileImage); ShellCommandSub; } if ( $Permissions ne "" ) { @Args = ("chmod", $Permissions, $dstFileImage); ShellCommandSub; } if ($debug eq "on") { print "Resized $srcFileAbs to 200x200 $dstFileImage -f=$Overwrite.\n" }; if ($Silent eq "No") { print "Resized $srcFileAbs to 200x200 Folder.jpg\n" }; if ($emailTo ne "" ) { $EMailSubLog="$EMailSubLog
\nCreated Folder.jpg from resizing $srcFileAbs." }; # } else { # Delete the temporary 200x200 graphic @Args = ("rm", $i ); ShellCommandSub; # if ($debug eq "on") { print "A better Folder.jpg already exists because $fileSize1 < $fileSize2..\n" }; if ($Silent eq "No" && $dstFileImage eq $dstFileAbs ) { print "Not moving Folder.jpg because a better Folder.jpg already exists.\n" }; } # } elsif ( -e $dstFileAbs && $Overwrite eq "No") { # So it is not an audio or graphic so it is some general file and # the destination file already exists and we are not going to overwrite it. # if ($debug eq "on") { print "File already exists and we are going to leave it -f=$Overwrite.\n" }; if ($Silent eq "No") { print "File already exists $dstFileMP3Abs\n" }; } else { # We are going to move or overwite the destination file with the source # @Args = ("cp", "-f", $srcFileAbs, $dstFileAbs); ShellCommandSub; # Now we set the permissions and owner if ( $Owner ne "" ) { @Args = ("chown", $Owner, $dstFileAbs); ShellCommandSub; } # Now we set the permissions and owner if ( $Group ne "" ) { @Args = ("chgrp", $Group, $dstFileAbs); ShellCommandSub; } if ( $Permissions ne "" ) { @Args = ("chmod", $Permissions, $dstFileAbs); ShellCommandSub; } # if ($debug eq "on") { print "Copied the file from $srcFileAbs $dstFileAbs -f=$Overwrite.\n" }; if ($Silent eq "No") { print "Copied $dstFileAbs\n" }; if ($emailTo ne "" ) { $EMailSubLog="$EMailSubLog
\nCopied $dstFileAbs" }; }; }; }; }, $srcDirAbs; if ( $AddArtWorkToAll eq "Yes" ) { # This is a special section that re-applies the graphics to all the music files find sub { $srcFileAbs = $File::Find::name; # sanatise characters that can trigger a specific meaning if ($debug eq "on") { print "DEBUG: file to add artwork to=$srcFileAbs\n" }; ($srcFilename, $srcFilePathAbs, $srcFileExtension) = fileparse( $srcFileAbs, qr/\.[^.]*/); $dstFileImage = $srcFilePathAbs . "Folder.jpg"; if ( $srcFileExtension eq ".mp3" && ! -e $dstFileImage) { # So there is no Folder.jpg, so we can not add it to the mp3. if ($Silent eq "No") { print "There is no Folder.jpg in $srcFilePathAbs\n" }; if ($emailTo ne "" ) { $EMailSubLog="There is no Folder.jpg in $srcFilePathAbs, try to find an imageand put it there.
\n$EMailSubLog" }; } if ( $srcFileExtension eq ".mp3" && -e $dstFileImage) { # $dstFileText = EscapeSpecialCharactersSub( $dstFileImage ); $srcFileText = EscapeSpecialCharactersSub( $srcFileAbs ); @Args = ("eyeD3 --to-v2.3 --add-image=$dstFileText:FRONT_COVER $srcFileText >/dev/null"); ShellCommandSub; if ($Silent eq "No") { print "Added $dstFileImage to $srcFileAbs\n" }; if ($emailTo ne "" ) { $EMailSubLog="$EMailSubLog
\nAdded $dstFileImage to $srcFileAbs" }; } }, $dstDirAbs; } else { if ( $WasAtLeastOneMP3Created eq "YES" ) { # At some point we created an mp3 file so we will go through the list of new ones and add # a graphic to them # foreach $srcFileAbs ( @mp3sToAddGraphicTo ) { # # sanatise characters that can trigger a specific meaning if ($debug eq "on") { print "DEBUG: Going to add album art to $srcFileAbs\n" }; # ($srcFilename, $srcFilePathAbs, $srcFileExtension) = fileparse( $srcFileAbs, qr/\.[^.]*/); $dstFileImage = $srcFilePathAbs . "Folder.jpg"; if ( $srcFileExtension eq ".mp3" && ! -e $dstFileImage) { # There is no Folder.jpg to add as a graphic to the mp3 file. if ($Silent eq "No") { print "There is no Folder.jpg in $srcFilePathAbs\n" }; if ($emailTo ne "" ) { $EMailSubLog="There is no Folder.jpg in $srcFilePathAbs, try to find an imageand put it there.
\n$EMailSubLog" }; } if ( $srcFileExtension eq ".mp3" && -e $dstFileImage) { $dstFileText = EscapeSpecialCharactersSub( $dstFileImage ); $srcFileText = EscapeSpecialCharactersSub( $srcFileAbs ); @Args = ("eyeD3 --to-v2.3 --add-image=$dstFileText:FRONT_COVER $srcFileText >/dev/null"); ShellCommandSub; # Now we set the permissions and owner if ( $Owner ne "" ) { @Args = ("chown", $Owner, $dstFileAbs); ShellCommandSub; } # Now we set the permissions and owner if ( $Group ne "" ) { @Args = ("chgrp", $Group, $dstFileAbs); ShellCommandSub; } if ( $Permissions ne "" ) { @Args = ("chmod", $Permissions, $dstFileAbs); ShellCommandSub; } if ($Silent eq "No") { print "Added $dstFileImage to $srcFileAbs\n" }; if ($emailTo ne "" ) { $EMailSubLog="$EMailSubLog
\nAdded Folder.jpg to $srcFileAbs" }; } } } } if ($emailTo ne "" ) { if ( $EMailSubLog eq "" ) { $EMailSubLog = "Nothing changed, no mp3 files were created."; } EMailSub($EMailSubLog); }