Spaces:
Paused
Paused
Commit
·
7bea24d
1
Parent(s):
c5b0dde
basic generation (without audio) works
Browse files- src/index.mts +2 -1
- src/production/postInterpolation.mts +2 -2
- src/scheduler/processTask.mts +5 -4
- src/scheduler/readTasks.mts +5 -1
- src/scheduler/savePendingTask.mts +2 -0
- src/types.mts +0 -1
- src/utils/getValidResolution.mts +4 -2
- src/utils/parseShotRequest.mts +1 -1
- src/utils/parseVideoRequest.mts +5 -1
src/index.mts
CHANGED
|
@@ -34,10 +34,11 @@ app.post("/", async (req, res) => {
|
|
| 34 |
let task: VideoTask = null
|
| 35 |
|
| 36 |
console.log(`creating task from request..`)
|
|
|
|
| 37 |
try {
|
| 38 |
task = await parseVideoRequest(request)
|
| 39 |
} catch (err) {
|
| 40 |
-
console.error(`failed to create task: ${task}`)
|
| 41 |
res.status(400)
|
| 42 |
res.write(JSON.stringify({ error: "query seems to be malformed" }))
|
| 43 |
res.end()
|
|
|
|
| 34 |
let task: VideoTask = null
|
| 35 |
|
| 36 |
console.log(`creating task from request..`)
|
| 37 |
+
console.log(`request: `, JSON.stringify(request))
|
| 38 |
try {
|
| 39 |
task = await parseVideoRequest(request)
|
| 40 |
} catch (err) {
|
| 41 |
+
console.error(`failed to create task: ${task} (${err})`)
|
| 42 |
res.status(400)
|
| 43 |
res.write(JSON.stringify({ error: "query seems to be malformed" }))
|
| 44 |
res.end()
|
src/production/postInterpolation.mts
CHANGED
|
@@ -20,13 +20,13 @@ export const postInterpolation = async (fileName: string, durationMs: number, nb
|
|
| 20 |
|
| 21 |
const currentVideoDurationInSec = metadata.format.duration
|
| 22 |
|
| 23 |
-
console.log(`
|
| 24 |
|
| 25 |
console.log(`target duration in sec: ${durationInSec}s (${durationMs}ms)`)
|
| 26 |
|
| 27 |
// compute a ratio ex. 0.3 = 30% of the total length
|
| 28 |
const durationRatio = currentVideoDurationInSec / durationInSec
|
| 29 |
-
console.log(`durationRatio: ${durationRatio}
|
| 30 |
|
| 31 |
ffmpeg(filePath)
|
| 32 |
|
|
|
|
| 20 |
|
| 21 |
const currentVideoDurationInSec = metadata.format.duration
|
| 22 |
|
| 23 |
+
console.log(`currentVideoDurationInSec in sec: ${currentVideoDurationInSec}s`)
|
| 24 |
|
| 25 |
console.log(`target duration in sec: ${durationInSec}s (${durationMs}ms)`)
|
| 26 |
|
| 27 |
// compute a ratio ex. 0.3 = 30% of the total length
|
| 28 |
const durationRatio = currentVideoDurationInSec / durationInSec
|
| 29 |
+
console.log(`durationRatio: ${durationRatio}`)
|
| 30 |
|
| 31 |
ffmpeg(filePath)
|
| 32 |
|
src/scheduler/processTask.mts
CHANGED
|
@@ -57,7 +57,7 @@ export const processTask = async (task: VideoTask) => {
|
|
| 57 |
// await copyVideoFromTmpToPending(shot.fileName)
|
| 58 |
|
| 59 |
// copy from /tmp to /data/completed
|
| 60 |
-
await copyVideoFromTmpToCompleted(shot.fileName)
|
| 61 |
|
| 62 |
shot.hasGeneratedPreview = true
|
| 63 |
shot.nbCompletedSteps++
|
|
@@ -201,16 +201,17 @@ export const processTask = async (task: VideoTask) => {
|
|
| 201 |
|
| 202 |
console.log(`end of the loop:`)
|
| 203 |
console.log(`nb completed shots: ${task.nbCompletedShots}`)
|
|
|
|
| 204 |
|
| 205 |
-
if (task.nbCompletedShots === task.
|
| 206 |
console.log(`we have completed the whole video sequence!`)
|
| 207 |
console.log(`assembling the video..`)
|
| 208 |
|
| 209 |
-
if (task.
|
| 210 |
console.log(`we only have one shot, so this gonna be easy`)
|
| 211 |
task.hasAssembledVideo = true
|
| 212 |
|
| 213 |
-
// the shot
|
| 214 |
await moveVideoFromPendingToCompleted(task.shots[0].fileName, task.fileName)
|
| 215 |
|
| 216 |
await updatePendingTask(task)
|
|
|
|
| 57 |
// await copyVideoFromTmpToPending(shot.fileName)
|
| 58 |
|
| 59 |
// copy from /tmp to /data/completed
|
| 60 |
+
await copyVideoFromTmpToCompleted(shot.fileName, task.fileName)
|
| 61 |
|
| 62 |
shot.hasGeneratedPreview = true
|
| 63 |
shot.nbCompletedSteps++
|
|
|
|
| 201 |
|
| 202 |
console.log(`end of the loop:`)
|
| 203 |
console.log(`nb completed shots: ${task.nbCompletedShots}`)
|
| 204 |
+
console.log(`len of the shot array: ${task.shots.length}`)
|
| 205 |
|
| 206 |
+
if (task.nbCompletedShots === task.shots.length) {
|
| 207 |
console.log(`we have completed the whole video sequence!`)
|
| 208 |
console.log(`assembling the video..`)
|
| 209 |
|
| 210 |
+
if (task.shots.length === 1) {
|
| 211 |
console.log(`we only have one shot, so this gonna be easy`)
|
| 212 |
task.hasAssembledVideo = true
|
| 213 |
|
| 214 |
+
// the single shot (so, the first) becomes the final movie
|
| 215 |
await moveVideoFromPendingToCompleted(task.shots[0].fileName, task.fileName)
|
| 216 |
|
| 217 |
await updatePendingTask(task)
|
src/scheduler/readTasks.mts
CHANGED
|
@@ -10,16 +10,20 @@ export const readTasks = async (taskDirFilePath: string): Promise<VideoTask[]> =
|
|
| 10 |
let tasksFiles: string[] = []
|
| 11 |
try {
|
| 12 |
const filesInDir = await fs.readdir(taskDirFilePath)
|
|
|
|
| 13 |
|
| 14 |
// we only keep valid files (in UUID.json format)
|
| 15 |
tasksFiles = filesInDir.filter(fileName => fileName.match(/[a-z0-9\-]\.json/i))
|
|
|
|
|
|
|
| 16 |
} catch (err) {
|
| 17 |
console.log(`failed to read tasks: ${err}`)
|
| 18 |
}
|
| 19 |
|
| 20 |
const tasks: VideoTask[] = []
|
| 21 |
|
| 22 |
-
for (const taskFileName
|
|
|
|
| 23 |
const taskFilePath = path.join(taskDirFilePath, taskFileName)
|
| 24 |
try {
|
| 25 |
const task = await readTask(taskFilePath)
|
|
|
|
| 10 |
let tasksFiles: string[] = []
|
| 11 |
try {
|
| 12 |
const filesInDir = await fs.readdir(taskDirFilePath)
|
| 13 |
+
console.log("filesInDir:", filesInDir)
|
| 14 |
|
| 15 |
// we only keep valid files (in UUID.json format)
|
| 16 |
tasksFiles = filesInDir.filter(fileName => fileName.match(/[a-z0-9\-]\.json/i))
|
| 17 |
+
|
| 18 |
+
console.log("tasksfiles:", tasksFiles)
|
| 19 |
} catch (err) {
|
| 20 |
console.log(`failed to read tasks: ${err}`)
|
| 21 |
}
|
| 22 |
|
| 23 |
const tasks: VideoTask[] = []
|
| 24 |
|
| 25 |
+
for (const taskFileName of tasksFiles) {
|
| 26 |
+
console.log("taskFileName:", taskFileName)
|
| 27 |
const taskFilePath = path.join(taskDirFilePath, taskFileName)
|
| 28 |
try {
|
| 29 |
const task = await readTask(taskFilePath)
|
src/scheduler/savePendingTask.mts
CHANGED
|
@@ -7,5 +7,7 @@ import { pendingTasksDirFilePath } from "../config.mts"
|
|
| 7 |
export const savePendingTask = async (task: VideoTask) => {
|
| 8 |
const fileName = `${task.id}.json`
|
| 9 |
const filePath = path.join(pendingTasksDirFilePath, fileName)
|
|
|
|
|
|
|
| 10 |
await fs.writeFile(filePath, JSON.stringify(task, null, 2), "utf8")
|
| 11 |
}
|
|
|
|
| 7 |
export const savePendingTask = async (task: VideoTask) => {
|
| 8 |
const fileName = `${task.id}.json`
|
| 9 |
const filePath = path.join(pendingTasksDirFilePath, fileName)
|
| 10 |
+
console.log("fileName:", fileName)
|
| 11 |
+
console.log("filePath:", filePath)
|
| 12 |
await fs.writeFile(filePath, JSON.stringify(task, null, 2), "utf8")
|
| 13 |
}
|
src/types.mts
CHANGED
|
@@ -210,7 +210,6 @@ export interface VideoSequenceData {
|
|
| 210 |
|
| 211 |
hasAssembledVideo: boolean
|
| 212 |
nbCompletedShots: number
|
| 213 |
-
nbTotalShots: number
|
| 214 |
progressPercent: number
|
| 215 |
completedAt: string
|
| 216 |
completed: boolean
|
|
|
|
| 210 |
|
| 211 |
hasAssembledVideo: boolean
|
| 212 |
nbCompletedShots: number
|
|
|
|
| 213 |
progressPercent: number
|
| 214 |
completedAt: string
|
| 215 |
completed: boolean
|
src/utils/getValidResolution.mts
CHANGED
|
@@ -3,8 +3,10 @@ import { getValidNumber } from "./getValidNumber.mts"
|
|
| 3 |
export const getValidResolution = (something: any) => {
|
| 4 |
const strValue = `${something || ''}`
|
| 5 |
const chunks = strValue.split('x')
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
| 8 |
}
|
| 9 |
|
| 10 |
const [widthStr, heightStr] = chunks
|
|
|
|
| 3 |
export const getValidResolution = (something: any) => {
|
| 4 |
const strValue = `${something || ''}`
|
| 5 |
const chunks = strValue.split('x')
|
| 6 |
+
console.log("chunks:", chunks)
|
| 7 |
+
|
| 8 |
+
if (chunks.length !== 2) {
|
| 9 |
+
return `1280x720`
|
| 10 |
}
|
| 11 |
|
| 12 |
const [widthStr, heightStr] = chunks
|
src/utils/parseShotRequest.mts
CHANGED
|
@@ -7,7 +7,7 @@ import { generateSeed } from "./generateSeed.mts"
|
|
| 7 |
import { getValidNumber } from "./getValidNumber.mts"
|
| 8 |
import { shotFormatVersion } from "../config.mts"
|
| 9 |
|
| 10 |
-
export const parseShotRequest = async (sequence: VideoSequence, maybeShotMeta: VideoShotMeta): Promise<VideoShot> => {
|
| 11 |
// we don't want people to input their own ID or we might have trouble,
|
| 12 |
// such as people attempting to use a non-UUID, a file path (to hack us), etc
|
| 13 |
const id = uuidv4()
|
|
|
|
| 7 |
import { getValidNumber } from "./getValidNumber.mts"
|
| 8 |
import { shotFormatVersion } from "../config.mts"
|
| 9 |
|
| 10 |
+
export const parseShotRequest = async (sequence: VideoSequence, maybeShotMeta: Partial<VideoShotMeta>): Promise<VideoShot> => {
|
| 11 |
// we don't want people to input their own ID or we might have trouble,
|
| 12 |
// such as people attempting to use a non-UUID, a file path (to hack us), etc
|
| 13 |
const id = uuidv4()
|
src/utils/parseVideoRequest.mts
CHANGED
|
@@ -19,6 +19,7 @@ export const parseVideoRequest = async (request: VideoTaskRequest): Promise<Vide
|
|
| 19 |
const id = uuidv4()
|
| 20 |
|
| 21 |
if (typeof request.prompt === "string" && request.prompt.length > 0) {
|
|
|
|
| 22 |
// TODO: use llama2 to populate this!
|
| 23 |
request.sequence = {
|
| 24 |
videoPrompt: request.prompt,
|
|
@@ -28,6 +29,7 @@ export const parseVideoRequest = async (request: VideoTaskRequest): Promise<Vide
|
|
| 28 |
}]
|
| 29 |
}
|
| 30 |
|
|
|
|
| 31 |
const task: VideoTask = {
|
| 32 |
// ------------ VideoSequenceMeta -------------
|
| 33 |
id,
|
|
@@ -68,7 +70,6 @@ export const parseVideoRequest = async (request: VideoTaskRequest): Promise<Vide
|
|
| 68 |
fileName: `${id}.mp4`,
|
| 69 |
hasAssembledVideo: false,
|
| 70 |
nbCompletedShots: 0,
|
| 71 |
-
nbTotalShots: 0,
|
| 72 |
progressPercent: 0,
|
| 73 |
completedAt: null,
|
| 74 |
completed: false,
|
|
@@ -80,9 +81,12 @@ export const parseVideoRequest = async (request: VideoTaskRequest): Promise<Vide
|
|
| 80 |
shots: [],
|
| 81 |
}
|
| 82 |
|
|
|
|
| 83 |
const maybeShots = Array.isArray(request.shots) ? request.shots : []
|
| 84 |
|
|
|
|
| 85 |
for (const maybeShot of maybeShots) {
|
|
|
|
| 86 |
try {
|
| 87 |
const shot = await parseShotRequest(task, maybeShot)
|
| 88 |
task.shots.push(shot)
|
|
|
|
| 19 |
const id = uuidv4()
|
| 20 |
|
| 21 |
if (typeof request.prompt === "string" && request.prompt.length > 0) {
|
| 22 |
+
console.log("we have a valid prompt:", request.prompt)
|
| 23 |
// TODO: use llama2 to populate this!
|
| 24 |
request.sequence = {
|
| 25 |
videoPrompt: request.prompt,
|
|
|
|
| 29 |
}]
|
| 30 |
}
|
| 31 |
|
| 32 |
+
console.log("continuing..")
|
| 33 |
const task: VideoTask = {
|
| 34 |
// ------------ VideoSequenceMeta -------------
|
| 35 |
id,
|
|
|
|
| 70 |
fileName: `${id}.mp4`,
|
| 71 |
hasAssembledVideo: false,
|
| 72 |
nbCompletedShots: 0,
|
|
|
|
| 73 |
progressPercent: 0,
|
| 74 |
completedAt: null,
|
| 75 |
completed: false,
|
|
|
|
| 81 |
shots: [],
|
| 82 |
}
|
| 83 |
|
| 84 |
+
console.log("we are still good..")
|
| 85 |
const maybeShots = Array.isArray(request.shots) ? request.shots : []
|
| 86 |
|
| 87 |
+
console.log("let's try..")
|
| 88 |
for (const maybeShot of maybeShots) {
|
| 89 |
+
console.log("trying shot", maybeShot)
|
| 90 |
try {
|
| 91 |
const shot = await parseShotRequest(task, maybeShot)
|
| 92 |
task.shots.push(shot)
|