#!/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