Use the parent clip last frame and new-segment join for extensions, not the stitched file's first frame. Show this account's library storage in Settings.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-28 10:54:46 -05:00
co-authored by Cursor
parent 231c59a7a7
commit 0af3cddb14
16 changed files with 571 additions and 70 deletions
+4 -1
View File
@@ -172,8 +172,11 @@ async function runExtend(
}
) {
copyFileSync(params.sourcePath, params.part1Path)
await extractLastFrame(params.part1Path, params.framePath)
await extractLastFrame(params.sourcePath, params.framePath)
const frame = readFileSync(params.framePath)
if (!frame.length || frame.length < 64) {
throw new Error('Could not extract the last frame of the clip being extended')
}
if (job.library) job.library.thumb = undefined
const sound = await probeHasAudio(params.part1Path)
+3 -2
View File
@@ -1,6 +1,6 @@
import { addStudioJob, kickStudioQueue, listStudioJobs } from '~/server/utils/studioQueue'
import { defaultVideoSteps, isLtxWorkflow, isTextToVideo, parseVideoWorkflow } from '~/utils/videoModels'
import { normalizePermanenceRefs, resolveGlobalLocks, type PermanenceRef } from '~/utils/globalLocks'
import { allowIdentityRefs, normalizePermanenceRefs, resolveGlobalLocks, type PermanenceRef } from '~/utils/globalLocks'
function parseDuration(raw: unknown) {
const seconds = Number(raw)
@@ -121,7 +121,8 @@ export default defineEventHandler(async (event) => {
shotPermanenceRefs[index + 1] = item.permanenceRefs
}
}
const useIdentityRefs = workflow === 'v2' && !textToVideo && !isLtxWorkflow(workflow) && fields.useIdentityRefs === 'true'
const requestedIdentity = workflow === 'v2' && !textToVideo && !isLtxWorkflow(workflow) && fields.useIdentityRefs === 'true'
const useIdentityRefs = allowIdentityRefs(requestedIdentity, permanenceRefs, globalLocks, shotPermanenceRefs)
const { width, height } = resolveOutputSize(
fields.aspect,
image?.data || Buffer.alloc(0),
@@ -27,7 +27,7 @@ export default defineEventHandler(async (event) => {
const etag = fileEtag(path)
setHeader(event, 'ETag', etag)
setHeader(event, 'Cache-Control', wantThumb ? 'private, max-age=86400, stale-while-revalidate=604800' : 'private, max-age=3600')
setHeader(event, 'Cache-Control', wantThumb ? 'private, max-age=60, must-revalidate' : 'private, max-age=60, must-revalidate')
if (getHeader(event, 'if-none-match') === etag) {
setResponseStatus(event, 304)
return null
@@ -27,7 +27,7 @@ export default defineEventHandler(async (event) => {
const etag = fileEtag(path)
setHeader(event, 'ETag', etag)
setHeader(event, 'Cache-Control', wantThumb ? 'private, max-age=86400, stale-while-revalidate=604800' : 'private, max-age=3600')
setHeader(event, 'Cache-Control', wantThumb ? 'private, max-age=60, must-revalidate' : 'private, max-age=60, must-revalidate')
if (getHeader(event, 'if-none-match') === etag) {
setResponseStatus(event, 304)
return null
+4
View File
@@ -0,0 +1,4 @@
export default defineEventHandler(async (event) => {
const { owner } = assertLibraryOwner(event)
return libraryStorage(owner)
})