Skip to content

Instantly share code, notes, and snippets.

@rkaiser0324
Last active March 2, 2021 17:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkaiser0324/bed0eb7718dfb0d691f767b9f0289924 to your computer and use it in GitHub Desktop.
Save rkaiser0324/bed0eb7718dfb0d691f767b9f0289924 to your computer and use it in GitHub Desktop.
PHP script to organize a music directory based on tags - see https://blog.echothis.com/2021/02/24/organizing-a-large-music-library-in-2021/
<?php
/**
* mp3move.php </path/to/source/root/to/scan> </path/to/dest/root>
*
* No trailing slashes on destination.
*
* 1) Tested on CentOS 7 only
* 2) Install ffmpeg per https://linuxize.com/post/how-to-install-ffmpeg-on-centos-7/
*
*/
if (empty($argv[2])) {
throw new exception("Provide source and destination paths");
}
$sourcepath = $argv[1];
if (!is_dir($sourcepath)) {
throw new exception("Invalid source path");
}
$destpath = $argv[2];
if (!is_dir($destpath)) {
throw new exception("Invalid destination path");
}
// Using the RecursiveIterator on Docker with a Windows host is unreliable for large directories, so do this instead
exec("find '$sourcepath' -print", $files, $result_code);
$i = 0;
foreach ($files as $file) {
if (is_dir($file)) {
continue;
}
$i++;
move($file, $destpath, $i, count($files));
}
function move($el, $destpath, $i, $total)
{
try {
printf("%s/%s - %s\n", $i, $total, $el);
unset($output);
$escaped = str_replace("'", "\\'", $el);
exec("ffmpeg -i \$'$escaped' 2>&1 |grep -E '^\s*artist\s*\:\s.*$' |awk -F ': ' '{print $2}'", $output, $result_code);
if (empty($output[0])) {
throw new exception("empty artist");
}
$artist = $output[0];
$path = $destpath . "/" . substr($artist, 0, 1) . "/" . $artist . "/";
unset($output);
exec("ffmpeg -i \$'$escaped' 2>&1 |grep -E '^\s*album\s*\:\s.*$' |awk -F ': ' '{print $2}'", $output, $result_code);
$album = '';
if (!empty($output[0])) {
$album = $output[0];
$path .= $album . "/";
}
if (!file_exists($path)) {
if (!mkdir($path, 0777, true)) {
throw new exception("Cannot create $path");
}
}
if (file_exists($path . basename($el))) {
// Delete the source file
if (!unlink($el)) {
throw new exception("Cannot delete ". $el);
}
} else {
if (!rename($el, $path . basename($el))) {
throw new exception("Cannot move file to " . $path . basename($el));
}
printf(" -> %s \n", $path . basename($el));
}
} catch (exception $ex) {
printf("\033[01;31m %s - %s \033[0m\n", $el, $ex->getMessage());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment