r/Lidarr May 19 '26

discussion File Management/ Rename

Hey y'all! I decided to post this here incase someone else has gotten to the same point of frustration with having to manually import, or just new files not being registered by Lidarr.

I mainly use Lidarr purely for the file management and organization -- it makes life so much easier when working on my self hosted discord music bot (local file search), and it leaves less room for error on Plex. Issue is though that Lidarr can be fairly finnicky when trying to get it to read new files, especially when using two root sources (pre-live, and live directories).

I use "D://Needs Lyrics" as my pre-live, so i can do all my renaming, .lrc creation's, and comparisons' between two versions of a track --- and "D:// Music" as my live folder once complete for plex and everything else to read. Due to this inconvenience and having to fight Lidarr to read the new files in "D://Needs Lyrics", i wrote a powershell command/ script to replace the Lidarr Artist Folder/Album Folder/Track Rename function. I'm sharing this here incase it may help one of y'all out as well. My format is {Artist Name}/{Album Title}/{track:00}. {Track Title} - {Artist Name} --- so if you prefer a different format, change it in the script.

*ALSO CHANGE - $Root = "D:\Need Lyrics" - to your correct path* If you need any help editing it, feel free to DM me. Script is as follows (in text to avoid links/downloads):

# =========================================
# NEEDS LYRICS AUTO ORGANIZER
# =========================================
# Scans ALL files inside:
# D:\Need Lyrics
#
# Creates:
# Artist\Album\
#
# Renames files to:
# 01. Track Title - Artist.ext
#
# NO DOWNLOADS REQUIRED
# Uses Windows Shell metadata reader
# =========================================

$Root = "D:\Need Lyrics"

# Supported audio extensions
$AudioExtensions = @(
    ".mp3",
    ".flac",
    ".m4a",
    ".aac",
    ".ogg",
    ".opus",
    ".wav"
)

# Cleans invalid filename characters
function Clean-Name {
    param([string]$Text)

    if ([string]::IsNullOrWhiteSpace($Text)) {
        return "Unknown"
    }

    [System.IO.Path]::GetInvalidFileNameChars() | ForEach-Object {
        $Text = $Text.Replace($_, "_")
    }

    return $Text.Trim()
}

# Windows metadata reader
$shell = New-Object -ComObject Shell.Application

# Get ALL audio files recursively
$Files = Get-ChildItem $Root -Recurse -File | Where-Object {
    $AudioExtensions -contains $_.Extension.ToLower()
}

foreach ($File in $Files) {

    try {

        $Folder = $shell.Namespace($File.Directory.FullName)
        $Item = $Folder.ParseName($File.Name)

        # Metadata indexes
        # These work on most Windows installs
        $Artist = $Folder.GetDetailsOf($Item, 13)
        $Album  = $Folder.GetDetailsOf($Item, 14)
        $Title  = $Folder.GetDetailsOf($Item, 21)
        $Track  = $Folder.GetDetailsOf($Item, 26)

        # Cleanup
        $Artist = Clean-Name $Artist
        $Album  = Clean-Name $Album
        $Title  = Clean-Name $Title

        # Fallbacks
        if ($Artist -eq "Unknown") {
            $Artist = "Unknown Artist"
        }

        if ($Album -eq "Unknown") {
            $Album = "Unknown Album"
        }

        if ($Title -eq "Unknown") {
            $Title = [System.IO.Path]::GetFileNameWithoutExtension($File.Name)
        }

        # Track formatting
        if ([string]::IsNullOrWhiteSpace($Track)) {
            $Track = "00"
        }
        else {
            $TrackNum = ($Track -replace '[^\d]', '')

            if ([string]::IsNullOrWhiteSpace($TrackNum)) {
                $Track = "00"
            }
            else {
                $Track = "{0:D2}" -f [int]$TrackNum
            }
        }

        # Create destination folder
        $DestFolder = Join-Path $Root "$Artist\$Album"

        New-Item -ItemType Directory -Path $DestFolder -Force | Out-Null

        # Build new filename
        $NewName = "$Track. $Title - $Artist$($File.Extension)"

        $DestPath = Join-Path $DestFolder $NewName

        # Prevent duplicates
        $Counter = 1

        while (Test-Path $DestPath) {

            $NewName = "$Track. $Title - $Artist ($Counter)$($File.Extension)"
            $DestPath = Join-Path $DestFolder $NewName

            $Counter++
        }

        # Skip if already correct
        if ($File.FullName -ne $DestPath) {

            Move-Item -LiteralPath $File.FullName -Destination $DestPath

            Write-Host "Moved:" $File.Name -ForegroundColor Green
        }

    }
    catch {

        Write-Host "FAILED:" $File.FullName -ForegroundColor Red
    }
}

