You are not logged in.
I want to rename a bunch of audio files in my music collection (some files are MP3, others FLAC, and others WMA).
I know you can insert tags with MP3_Artist, MP3_Title, WMA_Artist, WMA_Title, FLAC_Artist, FLAC_Title, etc.
I'm wondering if anyone here has a preset using either PascalScript (CalculateMetaTag), or just a bunch of well thought-out rules that can handle renaming of all audio file-types in one preset.
I'm guessing I could run CalculateMetaTag with the correct MetaTagName based on the file-name's extension. I'm just wondering if anyone has already authored a great media renaming preset so I don't have to re-invent the wheel.
Any help would be greatly appreciated!
Offline
Ok, so I decided to just tackle this myself today. I came up with two PascalScript Scripts.
The first one is simple, and just renames each media file as:
ARTIST - TRACK.EXTENSION
function RemoveIllegal(const S: WideString): WideString;
begin
Result := WideReplaceStr(S, ' / ', ', ');
Result := WideReplaceStr(Result, ' \ ', ', ');
Result := WideReplaceStr(Result, '/', ', ');
Result := WideReplaceStr(Result, '\', ', ');
Result := WideReplaceStr(Result, '<', ' ');
Result := WideReplaceStr(Result, '>', ' ');
Result := WideReplaceStr(Result, ':', ' ');
Result := WideReplaceStr(Result, '"', ' ');
Result := WideReplaceStr(Result, '|', ', ');
Result := WideReplaceStr(Result, '?', ' ');
Result := WideReplaceStr(Result, '*', ' ');
end;
var
FileExt: WideString;
NewFileName: WideString;
MediaArtist: WideString;
MediaAlbum: WideString;
MediaTitle: WideString;
MediaTrackNo: WideString;
begin
FileExt := WideExtractFileExt(FileName);
case FileExt of
'.mp3': begin
MediaArtist := CalculateMetaTag(FilePath, 'MP3_Artist');
MediaAlbum := CalculateMetaTag(FilePath, 'MP3_Album');
MediaTitle := CalculateMetaTag(FilePath, 'MP3_Title');
MediaTrackNo := CalculateMetaTag(FilePath, 'MP3_TrackNo');
end;
'.flac': begin
MediaArtist := CalculateMetaTag(FilePath, 'FLAC_Artist');
MediaAlbum := CalculateMetaTag(FilePath, 'FLAC_Album');
MediaTitle := CalculateMetaTag(FilePath, 'FLAC_Title');
MediaTrackNo := CalculateMetaTag(FilePath, 'FLAC_TrackNo');
end;
'.wma': begin
MediaArtist := CalculateMetaTag(FilePath, 'WMA_Artist');
MediaAlbum := CalculateMetaTag(FilePath, 'WMA_Album');
MediaTitle := CalculateMetaTag(FilePath, 'WMA_Title');
MediaTrackNo := CalculateMetaTag(FilePath, 'WMA_TrackNo');
end;
else
begin
MediaArtist := '';
MediaAlbum := '';
MediaTitle := '';
MediaTrackNo := '';
end;
end;
if (Length(MediaArtist) = 0) or (Length(MediaTitle) = 0) then
begin
NewFileName := FileName;
end
else
begin
// Remove any leading or trailing whitespace.
MediaArtist := Trim(MediaArtist);
MediaAlbum := Trim(MediaAlbum);
MediaTitle := Trim(MediaTitle);
// Remove and substitute illegal Windows characters.
MediaArtist := RemoveIllegal(MediaArtist);
MediaAlbum := RemoveIllegal(MediaAlbum);
MediaTitle := RemoveIllegal(MediaTitle);
// Remove trailing periods from the song title
// so we don't get double periods before the extension.
// I.E. B.Y.O.B..mp3 becomes B.Y.O.B.mp3
while (Length(MediaTitle) > 0) and (MediaTitle[Length(MediaTitle)] = '.') do
Delete(MediaTitle, Length(MediaTitle), 1);
// Build the new file name.
NewFileName := MediaArtist + ' - ' + MediaTitle + WideExtractFileExt(FileName);
end;
FileName := NewFileName;
end.
1. If the Artist or Title metadata isn't present in the file, the script aborts renaming the file.
2. The script automatically removes illegal characters that Windows will choke on.
The next one is more complicated, and renames files in "Album format". Or more specifically:
ARTIST - ALBUM - TRACKNO - TITLE.EXTENSION
Here is the code. It's commented for easier readability:
const
PAD_TO_LENGTH = 2;
// Functions dealing with padding the track number.
function CountDigits(const S: WideString; StartI: Integer): Integer;
var I: Integer;
begin
Result := 0;
for I:=StartI to WideLength(S) do
begin
if IsWideCharDigit(S[i]) then
Inc(Result)
else
Break;
end;
end;
function MakeZeros(Count: Integer): WideString;
var I: Integer;
begin
Result := '';
for I:=1 to Count do
Result := Result + '0';
end;
// Function to remove Illegal Windows characters from a string.
function RemoveIllegal(const S: WideString): WideString;
begin
Result := WideReplaceStr(S, ' / ', ', ');
Result := WideReplaceStr(Result, ' \ ', ', ');
Result := WideReplaceStr(Result, '/', ', ');
Result := WideReplaceStr(Result, '\', ', ');
Result := WideReplaceStr(Result, '<', ' ');
Result := WideReplaceStr(Result, '>', ' ');
Result := WideReplaceStr(Result, ':', ' ');
Result := WideReplaceStr(Result, '"', ' ');
Result := WideReplaceStr(Result, '|', ', ');
Result := WideReplaceStr(Result, '?', ' ');
Result := WideReplaceStr(Result, '*', ' ');
end;
var
FileExt: WideString;
NewFileName: WideString;
MediaArtist: WideString;
MediaAlbum: WideString;
MediaTitle: WideString;
MediaTrackNo: WideString;
Start, Count: Integer;
TrackNoExists: Boolean;
begin
FileExt := WideExtractFileExt(FileName);
case FileExt of
'.mp3': begin
MediaArtist := CalculateMetaTag(FilePath, 'MP3_Artist');
MediaAlbum := CalculateMetaTag(FilePath, 'MP3_Album');
MediaTitle := CalculateMetaTag(FilePath, 'MP3_Title');
MediaTrackNo := CalculateMetaTag(FilePath, 'MP3_TrackNo');
end;
'.flac': begin
MediaArtist := CalculateMetaTag(FilePath, 'FLAC_Artist');
MediaAlbum := CalculateMetaTag(FilePath, 'FLAC_Album');
MediaTitle := CalculateMetaTag(FilePath, 'FLAC_Title');
MediaTrackNo := CalculateMetaTag(FilePath, 'FLAC_TrackNo');
end;
'.wma': begin
MediaArtist := CalculateMetaTag(FilePath, 'WMA_Artist');
MediaAlbum := CalculateMetaTag(FilePath, 'WMA_Album');
MediaTitle := CalculateMetaTag(FilePath, 'WMA_Title');
MediaTrackNo := CalculateMetaTag(FilePath, 'WMA_TrackNo');
end;
else
begin
MediaArtist := '';
MediaAlbum := '';
MediaTitle := '';
MediaTrackNo := '';
end;
end;
if (Length(MediaArtist) = 0) or (Length(MediaTitle) = 0) or (Length(MediaAlbum) = 0) then
begin
NewFileName := FileName;
end
else
begin
// Remove all illegal Windows characters.
MediaArtist := RemoveIllegal(MediaArtist);
MediaAlbum := RemoveIllegal(MediaAlbum);
MediaTitle := RemoveIllegal(MediaTitle);
MediaTrackNo := RemoveIllegal(MediaTrackNo);
// Remove any leading or trailing whitespace.
MediaArtist := Trim(MediaArtist);
MediaAlbum := Trim(MediaAlbum);
MediaTitle := Trim(MediaTitle);
MediaTrackNo := Trim(MediaTrackNo);
// Remove trailing periods from the song title
// so we don't get double periods before the extension.
// I.E. B.Y.O.B..mp3 becomes B.Y.O.B.mp3
while (Length(MediaTitle) > 0) and (MediaTitle[Length(MediaTitle)] = '.') do
Delete(MediaTitle, Length(MediaTitle), 1);
if (Length(MediaTrackNo) = 0) then TrackNoExists := False
else TrackNoExists := True;
// Pad the track number to two leading zeros if it exists.
if TrackNoExists then
begin
Start := 1;
while Start < WideLength(FileName) do
begin
Count := CountDigits(MediaTrackNo, Start);
if (Count > 0) then
if (Count < PAD_TO_LENGTH) then
begin
WideInsert(MakeZeros(PAD_TO_LENGTH-Count), MediaTrackNo, Start);
Start := Start + PAD_TO_LENGTH;
end
else
Start := Start + Count
else
Inc(Start);
end;
end;
// Build the new filename. If the track number isn't supplied an
// alternative format is defined and used.
if TrackNoExists then
NewFileName := MediaArtist + ' - ' + MediaAlbum + ' - ' + MediaTrackNo + ' - ' + MediaTitle + WideExtractFileExt(FileName)
else
NewFileName := MediaArtist + ' - ' + MediaAlbum + ' - ' + MediaTitle + WideExtractFileExt(FileName);
end;
FileName := NewFileName;
end.
Notes:
1. All illegal Windows characters are removed or substituted.
2. Leading or trailing whitespace is removed from each metadata component.
3. Trailing periods from the song title are removed. For example, B.Y.O.B..mp3 becomes B.Y.O.B.mp3
4. If Artist, Title, or Album metadata is missing, the script aborts the rename.
5. If Artist, Title, and Album metadata exists but Track Number metadata doesn't exist, the script reverts to an alternative format (ARTIST - ALBUM - TITLE.EXTENSION)
6. If all metadata is present, the track number is padded with a leading zero if it isn't already two digits (Basically: 1-9 get leading zeros).
Hopefully some of you find this useful. I would be happy to extend, update, or revise the code if anyone here has suggestions or sees a way to improve the script. Or if there are bugs you find, let me know. PascalScript is not my forte, but I think I've managed to learn the basics.
As a side note, I am now working on a Powershell script with right-click shell integration to automatically create m3u playlist files in UTF8 format. So once you rename all your files, you can then select all your mp3/flac/wma files and then right click > generate m3u.
I'll also be creating a recursive variant that will generate m3u files for each folder within a supplied top-level folder that contains mp3/flac/wma files.
Once I complete this I'll post the Powershell scripts on here as well.
Again, feedback is welcome!
Jay
Edit 1: Improved the first script.
Last edited by visusys (2023-02-14 04:14)
Offline
I finished coding a quick Powershell script that will create a m3u file for a given folder.
You will need Powershell 7 installed, and execution policy set to "RemoteSigned".
Here is the script:
param (
[Parameter(Mandatory)]
[String]
$Directory,
[Parameter(Mandatory=$false)]
[String]
$M3UFilename
)
$M3UDirectory = [System.IO.DirectoryInfo]$Directory
Write-Host "`$M3UDirectory:" $M3UDirectory -ForegroundColor Green
$MediaFiles = [System.Collections.ArrayList]@()
$Files = $M3UDirectory.GetFiles()
$Files | ForEach-Object {
if($_ -match '\.(mp3|flac|wma|aiff|aif|wav|m4a|mp4|aac|ogg|alac)$'){
$MediaFiles.Add($_.Name)
}
}
$MediaFiles.Sort()
if($M3UFilename -eq ""){
$M3UFilename = "00 " + $M3UDirectory.BaseName + ".m3u"
}elseif ( ! $M3UFilename.EndsWith("m3u") ) {
$M3UFilename = "$M3UFilename.m3u"
}
$M3UFullname = Join-Path -Path $M3UDirectory -ChildPath $M3UFilename
if ( Test-Path $M3UFullname -PathType Leaf ) { Remove-Item $M3UFullname }
$MediaFilesStr = $MediaFiles -join [Environment]::NewLine
$MediaFilesStr | Out-File -Encoding UTF8 -FilePath $M3UFullname -NoNewline
Here is an example registry entry that will add a "Generate M3U from Directory" entry to your right-click context menu for all folders:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\01_GenerateM3UFromFolder]
@="Generate M3U from Directory"
"Icon"="\"C:\\Icons\\AudioPlaylistIcon.ico\""
[HKEY_CLASSES_ROOT\Directory\shell\01_GenerateM3UFromFolder\command]
@="pwsh.exe -File \"C:\\Powershell\\Scripts\\GenerateM3UFromFolder.ps1\" \"%L\""
"NeverDefault"=""
Here's an icon you can use:
Now, all you need to do to create a m3u file for any directory is just right click and select "Generate M3U from Directory".
Offline
Just a few notes without order - just as I spot them ...
If you do have different rules with partly the same functions you might think about putting them into an external file and include them with a line like "{$INCLUDE commons.pas}"
Do the trim after RemoveIllegal - or put it into the RemoveIllegal and name it like CleanUp
After all these replacements you might have multiple spaces or commas in your string. Trim won't shorten this. As a fan of regular expressions I would use
function CleanUp(const S: WideString): WideString;
begin
Result := ReplaceRegEx(S, ' *[/|\\] *', ', ', True, False);
Result := ReplaceRegEx(Result, '[<>:"?* ]+', ' ', True, False);
Result := Trim(Result);
end;
ReNamer also has rules for clean up. Just consider if prefer cleaning every part in advance or the resulting name at the end.
As I read another statement of Denis here: Performance of meta tag extraction each CalculateMetaTag might scan the file. This might get a performance issue.
Instead of MakeZeros you might use WideRepeatString('0', Count)
The outer loop for the padding is checking the length of FileName instead of MediaTrackNo
For the padding you might use FindRegEx(MediaTrackNo, '\d+', True, Positions, Matches) and Insert(WideRepeatString('0', PAD_TO_LENGTH-Length(Matches[0])), MediaTrackNo, Positions[0])
Put the padding into a function call as well as the addition of ' - ' if MediaTrackNo is not empty. Then you don't need TrackNoExists anymore.
I really like ReNamer for its features - but for organizing and renaming my audio files I prefer using foobar2000.
foobar2000 could also create playlist files
Offline
Great suggestions!
Thanks so much for looking over the code and taking the time to give some pointers. I agree with essentially everything and I'll update the code soon.
I've used foobar2000 in the past and it was good, but I have been using Winamp for almost 15 years now and find it super hard to switch since I'm so used to it. Maybe I'lll give Foobar another shot.
I do think the m3u script is useful though. It's really convenient to just right click on a folder > Generate M3U. I also have a variant that creates a m3u file from a selection of media files but it requires other dependencies to work so I didn't post it here.
Offline