Keep every saved segment, show the longest clip with an expand list, branch on extend, and parse shot 2/3 blocks into a shared-duration queue with live part status.
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
export interface ParsedShot {
|
|
n: number
|
|
prompt: string
|
|
role: 'initial' | 'extension'
|
|
}
|
|
|
|
export function parseShotScript(text: string): ParsedShot[] {
|
|
const src = String(text || '').replace(/\r\n/g, '\n')
|
|
const marker = /shot\s+(\d+)\b/gi
|
|
const markers: { n: number; start: number; end: number }[] = []
|
|
for (const match of src.matchAll(marker)) {
|
|
markers.push({
|
|
n: Number(match[1]),
|
|
start: match.index || 0,
|
|
end: (match.index || 0) + match[0].length
|
|
})
|
|
}
|
|
const blocks: { n: number; prompt: string }[] = []
|
|
if (!markers.length) {
|
|
const prompt = src.trim()
|
|
return prompt ? [{ n: 1, prompt, role: 'initial' }] : []
|
|
}
|
|
const preamble = src.slice(0, markers[0].start).trim()
|
|
if (preamble) blocks.push({ n: 1, prompt: preamble })
|
|
for (let i = 0; i < markers.length; i++) {
|
|
const from = markers[i].end
|
|
const to = i + 1 < markers.length ? markers[i + 1].start : src.length
|
|
const prompt = src.slice(from, to).trim()
|
|
if (prompt) blocks.push({ n: markers[i].n, prompt })
|
|
}
|
|
const byN = new Map<number, string>()
|
|
for (const block of blocks) {
|
|
const prev = byN.get(block.n)
|
|
byN.set(block.n, prev ? `${prev}\n${block.prompt}` : block.prompt)
|
|
}
|
|
return [...byN.entries()]
|
|
.sort((a, b) => a[0] - b[0])
|
|
.map(([n, prompt], index) => ({
|
|
n,
|
|
prompt,
|
|
role: index === 0 ? 'initial' : 'extension'
|
|
}))
|
|
}
|