File size: 3,789 Bytes
bda5f6b
e2472ff
bda5f6b
e2472ff
bda5f6b
 
9658ad9
bda5f6b
 
9658ad9
 
bda5f6b
 
 
 
9658ad9
 
 
bda5f6b
9658ad9
 
e2472ff
9658ad9
 
e2472ff
9658ad9
 
 
 
 
 
e2472ff
 
bda5f6b
 
 
 
 
9658ad9
bda5f6b
 
9658ad9
 
e2472ff
 
 
 
9658ad9
bda5f6b
 
9658ad9
bda5f6b
 
e2472ff
 
bda5f6b
e2472ff
9658ad9
e2472ff
 
9658ad9
e2472ff
bda5f6b
 
e2472ff
 
9658ad9
e2472ff
9658ad9
e2472ff
 
9658ad9
e2472ff
9658ad9
bda5f6b
 
 
9658ad9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bda5f6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e2472ff
 
 
 
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
113
114
115
116
117
118
119
120
121
import { promises as fs } from 'fs'
import path from 'node:path'

import tmpDir from 'temp-dir'
import express from 'express'

import { generateVideo } from './services/generateVideo.mts'
import { downloadVideo } from './services/downloadVideo.mts'
import { upscaleVideo } from './services/upscaleVideo.mts'
import { generateSeed } from './services/generateSeed.mts'
import { MakeShot } from './types.mts'

const app = express()
const port = 7860

app.use(express.json())


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

  console.log('received query:', query)
  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 audio prompt
  const audioPrompt = `${query.audioPrompt || ''}`

  // optional seed
  const seedStr = Number(`${query.seed || ''}`)
  const maybeSeed = Number(seedStr)
  const seed = isNaN(maybeSeed) || ! isFinite(maybeSeed) ? generateSeed() : maybeSeed
    

  // should we upscale or not?
  const upscale = `${query.upscale || 'false'}` === 'true'

  // duration of the prompt, in seconds
  const defaultDuration = 3
  const durationStr = Number(`${query.duration || defaultDuration}`)
  const maybeDuration = Number(durationStr)
  const duration = Math.min(3, 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 fps = 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 shotFileName = `${Date.now()}.mp4`

  console.log('generating video with the following params:', {
    shotPrompt,
    audioPrompt,
    resolution,
    duration,
    nbSteps,
    fps,
    seed,
    upscale,
    shotFileName
  })
  console.log('generating base video ..')
  const generatedVideoUrl = await generateVideo(shotPrompt, {
    seed,
    nbFrames: 24, // if we try more eg 48 frames, this will crash the upscaler (not enough memory)
    nbSteps
  })


  console.log('downloading video..')
  const videoFileName = await downloadVideo(generatedVideoUrl, shotFileName)

  if (upscale) {
    console.log('upscaling video..')
    await upscaleVideo(videoFileName, shotPrompt)
  }

  // TODO call AudioLDM
  if (audioPrompt) {
    // const baseAudio = await callAudioLDM(audioPrompt)
    console.log('calling audio prompt')
  }

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

  const filePath = path.resolve(tmpDir, videoFileName)

  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}`) })