Skip to content

Instantly share code, notes, and snippets.

@mansouryaacoubi
Last active November 8, 2021 10:28
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 mansouryaacoubi/1efef8986a0039020924f835f5b85d3e to your computer and use it in GitHub Desktop.
Save mansouryaacoubi/1efef8986a0039020924f835f5b85d3e to your computer and use it in GitHub Desktop.
Change ID3 Info and Rename Files (MP3)

Usage

Just copy your project folder into your music-directory and execute the following:

Once:

composer install

Everytime you want to rename mp3s:

php rename.php
{
"name": "mya/rename",
"require": {
"james-heinrich/getid3": "^1.9"
},
"authors": [
{
"name": "Mansour Yaacoubi",
"email": "info@yaacoubi.com"
}
]
}
<?php
require 'vendor/autoload.php';
$base = array_key_exists(1, $argv) ? $argv[1] : './';
$files = array_diff(scandir($base), [ '.', '..', basename(__DIR__) ]);
$encoding = 'UTF-8';
// Initialize getID3 engine
$getID3 = new getID3;
$getID3->setOption(compact('encoding'));
foreach( $files as $file ) {
if( is_dir($base.$file) || !str_ends_with(strtolower($file), '.mp3') ) continue;
[ $artist, $title ] = explode('-', getNormalFileName($file));
$artist = getArtistArray($artist);
$title = getTitleArray($title);
$newFileName = implode(' ft ', $artist) . ' - ' . implode(', ', $title) . '.mp3';
renameTags($base.$file, $title, $artist); // Rename Tags
rename($base.$file, $base.$newFileName); // Rename Filename
}
function str_ends_with($haystack, $needle)
{
return strrpos($haystack, $needle) + strlen($needle) ===
strlen($haystack);
}
function getNormalFileName($file)
{
$file = strtolower($file);
$file = str_replace([ '_', '.mp3' ], ' ', $file);
$file = preg_replace("/\([^)]+\)/", '', $file);
return $file;
}
function getArtistArray($artist)
{
$artist = str_replace( [ ' ft. ', ' ft ', ' feat. ', ' feat ', '&', ' et ', ' and ' ], ', ', $artist );
$artist = explode( ',', $artist );
$artist = array_map('trim', $artist);
$artist = array_map('ucwords', $artist);
$artist = preg_replace('!\s+!', ' ', $artist);
return $artist;
}
function getTitleArray($title)
{
$title = explode( ',', $title );
$title = array_map('trim', $title);
$title = array_map('ucwords', $title);
$title = preg_replace('!\s+!', ' ', $title);
return $title;
}
function renameTags($file, $title, $artist)
{
global $encoding;
if( !$title ) $title = null;
elseif( !is_array($title) ) $title = [ $title ];
if( !$artist ) $artist = null;
elseif( !is_array($artist) ) $artist = [ $artist ];
$tag_data = [
'comment' => ['Tagged by Yaacoubi.com'],
'popularimeter' => ['email' => 'id3@yaacoubi.com', 'rating' => 128, 'data' => 0],
'unique_file_identifier' => ['ownerid'=>'id3@yaacoubi.com', 'data' => md5(time()) ],
];
$tagwriter = new getid3_writetags;
$tagwriter->filename = $file;
$tagwriter->tagformats = [ 'id3v2.3' ];
$tagwriter->overwrite_tags = true;
$tagwriter->tag_encoding = $encoding;
$tagwriter->remove_other_tags = true;
if($title) $tag_data['title'] = $title;
if($artist) $tag_data['artist'] = $artist;
$tagwriter->tag_data = $tag_data;
// write tags
if ( $tagwriter->WriteTags() ) {
$ttl = implode(', ', $title);
$art = implode(', ', $artist);
echo 'Successfully wrote tags ' . "($ttl by $art)" .PHP_EOL;
if (!empty($tagwriter->warnings)) {
echo 'There were some warnings:'.PHP_EOL.implode(PHP_EOL.PHP_EOL, $tagwriter->warnings);
}
} else {
echo 'Failed to write tags!'.PHP_EOL.implode(PHP_EOL.PHP_EOL, $tagwriter->errors);
}
}
?>
@mansouryaacoubi
Copy link
Author

Of course there is a lot of room for improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment