better collision handling

This commit is contained in:
Nathan
2026-02-06 16:32:33 -07:00
parent f009c026b4
commit 53684b7c8f
2 changed files with 1246 additions and 23 deletions
File diff suppressed because it is too large Load Diff
+66 -23
View File
@@ -6,13 +6,11 @@ param(
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
if (-not $PSScriptRoot) { $ScriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path }
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
}
$configLoader = Join-Path -Path $PSScriptRoot -ChildPath 'ConfigLoader.ps1' $configLoader = Join-Path -Path $ScriptDir -ChildPath 'ConfigLoader.ps1'
if (-not (Test-Path -LiteralPath $configLoader)) { if (-not (Test-Path -LiteralPath $configLoader)) {
throw "Missing ConfigLoader.ps1 in $PSScriptRoot" throw "Missing ConfigLoader.ps1 in $ScriptDir"
} }
. $configLoader . $configLoader
@@ -124,12 +122,21 @@ function Sync-SequenceFilenames {
} }
} }
function Get-Mp4FrameRange {
param([string]$Name)
if ($Name -match '[-_](\d+)[-_](\d+)\.mp4$') {
return [pscustomobject]@{ Start = [int]$Matches[1]; End = [int]$Matches[2] }
}
return $null
}
function Rename-SequencePreviewMp4 { function Rename-SequencePreviewMp4 {
param( param(
[Parameter(Mandatory)] [string]$SequenceFolderPath, [Parameter(Mandatory)] [string]$SequenceFolderPath,
[Parameter(Mandatory)] [string]$SequenceName, [Parameter(Mandatory)] [string]$SequenceName,
[Parameter(Mandatory)] [int]$StartFrame, [Parameter(Mandatory)] [int]$StartFrame,
[Parameter(Mandatory)] [int]$EndFrame, [Parameter(Mandatory)] [int]$EndFrame,
[Parameter(Mandatory)] [string]$RootPath,
[string]$LogFile [string]$LogFile
) )
$renamed = 0 $renamed = 0
@@ -139,28 +146,64 @@ function Rename-SequencePreviewMp4 {
$targetName = "$SequenceName-$StartFrame-$EndFrame.mp4" $targetName = "$SequenceName-$StartFrame-$EndFrame.mp4"
$targetPath = Join-Path $SequenceFolderPath $targetName $targetPath = Join-Path $SequenceFolderPath $targetName
$collisionsDir = Join-Path $RootPath '_collisions'
$mp4s = Get-ChildItem -LiteralPath $SequenceFolderPath -File -Filter '*.mp4' -ErrorAction SilentlyContinue | $mp4s = @(Get-ChildItem -LiteralPath $SequenceFolderPath -File -Filter '*.mp4' -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -notlike '*\_archive\*' } Where-Object { $_.FullName -notlike '*\_archive\*' })
foreach ($m in $mp4s) { if ($mp4s.Count -eq 0) { return [pscustomobject]@{ Renamed = 0; Collisions = 0; Errors = 0; Checked = 0 } }
$checked++
if ($m.Name -eq $targetName) { continue } $checked = $mp4s.Count
try {
if (Test-Path -LiteralPath $targetPath) { $candidates = @($mp4s | ForEach-Object {
$collisions++ $fr = Get-Mp4FrameRange -Name $_.Name
if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] MP4 RENAME SKIP collision: '$($m.Name)' -> '$targetName'" | Add-Content -LiteralPath $LogFile } $frameMatch = ($fr -and $fr.Start -eq $StartFrame -and $fr.End -eq $EndFrame)
continue [pscustomobject]@{
File = $_
FrameMatch = $frameMatch
LastWrite = $_.LastWriteTimeUtc
}
} | Sort-Object -Property @{ Expression = { -not $_.FrameMatch }; Ascending = $true }, @{ Expression = 'LastWrite'; Descending = $true })
$best = $candidates[0].File
$moveToCollisions = if ($candidates.Count -gt 1) { $candidates[1..($candidates.Count - 1)] } else { @() }
try {
if (-not (Test-Path -LiteralPath $collisionsDir)) {
New-Item -ItemType Directory -Path $collisionsDir -Force | Out-Null
}
foreach ($c in $moveToCollisions) {
$f = $c.File
$destName = $f.Name
$destPath = Join-Path $collisionsDir $destName
if (Test-Path -LiteralPath $destPath) {
$base = [System.IO.Path]::GetFileNameWithoutExtension($destName)
$destName = "{0}_{1}.mp4" -f $base, (Get-Date -Format 'yyyyMMdd_HHmmss')
$destPath = Join-Path $collisionsDir $destName
} }
Rename-Item -LiteralPath $m.FullName -NewName $targetName -ErrorAction Stop Move-Item -LiteralPath $f.FullName -Destination $destPath -Force -ErrorAction Stop
$collisions++
if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] MP4 COLLISION moved: '$($f.Name)' -> '$destPath'" | Add-Content -LiteralPath $LogFile }
}
if ($best.Name -ne $targetName) {
if (Test-Path -LiteralPath $targetPath) {
$destPath = Join-Path $collisionsDir $targetName
if (Test-Path -LiteralPath $destPath) {
$base = [System.IO.Path]::GetFileNameWithoutExtension($targetName)
$destPath = Join-Path $collisionsDir ("{0}_{1}.mp4" -f $base, (Get-Date -Format 'yyyyMMdd_HHmmss'))
}
Move-Item -LiteralPath $targetPath -Destination $destPath -Force -ErrorAction Stop
$collisions++
}
Rename-Item -LiteralPath $best.FullName -NewName $targetName -ErrorAction Stop
$renamed++ $renamed++
if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] MP4 RENAME: '$($m.Name)' -> '$targetName'" | Add-Content -LiteralPath $LogFile } if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] MP4 RENAME: '$($best.Name)' -> '$targetName'" | Add-Content -LiteralPath $LogFile }
break
}
catch {
$errors++
if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] MP4 RENAME ERROR for '$($m.Name)': $($_.Exception.Message)" | Add-Content -LiteralPath $LogFile }
} }
} catch {
$errors++
if ($LogFile) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] MP4 ERROR: $($_.Exception.Message)" | Add-Content -LiteralPath $LogFile }
} }
return [pscustomobject]@{ return [pscustomobject]@{
@@ -295,7 +338,7 @@ try {
$renameErrors += $renameResult.Errors $renameErrors += $renameResult.Errors
if ($renameResult.FrameCount -gt 0 -and $null -ne $renameResult.MinFrame -and $null -ne $renameResult.MaxFrame) { if ($renameResult.FrameCount -gt 0 -and $null -ne $renameResult.MinFrame -and $null -ne $renameResult.MaxFrame) {
$mp4Result = Rename-SequencePreviewMp4 -SequenceFolderPath $seq.Path -SequenceName $seq.Name -StartFrame $renameResult.MinFrame -EndFrame $renameResult.MaxFrame -LogFile $logFile $mp4Result = Rename-SequencePreviewMp4 -SequenceFolderPath $seq.Path -SequenceName $seq.Name -StartFrame $renameResult.MinFrame -EndFrame $renameResult.MaxFrame -RootPath $root -LogFile $logFile
if ($DebugMode -or $mp4Result.Renamed -gt 0 -or $mp4Result.Collisions -gt 0 -or $mp4Result.Errors -gt 0) { if ($DebugMode -or $mp4Result.Renamed -gt 0 -or $mp4Result.Collisions -gt 0 -or $mp4Result.Errors -gt 0) {
Write-Host "[MP4]|$($seq.Path)|$($seq.Name)|renamed=$($mp4Result.Renamed)|collisions=$($mp4Result.Collisions)|errors=$($mp4Result.Errors)" -ForegroundColor Cyan Write-Host "[MP4]|$($seq.Path)|$($seq.Name)|renamed=$($mp4Result.Renamed)|collisions=$($mp4Result.Collisions)|errors=$($mp4Result.Errors)" -ForegroundColor Cyan
} }