File size: 3,350 Bytes
bda5f6b
 
 
 
9658ad9
bda5f6b
 
9658ad9
 
bda5f6b
 
 
 
9658ad9
 
 
bda5f6b
9658ad9
 
 
 
 
 
 
 
 
 
bda5f6b
 
 
 
 
 
 
9658ad9
bda5f6b
 
9658ad9
 
 
 
 
 
 
bda5f6b
 
9658ad9
bda5f6b
 
9658ad9
bda5f6b
9658ad9
 
 
 
 
bda5f6b
 
9658ad9
 
 
 
 
 
 
 
bda5f6b
 
 
9658ad9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { promises as fs } from 'fs'

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

  const token = `${query.token || ''}`
  if (token !== process.env.VS_SECRET_ACCESS_TOKEN) {
    res.write(JSON.stringify({ error: true, message: 'access denied' }))
    res.end()
    return
  }

  const shotPrompt = `${query.shotPrompt || ''}`
  if (shotPrompt.length) {
    res.write(JSON.stringify({ error: true, message: 'prompt too short' }))
    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 durationStr = Number(`${query.duration || ''}`)
  const maybeDuration = Number(durationStr)
  const duration = Math.min(3, Math.max(1, isNaN(maybeDuration) || !isFinite(maybeDuration) ? 3 : maybeDuration))
  
  const stepsStr = Number(`${query.steps || ''}`)
  const maybeSteps = Number(stepsStr)
  const nbSteps = Math.min(60, Math.max(1, isNaN(maybeSteps) || !isFinite(maybeSteps) ? 35 : maybeSteps))
  
  // const frames per second
  const fpsStr = Number(`${query.fps || ''}`)
  const maybeFps = Number(fpsStr)
  const fps = Math.min(60, Math.max(8, isNaN(maybeFps) || !isFinite(maybeFps) ? 24 : maybeFps))
  
  const resolutionStr = Number(`${query.resolution || ''}`)
  const maybeResolution = Number(resolutionStr)
  const resolution = Math.min(1080, Math.max(256, isNaN(maybeResolution) || !isFinite(maybeResolution) ? 576 : 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 buffer = await fs.readFile(videoFileName)
  res.setHeader('Content-Type', 'media/mp4')
  res.setHeader('Content-Length', buffer.length)
  res.end(buffer)
})

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