Files
aigen/shared/studio2/input.mjs
T

57 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { restoreInput } from './contracts.mjs'
export const aspectOptions = [{id:'auto',label:'Automatic',hint:'Match start or hero still'},{id:'16:9',label:'16:9',hint:'1344 × 768 · padded'},{id:'9:16',label:'9:16',hint:'768 × 1344 · padded'},{id:'1:1',label:'1:1',hint:'960 × 960 · padded'}]
export function resolveSize(aspect, source, fallback = {width:1344,height:768}) {
const presets = {'16:9':[1344,768],'9:16':[768,1344],'1:1':[960,960]}
if (presets[aspect]) return {width:presets[aspect][0],height:presets[aspect][1]}
if (!source?.width || !source?.height) return {width:fallback.width || 1344,height:fallback.height || 768}
const factor = Math.min(1344/Math.max(source.width,source.height),768/Math.min(source.width,source.height))
return {width:Math.max(256,Math.round(source.width*factor/32)*32),height:Math.max(256,Math.round(source.height*factor/32)*32)}
}
export function bindClip(form, clip, xaigen = false) {
if (!clip?.id) return form
const saved = clip.studio2 || clip.job || {}, settings = saved.settings || clip.settings || clip
const next = {...form, startClipId:clip.id, settings:{...form.settings}}
next.settings.aspect=['auto','16:9','9:16','1:1'].includes(settings.aspect)?settings.aspect:'auto'
for (const key of ['duration','aspect','width','height','fps','loraStack','turbo','steps','cfg']) {
if (settings[key] != null && key!=='aspect') next.settings[key] = structuredClone(settings[key])
}
next.engine = xaigen && (saved.engine || clip.engine)==='ltx' ? 'ltx' : 'minimax'
if (saved.identityStillId) next.identityStillId = saved.identityStillId
// Missing legacy metadata must not reset a user's current choice.
for (const key of ['lockFace','lockOutfit']) if (typeof saved[key] === 'boolean') next[key] = saved[key]
return next
}
export function restoreAsset(form, item) {
if (item.kind==='clip' || item.studio2?.kind==='video') {
const next=bindClip(form,item,form.engine==='ltx')
const seed=item.studio2?.settings?.seed ?? item.settings?.seed ?? item.seed
if (seed != null) next.settings.seed=seed
next.settings.seedMode='random'
return {...next,mode:'extend'}
}
const restored = restoreInput(item)
const next = {...form,...restored,settings:{...form.settings,...restored.settings}}
next.settings.seedMode='random'
if (item.kind === 'clip' || item.studio2?.kind === 'video') return {...bindClip(next,item),mode:'extend'}
next.imageAId=item.id
next.startClipId=''
next.settings.aspect=item.studio2?.settings?.aspect || item.settings?.aspect || 'auto'
return next
}
export function extendSelected(form, clip, xaigen = false) {
// Switching task on the already bound clip must preserve the user's overrides.
const next=clip?.id && form.startClipId !== clip.id ? bindClip(form,clip,xaigen) : form
return {...next,mode:'extend',engine:xaigen && next.engine==='ltx'?'ltx':'minimax'}
}
export function changeSource(form) {
return form.mode==='extend' ? form : {...form,startClipId:'',settings:{...form.settings,aspect:'auto'}}
}
export function useAsHero(form, item) { return {...form,identityStillId:item.id} }
export function useAsSource(form, item) { return {...form,imageAId:item.id} }
export function restoreAll(form,item) {
const restored=restoreInput(item),next={...form,...restored,settings:{...form.settings,...restored.settings,seedMode:'random'}}
next.mode=restored.mode==='iterate'?'edit':restored.mode || (item.kind==='clip'?'video':'edit')
return next
}