Accept only YuE2 in the music generate API.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,16 +1,7 @@
|
|||||||
import { yueGpConfigured } from '~/server/utils/yueGp'
|
|
||||||
import { yue2Configured } from '~/server/utils/yue2'
|
import { yue2Configured } from '~/server/utils/yue2'
|
||||||
import { addStudioJob, kickStudioQueue, listStudioJobs, videoJobsBusy } from '~/server/utils/studioQueue'
|
import { addStudioJob, kickStudioQueue, listStudioJobs, videoJobsBusy } from '~/server/utils/studioQueue'
|
||||||
import { comfyConfigured } from '~/server/utils/comfy'
|
|
||||||
import {
|
import {
|
||||||
clampLyricsStrength,
|
|
||||||
clampMusicCfg,
|
|
||||||
clampMusicDuration,
|
clampMusicDuration,
|
||||||
clampMusicSteps,
|
|
||||||
MUSIC_CFG_DEFAULT,
|
|
||||||
MUSIC_CFG_DEFAULT_15,
|
|
||||||
MUSIC_STEPS_DEFAULT,
|
|
||||||
MUSIC_STEPS_DEFAULT_15,
|
|
||||||
parseMusicEngine,
|
parseMusicEngine,
|
||||||
parseMusicSeed,
|
parseMusicSeed,
|
||||||
sanitizeMusicLyrics,
|
sanitizeMusicLyrics,
|
||||||
@@ -23,37 +14,28 @@ export default defineEventHandler(async (event) => {
|
|||||||
tags?: unknown
|
tags?: unknown
|
||||||
lyrics?: unknown
|
lyrics?: unknown
|
||||||
duration?: unknown
|
duration?: unknown
|
||||||
steps?: unknown
|
|
||||||
seed?: unknown
|
seed?: unknown
|
||||||
cfg?: unknown
|
|
||||||
lyricsStrength?: unknown
|
|
||||||
instrumental?: unknown
|
|
||||||
folderId?: unknown
|
folderId?: unknown
|
||||||
name?: unknown
|
name?: unknown
|
||||||
yueProfile?: unknown
|
|
||||||
engine?: unknown
|
engine?: unknown
|
||||||
sampler_name?: unknown
|
|
||||||
scheduler?: unknown
|
|
||||||
}>(event).catch(() => ({} as Record<string, unknown>))
|
}>(event).catch(() => ({} as Record<string, unknown>))
|
||||||
|
|
||||||
const engine = parseMusicEngine(body.engine)
|
const engine = parseMusicEngine(body.engine)
|
||||||
if (engine === 'yue' && !yueGpConfigured()) throw createError({ statusCode: 503, statusMessage: 'YuEGP host is not configured. Set COMFY_CONTROL_URL.' })
|
if (engine !== 'yue2') {
|
||||||
if (engine === 'yue2' && !yue2Configured()) throw createError({ statusCode: 503, statusMessage: 'YuE2 host is not configured. Set COMFY_CONTROL_URL.' })
|
throw createError({ statusCode: 400, statusMessage: 'Only YuE2 is supported for music generation.' })
|
||||||
if (engine !== 'yue' && engine !== 'yue2' && !comfyConfigured()) {
|
}
|
||||||
throw createError({
|
if (!yue2Configured()) {
|
||||||
statusCode: 503,
|
throw createError({ statusCode: 503, statusMessage: 'YuE2 host is not configured. Set COMFY_CONTROL_URL.' })
|
||||||
statusMessage: 'Beast ComfyUI is not configured. Set COMFY_HOST.'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const instrumental = body.instrumental === true || body.instrumental === 'true'
|
|
||||||
const tags = sanitizeMusicTags(body.tags)
|
const tags = sanitizeMusicTags(body.tags)
|
||||||
const lyrics = sanitizeMusicLyrics(body.lyrics, instrumental)
|
const lyrics = sanitizeMusicLyrics(body.lyrics, false)
|
||||||
if (!tags) {
|
if (!tags) {
|
||||||
throw createError({ statusCode: 400, statusMessage: 'Genre and style tags are required' })
|
throw createError({ statusCode: 400, statusMessage: 'Genre and style tags are required' })
|
||||||
}
|
}
|
||||||
if (!instrumental && !lyrics) {
|
const lyricsProblem = yueLyricsProblem(lyrics)
|
||||||
throw createError({ statusCode: 400, statusMessage: 'Lyrics are required unless Instrumental is on' })
|
if (lyricsProblem) {
|
||||||
|
throw createError({ statusCode: 400, statusMessage: lyricsProblem })
|
||||||
}
|
}
|
||||||
|
|
||||||
const ownerKey = libraryOwnerKey(event)
|
const ownerKey = libraryOwnerKey(event)
|
||||||
@@ -68,34 +50,12 @@ export default defineEventHandler(async (event) => {
|
|||||||
const destFolder = library.folders.find(folder => folder.id === folderId)
|
const destFolder = library.folders.find(folder => folder.id === folderId)
|
||||||
const folderLocked = Boolean(destFolder?.protected && !destFolder.unlocked)
|
const folderLocked = Boolean(destFolder?.protected && !destFolder.unlocked)
|
||||||
|
|
||||||
if ((engine === 'yue' || engine === 'yue2') && instrumental) throw createError({ statusCode: 400, statusMessage: 'YuE currently requires lyrics. Use ACE for instrumental music.' })
|
|
||||||
const yueProfile = body.yueProfile ?? 1
|
|
||||||
if (engine === 'yue' && yueProfile !== 1 && yueProfile !== 3) throw createError({ statusCode: 400, statusMessage: 'Choose YuEGP profile 1 or manual fallback 3.' })
|
|
||||||
if (engine === 'yue' && !instrumental) {
|
|
||||||
const problem = yueLyricsProblem(lyrics)
|
|
||||||
if (problem) throw createError({ statusCode: 400, statusMessage: problem })
|
|
||||||
}
|
|
||||||
if (engine === 'yue2' && !instrumental && !lyrics) {
|
|
||||||
throw createError({ statusCode: 400, statusMessage: 'YuE2 needs lyrics.' })
|
|
||||||
}
|
|
||||||
const duration = clampMusicDuration(body.duration)
|
const duration = clampMusicDuration(body.duration)
|
||||||
if ((engine === 'yue' || engine === 'yue2') && duration > 150) throw createError({ statusCode: 400, statusMessage: 'YuE supports up to 150 seconds per section.' })
|
|
||||||
const steps = clampMusicSteps(
|
|
||||||
body.steps,
|
|
||||||
engine === 'ace-step-1.5' ? MUSIC_STEPS_DEFAULT_15 : MUSIC_STEPS_DEFAULT
|
|
||||||
)
|
|
||||||
const cfg = clampMusicCfg(
|
|
||||||
body.cfg,
|
|
||||||
engine === 'ace-step-1.5' ? MUSIC_CFG_DEFAULT_15 : MUSIC_CFG_DEFAULT
|
|
||||||
)
|
|
||||||
const lyricsStrength = clampLyricsStrength(body.lyricsStrength)
|
|
||||||
const seed = parseMusicSeed(body.seed)
|
const seed = parseMusicSeed(body.seed)
|
||||||
const clipName = allocateOutputName(ownerKey, folderId, String(body.name || '').trim(), {
|
const clipName = allocateOutputName(ownerKey, folderId, String(body.name || '').trim(), {
|
||||||
engine: engine === 'ace-step-1.5' ? 'ace15' : engine === 'yue' ? 'yue' : engine === 'yue2' ? 'yue2' : 'ace'
|
engine: 'yue2'
|
||||||
})
|
})
|
||||||
|
|
||||||
const samplerName = String(body.sampler_name || 'euler')
|
|
||||||
const scheduler = String(body.scheduler || 'simple')
|
|
||||||
const familyId = crypto.randomUUID()
|
const familyId = crypto.randomUUID()
|
||||||
const studio = await addStudioJob({
|
const studio = await addStudioJob({
|
||||||
ownerKey,
|
ownerKey,
|
||||||
@@ -108,15 +68,15 @@ export default defineEventHandler(async (event) => {
|
|||||||
aspect: 'audio',
|
aspect: 'audio',
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
steps,
|
steps: 0,
|
||||||
turbo: false,
|
turbo: false,
|
||||||
seed,
|
seed,
|
||||||
cfg,
|
cfg: 0,
|
||||||
fps: 0,
|
fps: 0,
|
||||||
samplerName,
|
samplerName: 'euler',
|
||||||
scheduler,
|
scheduler: 'simple',
|
||||||
duration,
|
duration,
|
||||||
sound: !instrumental,
|
sound: true,
|
||||||
workflow: 'v1',
|
workflow: 'v1',
|
||||||
useIdentityRefs: false,
|
useIdentityRefs: false,
|
||||||
hideThumbnail: false,
|
hideThumbnail: false,
|
||||||
@@ -125,10 +85,9 @@ export default defineEventHandler(async (event) => {
|
|||||||
extensions: [],
|
extensions: [],
|
||||||
queueAutoRun: false,
|
queueAutoRun: false,
|
||||||
lyrics,
|
lyrics,
|
||||||
instrumental,
|
instrumental: false,
|
||||||
lyricsStrength,
|
lyricsStrength: 0,
|
||||||
musicEngine: engine,
|
musicEngine: 'yue2'
|
||||||
...(engine === 'yue' ? { yueProfile: yueProfile as 1 | 3 } : {})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
await kickStudioQueue()
|
await kickStudioQueue()
|
||||||
@@ -145,11 +104,9 @@ export default defineEventHandler(async (event) => {
|
|||||||
queued: !liveJobId,
|
queued: !liveJobId,
|
||||||
seed,
|
seed,
|
||||||
duration,
|
duration,
|
||||||
steps,
|
|
||||||
cfg,
|
|
||||||
folderId,
|
folderId,
|
||||||
folderLocked,
|
folderLocked,
|
||||||
engine,
|
engine: 'yue2' as const,
|
||||||
name: clipName
|
name: clipName
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user