Put ACE-Step music jobs on the same studio queue as video and image.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+84
-2
@@ -3,6 +3,7 @@
|
||||
<AppHeader
|
||||
subtitle="ACE-Step · vocals"
|
||||
current="music"
|
||||
:queue-count="queueCount"
|
||||
/>
|
||||
|
||||
<main class="mx-auto grid min-w-0 max-w-7xl gap-6 px-4 py-6 sm:px-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] lg:items-stretch">
|
||||
@@ -121,6 +122,10 @@
|
||||
{{ busy ? (status || 'Generating…') : 'Generate' }}
|
||||
</button>
|
||||
<p v-if="blockReason" class="text-xs text-zinc-400">{{ blockReason }}</p>
|
||||
<p v-else-if="queued" class="text-xs text-zinc-400">
|
||||
Waiting in the job queue.
|
||||
<NuxtLink to="/queue" class="text-amber-200 hover:text-amber-100">Open Queue</NuxtLink>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="glass min-w-0 max-w-full space-y-4 rounded-3xl p-5 sm:p-6">
|
||||
@@ -188,10 +193,14 @@ const progress = ref(0)
|
||||
const audioUrl = ref('')
|
||||
const trackId = ref('')
|
||||
const jobId = ref('')
|
||||
const studioJobId = ref('')
|
||||
const queued = ref(false)
|
||||
const queueCount = ref(0)
|
||||
const downloadName = ref('track.flac')
|
||||
let source: EventSource | null = null
|
||||
let listenGen = 0
|
||||
let settled = false
|
||||
let queuePoll: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
const blocked = computed(() => !tags.value.trim() || (!instrumental.value && !lyrics.value.trim()) || !folderId.value)
|
||||
const blockReason = computed(() => {
|
||||
@@ -232,6 +241,55 @@ function stopListen() {
|
||||
source = null
|
||||
}
|
||||
|
||||
function stopQueuePoll() {
|
||||
if (queuePoll) {
|
||||
clearInterval(queuePoll)
|
||||
queuePoll = null
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshStudioQueue() {
|
||||
const data = await $fetch<{
|
||||
jobs?: Array<{
|
||||
id: string
|
||||
status: string
|
||||
liveJobId?: string
|
||||
lastError?: string
|
||||
}>
|
||||
waitingCount?: number
|
||||
}>('/api/studio-queue').catch(() => ({ jobs: [] as Array<{ id: string; status: string; liveJobId?: string; lastError?: string }>, waitingCount: 0 }))
|
||||
const rows = data.jobs || []
|
||||
queueCount.value = data.waitingCount || rows.filter(job => job.status === 'waiting').length
|
||||
if (!studioJobId.value) return
|
||||
const row = rows.find(job => job.id === studioJobId.value)
|
||||
if (!row) {
|
||||
if (queued.value && !jobId.value) {
|
||||
queued.value = false
|
||||
}
|
||||
return
|
||||
}
|
||||
if (row.status === 'waiting' || (row.status === 'held' && !row.liveJobId)) {
|
||||
queued.value = true
|
||||
busy.value = true
|
||||
status.value = row.status === 'held' ? 'Paused in the job queue' : 'Waiting in the job queue…'
|
||||
return
|
||||
}
|
||||
if (row.status === 'error') {
|
||||
queued.value = false
|
||||
busy.value = false
|
||||
error.value = row.lastError || 'Generation failed'
|
||||
status.value = error.value
|
||||
stopQueuePoll()
|
||||
return
|
||||
}
|
||||
if (row.liveJobId && row.liveJobId !== jobId.value) {
|
||||
queued.value = false
|
||||
jobId.value = row.liveJobId
|
||||
status.value = status.value || 'Generating…'
|
||||
listen(row.liveJobId)
|
||||
}
|
||||
}
|
||||
|
||||
function applyEvent(payload: Record<string, any>) {
|
||||
if (payload.message) status.value = payload.message
|
||||
if (typeof payload.progress === 'number') progress.value = payload.progress
|
||||
@@ -253,6 +311,10 @@ function applyEvent(payload: Record<string, any>) {
|
||||
audioUrl.value = `/api/media?${params.toString()}`
|
||||
}
|
||||
stopListen()
|
||||
queued.value = false
|
||||
studioJobId.value = ''
|
||||
stopQueuePoll()
|
||||
queuePoll = setInterval(() => { void refreshStudioQueue() }, 8000)
|
||||
void notifyGenerationComplete('music')
|
||||
}
|
||||
if (payload.type === 'error' || payload.status === 'error') {
|
||||
@@ -260,7 +322,10 @@ function applyEvent(payload: Record<string, any>) {
|
||||
busy.value = false
|
||||
error.value = payload.error || payload.message || 'Generation failed'
|
||||
status.value = error.value
|
||||
queued.value = false
|
||||
stopListen()
|
||||
stopQueuePoll()
|
||||
queuePoll = setInterval(() => { void refreshStudioQueue() }, 8000)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,12 +358,15 @@ async function generate() {
|
||||
await ensureGenerationNotifyPermission()
|
||||
busy.value = true
|
||||
settled = false
|
||||
queued.value = false
|
||||
progress.value = 2
|
||||
audioUrl.value = ''
|
||||
trackId.value = ''
|
||||
jobId.value = ''
|
||||
studioJobId.value = ''
|
||||
status.value = 'Queueing ACE-Step…'
|
||||
try {
|
||||
const started = await $fetch<{ jobId: string; name?: string }>(
|
||||
const started = await $fetch<{ jobId: string; studioJobId?: string; queued?: boolean; name?: string }>(
|
||||
'/api/generate/music',
|
||||
{
|
||||
method: 'POST',
|
||||
@@ -314,11 +382,21 @@ async function generate() {
|
||||
}
|
||||
}
|
||||
)
|
||||
jobId.value = started.jobId
|
||||
studioJobId.value = started.studioJobId || ''
|
||||
if (started.name) downloadName.value = `${started.name}.flac`
|
||||
await refreshStudioQueue()
|
||||
stopQueuePoll()
|
||||
queuePoll = setInterval(() => { void refreshStudioQueue() }, 2500)
|
||||
if (started.queued) {
|
||||
queued.value = true
|
||||
status.value = 'Waiting in the job queue…'
|
||||
return
|
||||
}
|
||||
jobId.value = started.jobId
|
||||
listen(started.jobId)
|
||||
} catch (err: any) {
|
||||
busy.value = false
|
||||
queued.value = false
|
||||
error.value = err?.data?.statusMessage || err?.statusMessage || err?.message || 'Could not queue music generation'
|
||||
status.value = error.value
|
||||
}
|
||||
@@ -330,6 +408,9 @@ watch(instrumental, (on) => {
|
||||
|
||||
onMounted(async () => {
|
||||
await loadLibrary()
|
||||
await refreshStudioQueue()
|
||||
stopQueuePoll()
|
||||
queuePoll = setInterval(() => { void refreshStudioQueue() }, 8000)
|
||||
const query = useRoute().query
|
||||
if (typeof query.track === 'string' && query.track) {
|
||||
audioUrl.value = `/api/library/tracks/${query.track}/audio`
|
||||
@@ -340,5 +421,6 @@ onMounted(async () => {
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopListen()
|
||||
stopQueuePoll()
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user