Created
July 5, 2024 16:57
-
-
Save micycle1/10267acd358c745879963767101a5833 to your computer and use it in GitHub Desktop.
Groups flac or mp3 files into album folders, saving with appropriate filenames. Preserves singles.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ensure ffprobe is available in the system's PATH or specify its full path | |
$ffprobePath = "ffprobe" | |
$files = Get-ChildItem -Path "." -File | Where-Object { $_.Extension -eq ".mp3" -or $_.Extension -eq ".flac" } | |
Write-Host "Found $($files.Count) files to process." | |
# Store album information | |
$albums = @{} | |
foreach ($file in $files) { | |
# Use ffprobe to get file metadata | |
# Use the new ffprobe command | |
$output = & $ffprobePath -v error -select_streams a:0 -show_entries "stream=codec_name,bit_rate,channels,sample_rate : format=duration : format_tags : stream_tags" -of default=noprint_wrappers=1 "$file" 2>&1 | |
# Split the output into lines | |
$metadataLines = $output -split "`n" | |
#Write-Host $metadataLines | |
# Initialize variables to hold metadata | |
$albumName = $null | |
$albumArtist = $null | |
$artist = $null | |
$trackNumber = $null | |
$title = 0 | |
# Iterate over each line and extract the metadata based on the TAG: prefix | |
foreach ($line in $metadataLines) { | |
if ($line -match "^TAG:TITLE=(.+)") { | |
$title = $matches[1] | |
} elseif ($line -match "^TAG:ALBUM_ARTIST=(.+)") { | |
$albumArtist = $matches[1] | |
} elseif ($line -match "^TAG:ARTIST=(.+)") { | |
$artist = $matches[1] | |
} elseif ($line -match "^TAG:ALBUM=(.+)") { | |
$albumName = $matches[1] | |
} elseif ($line -match "^TAG:track=(.+)") { | |
$trackNumber = $matches[1] | |
} | |
} | |
# Handle missing album artist | |
if (-not $albumArtist) { | |
# $albumArtist = "Unknown Artist" | |
} | |
# Create album identifier | |
$albumID = "$albumArtist - $albumName" | |
if (-not $albumArtist -or $albumArtist -eq "") { | |
$albumID = $albumName | |
} | |
# Add track to album | |
if (-not $albums.ContainsKey($albumID)) { | |
$albums[$albumID] = @() | |
} | |
$albums[$albumID] += @{"file"=$file.FullName; "trackNumber"=$trackNumber; "title"=$title; "artist"=$artist} | |
} | |
# Write $albums object to console for debugging | |
Write-Host "" | |
Write-Host "=================================================" | |
Write-Host "" | |
Write-Host "Albums:" | |
foreach ($album in $albums.GetEnumerator()) { | |
# Check if the album has more than one track | |
if ($album.Value.Count -gt 1) { | |
Write-Host " Album: $($album.Key)" | |
foreach ($track in $album.Value) { | |
$trackDetails = "$($track.trackNumber) $($track.title)" | |
Write-Host " $trackDetails" | |
} | |
} | |
} | |
Write-Host "" | |
Write-Host "=================================================" | |
Write-Host "" | |
Write-Host "Organizing files into albums..." | |
# Process albums | |
foreach ($album in $albums.GetEnumerator()) { | |
# Process differently based on track count | |
if ($album.Value.Count -eq 1) { | |
# Handle single track album | |
$track = $album.Value[0] | |
$artistWithReplacements = $track.artist -replace "[\\\/:\*\?""<>\|]", "_" | |
$titleWithReplacements = $track.title -replace "[\\\/:\*\?""<>\|]", "_" | |
$fileExtension = [System.IO.Path]::GetExtension($track.file) | |
$newFileName = "$artistWithReplacements - $titleWithReplacements$fileExtension" | |
$newFilePath = Join-Path -Path "." -ChildPath $newFileName | |
Move-Item -Path $track.file -Destination $newFilePath | |
$relativeFileName = Split-Path $track.file -Leaf | |
Write-Host "Moved `"$relativeFileName`" to `"$newFilePath`"" | |
} | |
elseif ($album.Value.Count -gt 1) { | |
$albumPath = Join-Path -Path "." -ChildPath ($album.Key -replace "[\\\/:\*\?""<>\|]", "_") # Replace invalid characters | |
Write-Host "Processing album: $($album.Key)" | |
# Create album directory if it doesn't exist | |
if (-not (Test-Path $albumPath)) { | |
New-Item -ItemType Directory -Path $albumPath | Out-Null | |
Write-Host "Created directory: $albumPath" | |
} | |
# Move and rename files for multiple tracks | |
foreach ($track in $album.Value) { | |
$titleWithReplacements = $track.title -replace "[\\\/:\*\?""<>\|]", "_" | |
$fileExtension = [System.IO.Path]::GetExtension($track.file) | |
$newFileName = "{0} - {1}{2}" -f $track.trackNumber, $titleWithReplacements, $fileExtension | |
$newFilePath = Join-Path -Path $albumPath -ChildPath $newFileName | |
Move-Item -Path $track.file -Destination $newFilePath | |
$relativeFileName = Split-Path $track.file -Leaf | |
Write-Host "Moved `"$relativeFileName`" to `"$newFilePath`"" | |
} | |
} | |
} | |
Write-Host "Operation completed. Press any key to exit." | |
$null = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment