Queue Suno tracks one at a time

This commit is contained in:
DESKTOP-KSVGT20\shkim
2026-05-01 23:15:19 +09:00
parent 1414c38bd1
commit 96a54a3eca
3 changed files with 125 additions and 26 deletions
+103 -1
View File
@@ -12,6 +12,9 @@ $processor = Join-Path $scriptRoot "process-suno-library.ps1"
$inbox = Join-Path $scriptRoot "companion-inbox"
$logs = Join-Path $scriptRoot "companion-logs"
New-Item -ItemType Directory -Force -Path $inbox, $logs | Out-Null
$queue = [System.Collections.Queue]::new()
$queueIds = [System.Collections.Generic.HashSet[string]]::new()
$activeJob = $null
function Resolve-LibraryRoot {
param(
@@ -137,6 +140,80 @@ function Start-SunoProcess {
}
}
function Save-Manifest {
param($Manifest)
$firstTrack = @($Manifest.tracks)[0]
$id = "$($firstTrack.id)".Trim()
$safeId = if ($id) { $id } else { Get-Date -Format "yyyyMMdd-HHmmssfff" }
$manifestPath = Join-Path $inbox ("suno-track-{0}.manifest.json" -f $safeId)
$Manifest | ConvertTo-Json -Depth 50 | Set-Content -LiteralPath $manifestPath -Encoding UTF8
return $manifestPath
}
function Update-Queue {
if ($script:activeJob -and -not $script:activeJob.Process.HasExited) {
return
}
if ($script:activeJob -and $script:activeJob.Process.HasExited) {
Write-Host "Finished job $($script:activeJob.JobId) exit=$($script:activeJob.Process.ExitCode)"
$script:activeJob = $null
}
while (-not $script:activeJob -and $script:queue.Count -gt 0) {
$item = $script:queue.Dequeue()
[void]$script:queueIds.Remove($item.Id)
$manifest = [pscustomobject]@{
pageUrl = $item.PageUrl
capturedAt = (Get-Date).ToString("o")
count = 1
tracks = @($item.Track)
}
$manifestPath = Save-Manifest $manifest
$job = Start-SunoProcess $manifestPath
$script:activeJob = [pscustomobject]@{
JobId = $job.jobId
Process = Get-Process -Id $job.pid
TrackId = $item.Id
Title = $item.Title
Log = $job.log
ErrorLog = $job.errorLog
}
Write-Host "Started queued job $($job.jobId): $($item.Title) [$($item.Id)]"
}
}
function Add-TracksToQueue {
param($Tracks, [string]$PageUrl)
$sync = Get-MissingTracks $Tracks
$added = @()
$skipped = 0
foreach ($track in @($sync.missing)) {
$id = "$($track.id)".Trim()
if (-not $id) { $skipped++; continue }
if ($queueIds.Contains($id)) { $skipped++; continue }
if ($activeJob -and $activeJob.TrackId -eq $id) { $skipped++; continue }
$title = if ($track.title) { "$($track.title)" } else { $id }
$queue.Enqueue([pscustomobject]@{
Id = $id
Title = $title
Track = $track
PageUrl = $PageUrl
})
[void]$queueIds.Add($id)
$added += $track
}
Update-Queue
return [pscustomobject]@{
added = @($added).Count
skipped = $skipped
queued = $queue.Count
active = if ($activeJob) { $activeJob.Title } else { "" }
}
}
function Get-ExistingSunoIds {
param([string]$Root)
@@ -181,6 +258,7 @@ if (-not (Test-Path -LiteralPath $processor)) {
$listener = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Parse("127.0.0.1"), $Port)
$listener.Start()
$listener.Server.ReceiveTimeout = 1000
Write-Host "SUNO companion listening on http://127.0.0.1:$Port"
Write-Host "OutputRoot: $OutputRoot"
@@ -190,6 +268,11 @@ Write-Host "Press Ctrl+C to stop."
try {
while ($true) {
Update-Queue
if (-not $listener.Pending()) {
Start-Sleep -Milliseconds 500
continue
}
$client = $listener.AcceptTcpClient()
try {
$stream = $client.GetStream()
@@ -201,8 +284,9 @@ try {
}
if ($request.Method -eq "GET" -and $request.Path -eq "/health") {
Update-Queue
Write-Host "Health check OK: $(Get-Date -Format 'HH:mm:ss')"
Write-Response $stream 200 "OK" (@{ ok = $true; outputRoot = $OutputRoot; libraryRoot = $libraryRoot; artist = $ArtistName } | ConvertTo-Json -Compress)
Write-Response $stream 200 "OK" (@{ ok = $true; outputRoot = $OutputRoot; libraryRoot = $libraryRoot; artist = $ArtistName; queued = $queue.Count; active = if ($activeJob) { $activeJob.Title } else { "" } } | ConvertTo-Json -Compress)
continue
}
@@ -258,6 +342,24 @@ try {
continue
}
if ($request.Method -eq "POST" -and $request.Path -eq "/enqueue") {
$manifest = $request.Body | ConvertFrom-Json
if (-not $manifest.tracks -or @($manifest.tracks).Count -eq 0) {
Write-Response $stream 400 "Bad Request" (@{ ok = $false; error = "tracks is empty" } | ConvertTo-Json -Compress)
continue
}
$result = Add-TracksToQueue @($manifest.tracks) "$($manifest.pageUrl)"
Write-Host "Queue update: added=$($result.added), queued=$($result.queued), active=$($result.active)"
Write-Response $stream 200 "OK" (@{
ok = $true
added = $result.added
skipped = $result.skipped
queued = $result.queued
active = $result.active
} | ConvertTo-Json -Compress)
continue
}
Write-Response $stream 404 "Not Found" (@{ ok = $false; error = "not found" } | ConvertTo-Json -Compress)
} catch {
try {