Navidrome, Clients and Albums With Varying Artist Tags
I’m using Navidrome as my music server now, having switched from shoehorning Jellyfin into that role, and I quite like it. One thing I discovered, however, is that it – and quite a few clients that support it – rely on the Album Artist tag to help index files. Initially I found this problematic because many of my files didn’t have Album Artist populated. I solved this by writing a PowerShell script to copy the Perfomers tag data (Performers = Artist) to the Album Artist tag. I’ll share that in another post.
But then I discovered a different problem. If an album is a compilation or has variance in the artists from file to file (for example: This Guy feat. That Other Guy), it’d index files into separate albums of the same title. Navidrome’s developers confirmed that this is a feature, not a bug, and it makes sense. The solution for compilation albums is to set the Compilation tag to 1, which I haven’t automated yet but will shortly. The solution for non-comp albums is to make sure the Album Artists tag is consistent.
To accomplish this, I threw together the below script. It’s not optimized, it doesn’t have error handling or confirmation, and it’s apt to be destructive if you’re not careful. Still, it’s something you can build on, just as I inevitably will. As with all my music file related scripts, it requires taglib-sharp.dll. Obtain this file from TagLibSharp. You don’t have to futz with nuget or anything – just download the zipped package, yank the dll out of it, and put it in a subdir you’ll reference in the script.
This script will prompt for the full path to the files you wish to update, and then the name you wish to update the Album Artist tag to.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# uses taglib-sharp.dll # No errorchecking in this yet. josefek # update the below to reflect the accurate path to taglib-sharp.dll $null = [System.Reflection.Assembly]::LoadFrom("E:\mp3tools\taglib-sharp.dll") $basedir = Read-Host -Prompt 'Enter the base dir' $artist = Read-Host -Prompt 'Enter the Album Artist' $files = @(Get-ChildItem $basedir | Where-Object { $_.Extension -eq ".mp3" -or $_.Extension -eq ".m4a"} ) foreach ($file in $files) { $file.fullname if ($file) { try { $prop = Get-ItemProperty -literalpath $($file.fullname) | Select-Object IsReadOnly } catch { # Handling for situations like invalid path characters, which prevent properties from being read Write-host "Cannot detect readonly $($file.fullname)" } if ($($prop.IsReadOnly)) { # Remove Read-Only $file.IsReadOnly = $false } try { $f = [TagLib.File]::Create($file.fullname) } catch { write-host "Error on $f " $file.fullname } } $f.Tag.AlbumArtists = $artist $f.Save(); } exit |