Skip to content

Instantly share code, notes, and snippets.

@kmark
Last active January 20, 2017 08:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmark/6959258 to your computer and use it in GitHub Desktop.
Save kmark/6959258 to your computer and use it in GitHub Desktop.
Finds low quality songs in a directory based on a minimum bit rate. Tested with PHP 5.5.4. Find MediaInfo at mediaarea.net. I don't rely on MediaInfo for the recursion because it uses a fuckton of memory trying to do it.
<?php
/*******************************************************************************
* Copyright 2013 Kevin Mark *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
*******************************************************************************/
// Finds low quality songs in a directory based on a minimum bit rate
// Tested with PHP 5.5.4
// MediaInfo -> mediaarea.net
// I don't rely on MediaInfo for the recursion because it uses a fuckton of memory trying to do it.
// Directory to search
$directory = "/Users/kmark/Music/iTunes/iTunes Media/Music";
// Minimum overall bit rate in Kbps
$minQuality = 256;
// Path to mediainfo
$mediainfo = "/usr/local/bin/mediainfo";
// Shorten output?
$doShortenPath = true;
// If MP3 and LAME-encoded ignore bit rate on files that match this encoding settings regex
// Set null to disable
$lameIgnore = '/-V ?0/i'; // Skips -V 0 files
// If MP3 and LAME-encoded AND it fails the above check output the encoding settings too
$outEncSettings = true;
error_reporting(E_ALL ^ E_NOTICE);
if(!file_exists($directory) && !is_readable($directory)) {
exit("Cannot read from $directory\r\n");
}
$recursiveDirectory = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS));
$RegexIterator = new RegexIterator($recursiveDirectory, '/^.+\.(?:mp4|m4a|aac|mp3|aiff|wav)$/i', RecursiveRegexIterator::GET_MATCH);
foreach($RegexIterator as $path) {
$path = $path[0];
// May have problems if $mediainfo or $path includes quotes
$output = shell_exec("\"$mediainfo\" \"$path\"");
if($output == null) {
exit("MediaInfo shell_exec failed on $path\r\n");
}
if(preg_match('/^Overall bit rate +: ([\d.]+ Kbps)/im', $output, $bitrate)) {
$bitrate = (int)$bitrate[1];
if($bitrate < $minQuality) {
if($lameIgnore != null) {
if(preg_match('/^Encoding settings +: (-.+)$/im', $output, $encodingSettings)) {
if(preg_match($lameIgnore, $encodingSettings[1])) {
continue;
}
}
}
echo "$bitrate Kbps : " . shortenPath($path) .
(isset($encodingSettings[1]) && $outEncSettings ? (" [".$encodingSettings[1]."]") : ("")) . "\r\n";
}
continue;
}
// Uncomment this if you're concerned. Bit rate probably displayed in Mbps or not shown at all
//exit("Mediainfo regex parsing failed on $path\r\n");
}
function shortenPath($fullpath) {
if(!$GLOBALS["doShortenPath"]) {
return $fullpath;
}
// Crude but effective
return substr($fullpath, strlen($GLOBALS["directory"]) + 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment