File size: 3,539 Bytes
a65e95e
bda5f6b
a65e95e
bda5f6b
a65e95e
 
 
bda5f6b
 
 
 
9658ad9
 
a65e95e
9658ad9
a65e95e
 
9658ad9
a65e95e
9658ad9
e2472ff
a65e95e
9658ad9
 
 
 
a65e95e
e2472ff
a65e95e
bda5f6b
 
 
 
 
a65e95e
 
 
 
bda5f6b
a65e95e
 
9658ad9
e2472ff
29598d1
 
e2472ff
29598d1
a65e95e
 
 
 
 
bda5f6b
 
e2472ff
a65e95e
e2472ff
bda5f6b
a65e95e
9658ad9
e2472ff
 
9658ad9
e2472ff
bda5f6b
 
e2472ff
 
9658ad9
a65e95e
9658ad9
e2472ff
 
9658ad9
e2472ff
9658ad9
a65e95e
 
 
 
 
bda5f6b
 
a65e95e
 
 
9658ad9
a65e95e
 
 
 
9658ad9
a65e95e
 
9658ad9
 
a65e95e
 
9658ad9
 
a65e95e
bda5f6b
a65e95e
e2472ff
 
a65e95e
 
 
bda5f6b
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { promises as fs } from "fs"

import express from "express"

import { generateSeed } from "./services/generateSeed.mts"
import { Job, ShotQuery } from "./types.mts"
import { generateShot } from "./services/generateShot.mts"

const app = express()
const port = 7860

app.use(express.json())

const queue: Job[] = []

app.post("/shot", async (req, res) => {
  const query = req.body as ShotQuery

  const token = `${query.token || ""}`
  if (token !== process.env.VS_SECRET_ACCESS_TOKEN) {
    console.log("couldn't find access token in the query")
    res.write(JSON.stringify({ error: true, message: "access denied" }))
    res.end()
    return
  }

  const shotPrompt = `${query.shotPrompt || ""}`
  if (shotPrompt.length < 5) {
    res.write(JSON.stringify({ error: true, message: "prompt too short (must be at least 5 in length)" }))
    res.end()
    return
  }

  // optional video URL
  // const inputVideo = `${req.query.inputVideo || ""}`

  // optional background audio prompt
  const backgroundAudioPrompt = `${query.backgroundAudioPrompt || ""}`

  // optional foreground audio prompt
  const foregroundAudioPrompt = `${query.foregroundAudioPrompt || ""}`

  // optional seed
  const defaultSeed = generateSeed()
  const seedStr = Number(`${query.seed || defaultSeed}`)
  const maybeSeed = Number(seedStr)
  const seed = isNaN(maybeSeed) || ! isFinite(maybeSeed) ? defaultSeed : maybeSeed
  
  // in production we want those ON by default
  const upscale = `${query.upscale || "true"}` === "true"
  const interpolate = `${query.upscale || "true"}` === "true"
  const noise = `${query.noise || "true"}` === "true"


  const defaultDuration = 3
  const maxDuration = 5
  const durationStr = Number(`${query.duration || defaultDuration}`)
  const maybeDuration = Number(durationStr)
  const duration = Math.min(maxDuration, Math.max(1, isNaN(maybeDuration) || !isFinite(maybeDuration) ? defaultDuration : maybeDuration))
  
  const defaultSteps = 35
  const stepsStr = Number(`${query.steps || defaultSteps}`)
  const maybeSteps = Number(stepsStr)
  const nbSteps = Math.min(60, Math.max(1, isNaN(maybeSteps) || !isFinite(maybeSteps) ? defaultSteps : maybeSteps))
  
  // const frames per second
  const defaultFps = 24
  const fpsStr = Number(`${query.fps || defaultFps}`)
  const maybeFps = Number(fpsStr)
  const nbFrames = Math.min(60, Math.max(8, isNaN(maybeFps) || !isFinite(maybeFps) ? defaultFps : maybeFps))
  
  const defaultResolution = 576
  const resolutionStr = Number(`${query.resolution || defaultResolution}`)
  const maybeResolution = Number(resolutionStr)
  const resolution = Math.min(1080, Math.max(256, isNaN(maybeResolution) || !isFinite(maybeResolution) ? defaultResolution : maybeResolution))
  
  const actorPrompt = `${query.actorPrompt || ""}`

  const actorVoicePrompt = `${query.actorVoicePrompt || ""}`

  const actorDialoguePrompt = `${query.actorDialoguePrompt || ""}`


  const { filePath } = await generateShot({
    seed,
    actorPrompt,
    shotPrompt,
    backgroundAudioPrompt,
    foregroundAudioPrompt,
    actorDialoguePrompt,
    actorVoicePrompt,
    duration,
    nbFrames,
    resolution,
    nbSteps,
    upscale,
    interpolate,
    noise,
  })

  console.log(`generated video in ${filePath}`)

  console.log("returning result to user..")

  const buffer = await fs.readFile(filePath)

  res.setHeader("Content-Type", "media/mp4")
  res.setHeader("Content-Length", buffer.length)
  res.end(buffer)
})

app.listen(port, () => { console.log(`Open http://localhost:${port}`) })