Refactored everything

This commit is contained in:
bnair
2026-01-03 11:57:26 +01:00
parent b4a82e0db5
commit f1e79ad01d
18 changed files with 2371 additions and 582 deletions

207
legacy/finalOptimiser.ps1 Normal file
View File

@@ -0,0 +1,207 @@
# SMART PRE-FLIGHT ENCODER - VERBOSE CONSOLE OUTPUT
# Usage: .\Encode-TVShows.ps1
param(
[string]$TvDir = "Z:\tv",
[string]$ContentDir = "Z:\content",
[int]$MaxJobs = 2,
[int]$Av1Q = 34,
[int]$HevcQ = 28,
[string]$EncoderAV1 = "av1_amf",
[string]$EncoderHEVC = "hevc_amf",
[switch]$SkipAV1 = $true
)
# --- CONFIGURATION ---
$Global:FFMPEG = "ffmpeg"
$Global:FFPROBE = "ffprobe"
$Global:TEMP_DIR = "C:\Users\bnair\Videos\encodes"
$Global:LockDir = "C:\Users\bnair\Videos\encodes\locks"
$LogFileTV = "C:\Users\bnair\Videos\encodes\encoding-log-tv.csv"
$LogFileContent = "C:\Users\bnair\Videos\encodes\encoding-log-content.csv"
if (-not (Test-Path $Global:TEMP_DIR)) { New-Item -ItemType Directory -Path $Global:TEMP_DIR -Force | Out-Null }
if (-not (Test-Path $Global:LockDir)) { New-Item -ItemType Directory -Path $Global:LockDir -Force | Out-Null }
function Init-LogFile {
param([string]$Path)
if (-not (Test-Path $Path)) { "Timestamp,File,InputSize,OutputSize,CodecUsed,Status,Savings" | Out-File -FilePath $Path -Encoding UTF8 }
}
Init-LogFile $LogFileTV
Init-LogFile $LogFileContent
function Test-Tools {
Write-Host "Setup: Checking required tools..." -ForegroundColor Cyan
if (-not (Get-Command $Global:FFMPEG -ErrorAction SilentlyContinue)) { Write-Host "ERROR: ffmpeg not found!" -ForegroundColor Red; exit 1 }
Write-Host "Setup: Tools found." -ForegroundColor Green
}
$SharedFunctions = {
function Get-LockId {
param([string]$FilePath)
try {
$pathBytes = [System.Text.Encoding]::UTF8.GetBytes($FilePath)
$hash = [System.Security.Cryptography.SHA256]::Create().ComputeHash($pathBytes)
return [BitConverter]::ToString($hash).Replace("-", "").Substring(0, 16)
} catch { return "unknown_lock" }
}
function Run-FFmpeg {
param($In, $Out, $Enc, $Q, $Seek=$null, $Duration=$null)
$argsList = "-hide_banner -loglevel error -y"
if ($Seek) { $argsList += " -ss $Seek" }
$argsList += " -i `"$In`""
if ($Duration) { $argsList += " -t $Duration" }
$argsList += " -c:v $Enc -usage transcoding -quality quality -rc cqp -qp_i $Q -qp_p $Q -qp_b $Q -c:a copy `"$Out`""
return Start-Process -FilePath "ffmpeg" -ArgumentList $argsList -NoNewWindow -Wait -PassThru
}
function Process-VideoFile {
param($InputFile, $CurrentLogFile, $LockDir, $TempDir, $Av1Q, $HevcQ, $EncAV1, $EncHEVC, $SkipAV1)
$pidStr = $PID.ToString()
$lockId = Get-LockId -FilePath $InputFile
$lockFile = Join-Path $LockDir "$lockId.lock"
try {
if (Test-Path $lockFile) { return }
$pidStr | Out-File -FilePath $lockFile -Force
$fileName = Split-Path $InputFile -Leaf
Write-Host "[$pidStr] Found: $fileName" -ForegroundColor White
# Skip Logic
$currentCodec = (& "ffprobe" -v error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 "$InputFile" 2>&1)
if ($SkipAV1 -and ($currentCodec -match "av1" -or $currentCodec -match "hevc")) {
Write-Host "[$pidStr] SKIP: Already optimized ($currentCodec)" -ForegroundColor DarkGray
return
}
$inputSize = (Get-Item $InputFile).Length
# --- PHASE 1: PRE-FLIGHT SAMPLE ---
Write-Host "[$pidStr] Testing: Generating 60s sample..." -ForegroundColor Yellow
$tempSample = Join-Path $TempDir "$fileName.sample.mkv"
$procSample = Run-FFmpeg $InputFile $tempSample $EncAV1 $Av1Q "00:05:00" "60"
$doFullAV1 = $true
if ($procSample.ExitCode -eq 0 -and (Test-Path $tempSample)) {
$sampleSize = (Get-Item $tempSample).Length
# Threshold: 150MB for 60s is ~20Mbps (Likely bloat)
if ($sampleSize -gt 150MB) {
Write-Host "[$pidStr] Test Result: FAIL. Sample was $([math]::Round($sampleSize/1MB))MB. Too big for AV1." -ForegroundColor Red
$doFullAV1 = $false
} else {
Write-Host "[$pidStr] Test Result: PASS. Sample was $([math]::Round($sampleSize/1MB))MB. Proceeding with AV1." -ForegroundColor Green
}
Remove-Item $tempSample -Force
}
$finalStatus = "Failed"
$finalCodec = "None"
$finalSize = 0
$finalSavings = 0.00
# --- PHASE 2: FULL AV1 ---
if ($doFullAV1) {
Write-Host "[$pidStr] Action: Starting Full AV1 Encode..." -ForegroundColor Cyan
$tempAV1 = Join-Path $TempDir "$fileName.av1.mkv"
$procAV1 = Run-FFmpeg $InputFile $tempAV1 $EncAV1 $Av1Q
if ($procAV1.ExitCode -eq 0 -and (Test-Path $tempAV1)) {
$sizeAV1 = (Get-Item $tempAV1).Length
if ($sizeAV1 -lt $inputSize) {
$finalSavings = [math]::Round((1 - ($sizeAV1 / $inputSize)) * 100, 2)
Write-Host "[$pidStr] AV1 ACCEPTED: Saved ${finalSavings}%" -ForegroundColor Green
$finalOut = $InputFile -replace '\.mkv$', '_av1.mkv' -replace '\.mp4$', '_av1.mp4'
Move-Item $tempAV1 -Destination $finalOut -Force
Remove-Item $InputFile -Force
Rename-Item $finalOut -NewName $fileName -Force
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'),`"$InputFile`",$inputSize,$sizeAV1,AV1,`"Replaced (AV1)`",$finalSavings%" | Out-File -FilePath $CurrentLogFile -Append -Encoding UTF8
return
} else {
Write-Host "[$pidStr] AV1 REJECTED: Larger than source ($([math]::Round($sizeAV1/1GB,2)) GB). Deleting..." -ForegroundColor Red
Remove-Item $tempAV1 -Force
}
}
}
# --- PHASE 3: HEVC FALLBACK ---
Write-Host "[$pidStr] Action: Trying HEVC Fallback..." -ForegroundColor Cyan
$tempHEVC = Join-Path $TempDir "$fileName.hevc.mkv"
$procHEVC = Run-FFmpeg $InputFile $tempHEVC $EncHEVC $HevcQ
if ($procHEVC.ExitCode -eq 0 -and (Test-Path $tempHEVC)) {
$sizeHEVC = (Get-Item $tempHEVC).Length
if ($sizeHEVC -lt $inputSize) {
$finalSavings = [math]::Round((1 - ($sizeHEVC / $inputSize)) * 100, 2)
Write-Host "[$pidStr] HEVC ACCEPTED: Saved ${finalSavings}%" -ForegroundColor Green
$finalOut = $InputFile -replace '\.mkv$', '_hevc.mkv' -replace '\.mp4$', '_hevc.mp4'
Move-Item $tempHEVC -Destination $finalOut -Force
Remove-Item $InputFile -Force
Rename-Item $finalOut -NewName $fileName -Force
$finalStatus = "Replaced (HEVC)"
$finalCodec = "HEVC"
$finalSize = $sizeHEVC
} else {
Write-Host "[$pidStr] HEVC REJECTED: Also larger. Keeping original." -ForegroundColor Red
Remove-Item $tempHEVC -Force
$finalStatus = "Rejected (Both Larger)"
$finalSize = $sizeHEVC
$finalCodec = "HEVC"
}
}
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'),`"$InputFile`",$inputSize,$finalSize,$finalCodec,`"$finalStatus`",$finalSavings%" | Out-File -FilePath $CurrentLogFile -Append -Encoding UTF8
} finally {
Remove-Item $lockFile -Force -ErrorAction SilentlyContinue
}
}
}
function Process-Directory {
param($TargetDirectory, $TargetLogFile, $PhaseName)
if (-not (Test-Path $TargetDirectory)) { return }
Write-Host "`n=== PHASE: $PhaseName ===" -ForegroundColor Magenta
$files = Get-ChildItem -Path $TargetDirectory -Include *.mkv, *.mp4 -Recurse -File -ErrorAction SilentlyContinue
$videoFiles = $files | Where-Object { $_.Name -notmatch "_av1" -and $_.Name -notmatch "_hevc" }
Write-Host "Found $($videoFiles.Count) files." -ForegroundColor Cyan
$processed = 0
while ($processed -lt $videoFiles.Count) {
$batchSize = [math]::Min($MaxJobs, ($videoFiles.Count - $processed))
$currentBatch = $videoFiles[$processed..($processed + $batchSize - 1)]
$jobs = @()
foreach ($file in $currentBatch) {
$jobs += Start-Job -InitializationScript $SharedFunctions -ScriptBlock {
param($f, $log, $lock, $temp, $av1q, $hevcq, $e1, $e2, $skip)
Process-VideoFile $f $log $lock $temp $av1q $hevcq $e1 $e2 $skip
} -ArgumentList $file.FullName, $TargetLogFile, $Global:LockDir, $Global:TEMP_DIR, $Av1Q, $HevcQ, $EncoderAV1, $EncoderHEVC, $SkipAV1
}
while (($jobs | Where-Object { $_.State -eq 'Running' }).Count -gt 0) {
$jobs | Receive-Job
Start-Sleep -Seconds 2
}
$jobs | Receive-Job
$jobs | Remove-Job -Force
$processed += $batchSize
Write-Host "Progress Phase ${PhaseName}: $processed / $($videoFiles.Count)" -ForegroundColor Yellow
}
}
Test-Tools
Process-Directory $TvDir $LogFileTV "TV-Shows"
Process-Directory $ContentDir $LogFileContent "Content"
Write-Host "`nDone." -ForegroundColor Green