#1 2023-02-14 01:42

visusys
Member
Registered: 2021-10-16
Posts: 20

Does anyone have a master preset that will bulk rename mp3, flac, wma?

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

#2 2023-02-14 04:07

visusys
Member
Registered: 2021-10-16
Posts: 20

Re: Does anyone have a master preset that will bulk rename mp3, flac, wma?

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

#3 2023-02-14 06:50

visusys
Member
Registered: 2021-10-16
Posts: 20

Re: Does anyone have a master preset that will bulk rename mp3, flac, wma?

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:

Icon.zip

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

#4 2023-02-14 23:28

jogiwer
Member
From: Germany
Registered: 2022-11-05
Posts: 66

Re: Does anyone have a master preset that will bulk rename mp3, flac, wma?

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 wink

Offline

#5 2023-02-15 02:43

visusys
Member
Registered: 2021-10-16
Posts: 20

Re: Does anyone have a master preset that will bulk rename mp3, flac, wma?

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

Board footer

Powered by FluxBB