From 873223d8c657914ed6c93fc3115a530f0c56ef4e Mon Sep 17 00:00:00 2001 From: "DESKTOP-KSVGT20\\shkim" Date: Sat, 2 May 2026 00:42:21 +0900 Subject: [PATCH] Show Suno queue progress and fix track numbering --- chatgpt-suno-tampermonkey.user.js | 12 +++++++++-- process-suno-library.ps1 | 2 +- suno-companion.ps1 | 36 ++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/chatgpt-suno-tampermonkey.user.js b/chatgpt-suno-tampermonkey.user.js index 79cf358..34817d1 100644 --- a/chatgpt-suno-tampermonkey.user.js +++ b/chatgpt-suno-tampermonkey.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name ChatGPT to Suno Prompt Copier // @namespace local.suno-helper -// @version 0.7.8 +// @version 0.7.9 // @description Copy structured ChatGPT song prompt versions into Suno fields. // @author local // @match https://chatgpt.com/* @@ -28,7 +28,7 @@ (function () { "use strict"; - const SCRIPT_VERSION = "0.7.8"; + const SCRIPT_VERSION = "0.7.9"; const STORAGE_KEY = "chatgptSunoPromptSlots"; const SLOT_COUNT = 2; const isChatGPT = location.hostname.includes("chatgpt.com") || location.hostname.includes("chat.openai.com"); @@ -995,6 +995,7 @@ async function prepareSunoWavCandidate(track) { if (!track.id) return extractWavUrl(track.wavUrl); const base = `https://studio-api-prod.suno.com/api/gen/${encodeURIComponent(track.id)}`; + const billingDownloadUrl = `https://studio-api-prod.suno.com/api/billing/clips/${encodeURIComponent(track.id)}/download/`; const cdnWavUrl = `https://cdn1.suno.ai/${encodeURIComponent(track.id)}.wav`; try { await callSunoJson(`${base}/convert_wav/`, { method: "POST" }); @@ -1008,6 +1009,13 @@ } catch (error) { console.warn("[ChatGPT to Suno] wav_file probe failed; local retry will continue", error); } + try { + const data = await callSunoJson(billingDownloadUrl, { method: "GET" }); + const direct = extractWavUrl(data); + if (direct) return direct; + } catch (error) { + console.warn("[ChatGPT to Suno] billing download probe failed; local retry will continue", error); + } return extractWavUrl(track.wavUrl) || cdnWavUrl; } diff --git a/process-suno-library.ps1 b/process-suno-library.ps1 index fb1f896..4b91fa5 100644 --- a/process-suno-library.ps1 +++ b/process-suno-library.ps1 @@ -395,7 +395,7 @@ foreach ($track in $tracks) { $trackFolder = Get-TrackFolder $libraryRoot $title $id $safeTitle = ConvertTo-SafeName $title $id $shortId = Get-ShortId $id - $trackNo = Get-NextTrackNumber $trackFolder + $trackNo = [int](Get-NextTrackNumber $trackFolder) $prefix = "{0:D2} {1}" -f $trackNo, $safeTitle $lyrics = Get-DeepValue $track @("prompt", "lyrics", "lyric", "text") diff --git a/suno-companion.ps1 b/suno-companion.ps1 index b986aac..dc4ae32 100644 --- a/suno-companion.ps1 +++ b/suno-companion.ps1 @@ -15,6 +15,8 @@ New-Item -ItemType Directory -Force -Path $inbox, $logs | Out-Null $queue = [System.Collections.Queue]::new() $queueIds = [System.Collections.Generic.HashSet[string]]::new() $activeJob = $null +$lastProgressAt = [DateTime]::MinValue +$lastProgressText = "" function Resolve-LibraryRoot { param( @@ -135,6 +137,7 @@ function Start-SunoProcess { return [pscustomobject]@{ jobId = $jobId pid = $process.Id + process = $process log = $stdout errorLog = $stderr } @@ -153,10 +156,12 @@ function Save-Manifest { function Update-Queue { if ($script:activeJob -and -not $script:activeJob.Process.HasExited) { + Publish-ActiveJobProgress return } if ($script:activeJob -and $script:activeJob.Process.HasExited) { + Publish-ActiveJobProgress -Force Write-Host "Finished job $($script:activeJob.JobId) exit=$($script:activeJob.Process.ExitCode)" $script:activeJob = $null } @@ -174,7 +179,7 @@ function Update-Queue { $job = Start-SunoProcess $manifestPath $script:activeJob = [pscustomobject]@{ JobId = $job.jobId - Process = Get-Process -Id $job.pid + Process = $job.process TrackId = $item.Id Title = $item.Title Log = $job.log @@ -184,6 +189,35 @@ function Update-Queue { } } +function Get-LastLogLine { + param([string[]]$Paths) + + foreach ($path in $Paths) { + if (-not (Test-Path -LiteralPath $path)) { continue } + $line = Get-Content -LiteralPath $path -Tail 20 -ErrorAction SilentlyContinue | + Where-Object { "$_".Trim() } | + Select-Object -Last 1 + if ($line) { return "$line" } + } + return "" +} + +function Publish-ActiveJobProgress { + param([switch]$Force) + + if (-not $script:activeJob) { return } + $now = Get-Date + if (-not $Force -and ($now - $script:lastProgressAt).TotalSeconds -lt 10) { return } + + $line = Get-LastLogLine @($script:activeJob.ErrorLog, $script:activeJob.Log) + if (-not $line) { return } + if (-not $Force -and $line -eq $script:lastProgressText) { return } + + $script:lastProgressAt = $now + $script:lastProgressText = $line + Write-Host "[$($script:activeJob.JobId)] $($script:activeJob.Title): $line" +} + function Add-TracksToQueue { param($Tracks, [string]$PageUrl)