#!/usr/bin/perl ## ## Author: David McKeon <@bonzoli.com> ## URL: http://bonzoli.com ## Program: check_mp3 ## Creation Date: Date: 2007/01/30 19:54:04 PST ## Last Revision: $Date$ ## Version: v.5 ## ############################################################################# # David McKeon <@bonzoli.com> http://bonzoli.com # # # # Copyright (C) 2007-2007 David McKeon. All rights reserved. # # # # 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 2 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. # # # # You should have received a copy of the GNU General Public License along # # with this program; if not, write to: # # # # Free Software Foundation, Inc. # # 59 Temple Place - Suite 330 # # Boston, MA 02111-1307, USA. # # # # Or you can find the full GNU GPL online at: http://www.gnu.org # # # ############################################################################# ## Category: Perl ## ## ## ## ## # $| = 1; my $USAGE="Usage: check_mp3 NOTE: *.mp3 works \n"; my $file; if (! $ARGV[0]) { print "$USAGE\n"; exit; } use Getopt::Long; use File::Basename; my $debug=0; # Location to mpg123, we use this to test the mp3 files for errors. my $MPG123='/usr/local/bin/mpg123'; #--------------------------------------------------------------------------- Getopt::Long::Configure("no_ignore_case"); GetOptions( "h|help" => \$help, "V|version" => \$vers, #----------------------- ); #--------------------------------------------------------------------------- if($help){ exec("perldoc $0"); } if($vers){ version(); } #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- sub version { my($date) = "\$Date$_"; my($rvsn) = "\$Revision$_"; my($rcsd) = "\$Id$_"; $date =~ s/(.*: +)(.*?)(\s*$)/$2/g; $rvsn =~ s/(.*: +)(.*?)(\s*$)/$2/g; $rcsd =~ s/(.*: +)(.*?)(\s*$)/$2/g; print < URL: http://bonzoli.com Creation Date: 2007/01/30 17:54:04 GMT Last Revision: $date GMT Revision: $rcsd Copyright (C) 2007-2007 David McKeon. All rights reserved. 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 2 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. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA. Or you can find the full GNU GPL online at: http://www.gnu.org EOF exit; } sub shellify_string { ########################################################################## # FUNCTION DEFINITIONS #------------------------------------------------------------------------- # FUNCTION shellify_string # RECEIVES $string # RETURNS $string # DOES Going to make this line readable by shell, so mv's and copies work. # add a backslash before unusual characters my ( $file ); # shouldn't just shift work here? $file = shift @_; #print "my file is $file \n"; #If its not one of these characters put a \ in front of it. $file =~ s|[^-a-zA-Z0-9_.,/]|\\$&|g; # backslash newline gets ignored by sh, so we have to use quotes. $file =~ s|\\\n|'\n'|g; # make sure name doesn't have a leading - $file =~ s|^-|./-|; # null name is unprintable, make it '.' if ($file eq '') { $file = "."; } return $file; } ##MAIN####################################################################### print "HERE\n"; foreach $file (@ARGV) { # Non shellified version of file my $PFILE=$file; my $COUNT1=0; my $COUNT2=0; my $COUNT3=0; my ($name,$path,$suffix) = fileparse($file,''); if ($name=~/^.\/bad_/) { print "Skipping, already marked bad\n" if ($debug >= 1); next; } if ($file=~/\.[Mm][Pp]3$/ && !($name=~/bad_/)) { print "FILE=$file\n"; my $PFILE=shellify_string($PFILE); print "PFILE=$PFILE\n"; #$CMD="/usr/local/bin/mpg123 -t $file /tmp/mp3test.out"; print "Checking--->$PFILE\n" if ($debug >= 1); open ( ERRCHK,"$MPG123 -t $PFILE 2>&1|") || die "Error Couldn't Open File: $!"; while ( ) { if (/Can\'t find frame start/) { print "Not a MP3 Mark bad::: $_\n" if ($debug >= 2); # Basically this isn't an mp3 or its 0bytes. # Force a bad on this. $COUNT3=++$COUNT3; } if (/Searching for next FF header/) { print "SKIPPED::: $_\n" if ($debug >= 2); # Skipped 290 bytes in input. = audible skip #Searching for next FF header $COUNT3=++$COUNT3; } if (/Skipped \d+ bytes in input./) { print "SKIPPED::: $_\n" if ($debug >= 2); # Skipped 290 bytes in input. = audible skip #Searching for next FF header $COUNT2=++$COUNT2; } if (/Illegal Audio-MPEG-Header/) { $COUNT1=++$COUNT1; } } close ERRCHK; # Basically any more then 1 skip in a file sucks, so we mark it bad. if ($COUNT1>2 ||$COUNT2>1 || $COUNT3>0) { print "BADFILE=>$name,$path,$suffix\n" if ($debug >= 1); print "-->FOUND $COUNT1 BAD HEADERS, Skipped $COUNT2 and $COUNT3 FF errors, in $file.\n" if ($debug >= 1); # Its found bad, we are going to append bad_ to the head of file $name=~s/^/bad_/g; my $NEWFILE=$path.$name; print "renaming $file, $NEWFILE\n" if ($debug >= 1); rename $file, $NEWFILE; $file=$NEWFILE; } } } ##END MAIN####################################################################### #--------------------------------------------------------------------------- ## ## Use "perldoc check_mp3" to read the man page below. # __END__ =head1 NAME B - checks mp3 files for errors, renaming them to bad_(filename). =head1 SYNOPSIS B S<[ B<-hv> ]> S<[ I ]> =head1 DESCRIPTION B checks mp3 files then renames them to bad_(filename). This is nice especially if (you have a lot of files, but forgot which one was skipping on your mp3 player, this will probably find it for you. =head1 QUICK START The most common usage is as follows: B filename.mp3 B *.mp3 =head1 STANDARD OPTIONS B<-h --help> Prints this information. B<-v --version> Prints version information. =head1 OPTIONS =head1 EXAMPLE The example below B I<*.mp3> =head1 BUGS None. =head1 SEE ALSO check_mp3, sort_flacs, sort_mp3s, sort_oggs, sort_wmas =head1 AUTHOR AND COPYRIGHT David McKeon <@bonzoli.com> http://bonzoli.com Copyright (C) 2007-2007 David McKeon. All rights reserved. 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 2 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. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA. Or you can find the full GNU GPL online at: http://www.gnu.org =head1 VERSION Current Revision: v.5 Last Modification: $Date$ =pod SCRIPT CATEGORIES UNIX/System_administration =pod OSNAMES Any