Queue Suno WAV candidates with local retry

This commit is contained in:
DESKTOP-KSVGT20\shkim
2026-05-02 00:34:23 +09:00
parent 248f4a21d4
commit 10e25e03a4
2 changed files with 60 additions and 13 deletions
+26 -7
View File
@@ -1,7 +1,7 @@
// ==UserScript==
// @name ChatGPT to Suno Prompt Copier
// @namespace local.suno-helper
// @version 0.7.7
// @version 0.7.8
// @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.7";
const SCRIPT_VERSION = "0.7.8";
const STORAGE_KEY = "chatgptSunoPromptSlots";
const SLOT_COUNT = 2;
const isChatGPT = location.hostname.includes("chatgpt.com") || location.hostname.includes("chat.openai.com");
@@ -992,6 +992,25 @@
return extractWavUrl(track.wavUrl) || ((await canReadUrl(cdnWavUrl)) ? cdnWavUrl : "");
}
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 cdnWavUrl = `https://cdn1.suno.ai/${encodeURIComponent(track.id)}.wav`;
try {
await callSunoJson(`${base}/convert_wav/`, { method: "POST" });
} catch (error) {
console.warn("[ChatGPT to Suno] convert_wav failed; local retry will continue", error);
}
try {
const data = await callSunoJson(`${base}/wav_file/`, { method: "GET" });
const direct = extractWavUrl(data);
if (direct) return direct;
} catch (error) {
console.warn("[ChatGPT to Suno] wav_file probe failed; local retry will continue", error);
}
return extractWavUrl(track.wavUrl) || cdnWavUrl;
}
function downloadTextFile(text, name) {
const blob = new Blob([text], { type: "application/json;charset=utf-8" });
const url = URL.createObjectURL(blob);
@@ -1111,11 +1130,11 @@
let wavPending = 0;
for (let index = 0; index < missingTracks.length; index += 1) {
const track = { ...missingTracks[index] };
setStatus(statusTarget, `${index + 1}/${missingTracks.length} 없는 곡 WAV 준비 중: ${track.title || track.id}`);
track.wavUrl = await requestSunoWavUrl(track);
setStatus(statusTarget, `${index + 1}/${missingTracks.length} 없는 곡 WAV 변환 요청 중: ${track.title || track.id}`);
track.wavUrl = await prepareSunoWavCandidate(track);
if (!track.wavUrl) {
wavPending += 1;
setStatus(statusTarget, `${track.title || track.id} WAV 변환 URL이 아직 안 나와서 보류 (${wavPending}곡)`);
setStatus(statusTarget, `${track.title || track.id} WAV 후보 URL을 못 만들어서 보류 (${wavPending}곡)`);
continue;
}
const enqueueManifest = {
@@ -1138,10 +1157,10 @@
setStatus(statusTarget, `${enqueued}/${missingTracks.length}곡 큐 추가: ${track.title || track.id} / 대기 ${data.queued ?? "?"}`);
}
if (!enqueued) {
setStatus(statusTarget, `큐에 넣은 곡 없음. 새 곡 ${missingTracks.length}개 중 ${wavPending}개가 아직 SUNO WAV 변환 URL을 안 줬어.`);
setStatus(statusTarget, `큐에 넣은 곡 없음. 새 곡 ${missingTracks.length}개 중 ${wavPending}개가 WAV 후보 URL 생성 실패.`);
return;
}
setStatus(statusTarget, `큐 전송 완료: 새 곡 ${enqueued}개, WAV 보류 ${wavPending}개. 로컬 프로그램이 순서대로 처리 중.`);
setStatus(statusTarget, `큐 전송 완료: 새 곡 ${enqueued}개, 보류 ${wavPending}개. 로컬 프로그램이 WAV 준비를 기다리며 처리 중.`);
}
function trackOptionLabel(track, index) {