| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- param(
- [string]$CandidatesPath = "artifacts\music-template-extraction\candidates.json",
- [string]$OutputDir = "artifacts\music-template-extraction\review"
- )
- $ErrorActionPreference = "Stop"
- $data = Get-Content -Raw -Encoding UTF8 -LiteralPath $CandidatesPath | ConvertFrom-Json
- $probe = $null
- try {
- $probe = New-Object -ComObject KWPP.Application
- try { $probe.Quit() } catch {}
- } catch {
- $fallback = Join-Path $PSScriptRoot "render_music_template_candidates.py"
- $python = Get-Command python -ErrorAction Stop
- & $python.Source $fallback $CandidatesPath $OutputDir
- exit $LASTEXITCODE
- } finally {
- if ($probe) { [Runtime.InteropServices.Marshal]::ReleaseComObject($probe) | Out-Null }
- }
- $quotas = @{ child = 7; general = 12; traditional = 7; activity = 7; stage = 7; theory = 7 }
- $seenNames = @{}
- $seenSignatures = @{}
- $selected = [System.Collections.Generic.List[object]]::new()
- foreach ($scene in $quotas.Keys) {
- $count = 0
- $items = $data.items | Where-Object {
- $_.scene -eq $scene -and $_.score -ge 78 -and $_.slides -ge 10 -and $_.slides -le 60 -and
- $_.size_mb -le 250 -and $_.median_text -le 120
- } | Sort-Object score -Descending
- foreach ($item in $items) {
- if ($count -ge $quotas[$scene]) { break }
- if ($seenNames.ContainsKey($item.name_key) -or $seenSignatures.ContainsKey($item.signature)) { continue }
- $seenNames[$item.name_key] = $true
- $seenSignatures[$item.signature] = $true
- $selected.Add($item)
- $count += 1
- }
- }
- New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null
- $OutputDir = (Resolve-Path -LiteralPath $OutputDir).Path
- $rendered = [System.Collections.Generic.List[object]]::new()
- for ($candidateIndex = 0; $candidateIndex -lt $selected.Count; $candidateIndex += 1) {
- $item = $selected[$candidateIndex]
- $id = "candidate-{0:d2}" -f ($candidateIndex + 1)
- $candidateDir = Join-Path $OutputDir $id
- New-Item -ItemType Directory -Force -Path $candidateDir | Out-Null
- $app = $null
- $deck = $null
- try {
- $app = New-Object -ComObject KWPP.Application
- try { $app.Visible = $false } catch {}
- $deck = $app.Presentations.Open($item.path, $true, $true, $false)
- $slideCount = $deck.Slides.Count
- $indexes = @(1, [int][math]::Max(2, [math]::Round($slideCount * 0.25)), [int][math]::Max(2, [math]::Round($slideCount * 0.5)), [int][math]::Max(2, [math]::Round($slideCount * 0.75)), [int]$slideCount) | Sort-Object -Unique
- foreach ($slideIndex in $indexes) {
- $slideIndex = [int]$slideIndex
- $target = Join-Path $candidateDir ("slide-{0:d2}.jpg" -f $slideIndex)
- $deck.Slides.Item($slideIndex).Export($target, "JPG", 640, 360)
- }
- $rendered.Add([pscustomobject]@{
- id = $id
- name = $item.name
- scene = $item.scene
- score = $item.score
- source = $item.path
- slides = $slideCount
- samples = @($indexes | ForEach-Object { "slide-{0:d2}.jpg" -f $_ })
- })
- Write-Host "$id`t$($item.scene)`t$($item.name)"
- }
- catch {
- Write-Warning "$id render failed: $($_.Exception.Message)"
- }
- finally {
- if ($null -ne $deck) { try { $deck.Close() } catch {} }
- if ($null -ne $app) { try { $app.Quit() } catch {} }
- if ($null -ne $deck) { [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($deck) | Out-Null }
- if ($null -ne $app) { [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($app) | Out-Null }
- [gc]::Collect()
- [gc]::WaitForPendingFinalizers()
- }
- }
- @{ items = $rendered } | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $OutputDir "manifest.json") -Encoding UTF8
|