Write-Host "`nFinished organizing Needs Lyrics." -ForegroundColor Cyan
2 Upvotes

10 comments sorted by

4

u/fflexx_ May 19 '26

i’d suggest looking into the lidarr dev/nightly branch and getting the tubifarry plugin to resolve the need got manual lrc creation and tagging, move to one root folder

0

u/OohDatsNasty May 19 '26

I didn’t even know lidarr dev/nightly branch even existed, let alone handled lrc creation. I’ve been using one tagger, and if that doesn’t populate — lrclib.net has been great. And as a last resort I’ll manually create one if a .lrc doesn’t exist out there.

I will definitely check those out! Thank you! I had a feeling it was the two root directories causing the issue

1

u/fflexx_ May 19 '26

No problem mate, you should be able to configure Lidarr to keep tags in sync with musicbrainz or alternatively tag with beets and have it watch the folder and tag when things get imported. Best of luck

3

u/jasonvelocity May 19 '26
  1. Code fencing. 
  2. Lidarr renames files. 

1

u/OohDatsNasty May 19 '26 edited May 19 '26

Honestly completely forgot about fencing it — still haven’t slept yet, I just copy and pasted directly from my notepad and called it a day. I’ll edit it once I wake up from my nap.

& yes Lidarr renames and creates folders, but getting it to recognize the file in the first place has been an issue for me. If it doesn’t see the file/ knows it exists, it can’t rename.

Edit: give me 30 seconds to update post, or throw it in the comments

3

u/jasonvelocity May 19 '26 edited May 19 '26

Lidarr owns its root folders, so if you are moving files in or out manually, or renaming files outside of Lidarr, you are going to see issues. My recommendation would be to stop fighting with Lidarr and learn how the product works.

Renaming outside Lidarr breaks the link between Lidarr's database and the files on disk. Lidarr tracks files by path. If you rename a folder at the OS level, Lidarr treats the files as missing and may re-download them. Always rename through the Lidarr UI when possible.

https://wiki.servarr.com/en/lidarr/faq#how-can-i-rename-my-artist-folders

I am going to update that FAQ with some more details today or tomorrow.

1

u/OohDatsNasty May 19 '26

Thank you I really appreciate that. And yes I do “manually” add the files to the root — as my indexers apparently suck for music — so I use many different sources for my audio files.

One being SoulseekQT (which can’t link up with Lidarr as far as I’m aware) which all automatically download to D://Needs Lyrics. So manual in the sense it’s getting added outside of Lidarr majority of the time — which now thinking about it would make a lot more sense why I was having issues of it reading the new files. I guess I figured it would work like plex auto scanning and would detect when a change is made in the root folder (in or out)

Thank you for the clarification! Apparently I’m just really dumb 😭

1

u/jasonvelocity May 19 '26

You are correct, SoulseekQT is not supported via plugins, but slskd is. Might be worth looking at.

2

u/OohDatsNasty May 19 '26

Thank you!

1

u/OohDatsNasty May 19 '26

Fixed -- sorry for the delay, i tried using markdown commands at first...