Spaces:
Build error
Build error
File size: 5,267 Bytes
f64828c a99b4ac 07ae658 a99b4ac f64828c f7f7c46 07ae658 7e58471 faac575 7e58471 07ae658 f7f7c46 07ae658 f64828c 07ae658 f7f7c46 6997aba f7f7c46 f64828c 444bbdb 07ae658 f7f7c46 66f11df f7f7c46 6fa9239 f7f7c46 7e58471 07ae658 f7f7c46 f64828c 1f50b60 f64828c f7f7c46 f132701 f7f7c46 a99b4ac f7f7c46 0cf8825 f7f7c46 0cf8825 f7f7c46 0cf8825 a99b4ac f7f7c46 a99b4ac f7f7c46 66f11df f7f7c46 a99b4ac 07ae658 66f11df 7e58471 66f11df 7e58471 07ae658 f7f7c46 07ae658 f7f7c46 07ae658 |
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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
import { v4 as uuid } from 'uuid'
import { upscaleVideo } from './upscaleVideo.mts'
import { keepVideo } from './keepVideo.mts'
import { getStats } from './getStats.mts'
import { enhanceVideo } from './enhanceVideo.mts'
import { callZeroscope } from './callZeroscope.mts'
import { downloadVideo } from './downloadVideo.mts'
import { getDatabase } from './getDatabase.mts'
import { callMusicgen } from './callMusicgen.mts'
let hasReachedStartingPoint = false
type RunMode = 'running' | 'paused' | 'dry_run'
const status = `${process.env.WEBTV_STATUS || 'dry_run'}` as RunMode
console.log(`Web TV server status: ${status}`)
// to add more diversity to the stream, let's cut down on the length
const maxShotsPerSequence = 10
const main = async () => {
if (status === 'paused') {
setTimeout(() => {
main()
}, 30000)
return
}
console.log('Reading persistent file structure..')
const stats = await getStats()
console.log(`New format: We have ${stats.nbVideoFiles} video files`)
console.log(`Legacy: We have ${stats.nbLegacyVideoFiles} video files and ${stats.nbLegacyAudioFiles} audio files`)
console.log('Reading prompt database..')
const db = await getDatabase('./database.json')
const nbTotalShots = db.sequences.reduce((a, s) => a + s.shots.length, 0)
console.log(`Prompt database version: ${db.version}`)
console.log(`We got ${db.sequences.length} sequences for ${nbTotalShots} shots in total`)
console.log('Generating videos sequences..')
const instanceId = process.env.WEBTV_WORKER_INSTANCE_ID || '0'
const startingPointExists = db.sequences.some(seq => seq.shots.some(shot => shot.shotId === db.startAtShotId))
if (!startingPointExists) {
console.log(`Starting point ${db.startAtShotId} not found, we will start at the beginning`)
hasReachedStartingPoint = true
} else if (db.startAtShotId) {
console.log(`We are going to start at shot ${db.startAtShotId}`)
} else {
console.log('We are going to start at the beginning')
}
for (const sequence of db.sequences) {
const containsStartingPoint = sequence.shots.some(shot => shot.shotId === db.startAtShotId)
// we skip sequences that were already processed
if (!hasReachedStartingPoint && !containsStartingPoint) {
continue
}
// some sequences can also be skipped by human curation
if (sequence.skip) {
continue
}
console.log(`
-----------------------------------------------------------
Going to generate ${sequence.shots.length} for prompt:
${sequence.videoPrompt}
`)
const movieId = uuid()
const generatedShots: string[] = []
// this is hardcoded everywhere for now, since videos longer than 3 sec require the Nvidia A100
const videoDurationInSecs = 3
let shotIndex = 0
for (const shot of sequence.shots) {
if (shot.shotId === db.startAtShotId) {
hasReachedStartingPoint = true
}
if (!hasReachedStartingPoint) {
shotIndex++
continue
}
console.log(`- generating shot ${shot.shotId}: ${shot.videoPrompt}`)
if (status === 'dry_run') {
// console.log('DRY RUN')
shotIndex++
continue
}
try {
const generatedVideoUrl = await callZeroscope(shot.videoPrompt)
// note that we need to use the shot INDEX (not just the ID)
// to make sure the order is respected
const shotFileName = `inst_${instanceId}_movie_${movieId}_seq_${sequence.sequenceId}_shot_index_${shotIndex++}_shot_${shot.shotId}_${Date.now()}.mp4`
console.log(`- downloading shot ${shotFileName} from ${generatedVideoUrl}`)
await downloadVideo(generatedVideoUrl, shotFileName)
console.log(`- downloaded shot ${shotFileName}`)
console.log('- upscaling shot..')
try {
await upscaleVideo(shotFileName, shot.videoPrompt)
} catch (err) {
// upscaling is finicky, if it fails we try again
console.log('- trying again to upscale shot..')
await upscaleVideo(shotFileName, shot.videoPrompt)
}
console.log('- enhancing shot..')
await enhanceVideo(shotFileName)
console.log('- saving final shot..')
await keepVideo(shotFileName, process.env.WEBTV_VIDEO_STORAGE_PATH_NEXT)
generatedShots.push(shotFileName)
console.log('- done!')
} catch (err) {
console.log(`- error: ${err}`)
}
// for the initial demo, we may want to limit the number of shots per sequence
if (shotIndex > maxShotsPerSequence) {
break
}
}
console.log('Finished generating sequence')
const totalRunTime = videoDurationInSecs * generatedShots.length
if (totalRunTime <= 0) {
continue
}
// TODO: generate music from MusicGen, with the correct length
// (or we could generate a slightly larger track and let ffmpeg cut it)
console.log(`TODO: generate ${totalRunTime} seconds of music`)
await callMusicgen(sequence.audioPrompt) // this does nothing for now
}
console.log('Finished the cycle')
hasReachedStartingPoint = true // set this to true in all cases
setTimeout(() => {
main()
}, 2000)
}
setTimeout(() => {
main()
}, 3000)
|