jbilcke-hf HF staff commited on
Commit
f64828c
1 Parent(s): 66f11df

preparing a system to have multiple workers

Browse files
package-lock.json CHANGED
@@ -12,13 +12,15 @@
12
  "@gradio/client": "^0.1.3",
13
  "@huggingface/inference": "^2.5.2",
14
  "@types/express": "^4.17.17",
 
15
  "fluent-ffmpeg": "^2.1.2",
16
  "fs-extra": "^11.1.1",
17
  "node-fetch": "^3.3.1",
18
  "node-media-server": "^2.6.2",
19
  "puppeteer": "^20.7.4",
20
  "temp-dir": "^3.0.0",
21
- "ts-node": "^10.9.1"
 
22
  }
23
  },
24
  "node_modules/@babel/code-frame": {
@@ -315,6 +317,11 @@
315
  "@types/node": "*"
316
  }
317
  },
 
 
 
 
 
318
  "node_modules/@types/yauzl": {
319
  "version": "2.10.0",
320
  "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
@@ -2361,6 +2368,14 @@
2361
  "node": ">= 0.4.0"
2362
  }
2363
  },
 
 
 
 
 
 
 
 
2364
  "node_modules/v8-compile-cache-lib": {
2365
  "version": "3.0.1",
2366
  "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
 
12
  "@gradio/client": "^0.1.3",
13
  "@huggingface/inference": "^2.5.2",
14
  "@types/express": "^4.17.17",
15
+ "@types/uuid": "^9.0.2",
16
  "fluent-ffmpeg": "^2.1.2",
17
  "fs-extra": "^11.1.1",
18
  "node-fetch": "^3.3.1",
19
  "node-media-server": "^2.6.2",
20
  "puppeteer": "^20.7.4",
21
  "temp-dir": "^3.0.0",
22
+ "ts-node": "^10.9.1",
23
+ "uuid": "^9.0.0"
24
  }
25
  },
26
  "node_modules/@babel/code-frame": {
 
317
  "@types/node": "*"
318
  }
319
  },
320
+ "node_modules/@types/uuid": {
321
+ "version": "9.0.2",
322
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz",
323
+ "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ=="
324
+ },
325
  "node_modules/@types/yauzl": {
326
  "version": "2.10.0",
327
  "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
 
2368
  "node": ">= 0.4.0"
2369
  }
2370
  },
2371
+ "node_modules/uuid": {
2372
+ "version": "9.0.0",
2373
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
2374
+ "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
2375
+ "bin": {
2376
+ "uuid": "dist/bin/uuid"
2377
+ }
2378
+ },
2379
  "node_modules/v8-compile-cache-lib": {
2380
  "version": "3.0.1",
2381
  "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
package.json CHANGED
@@ -16,12 +16,14 @@
16
  "@gradio/client": "^0.1.3",
17
  "@huggingface/inference": "^2.5.2",
18
  "@types/express": "^4.17.17",
 
19
  "fluent-ffmpeg": "^2.1.2",
20
  "fs-extra": "^11.1.1",
21
  "node-fetch": "^3.3.1",
22
  "node-media-server": "^2.6.2",
23
  "puppeteer": "^20.7.4",
24
  "temp-dir": "^3.0.0",
25
- "ts-node": "^10.9.1"
 
26
  }
27
  }
 
16
  "@gradio/client": "^0.1.3",
17
  "@huggingface/inference": "^2.5.2",
18
  "@types/express": "^4.17.17",
19
+ "@types/uuid": "^9.0.2",
20
  "fluent-ffmpeg": "^2.1.2",
21
  "fs-extra": "^11.1.1",
22
  "node-fetch": "^3.3.1",
23
  "node-media-server": "^2.6.2",
24
  "puppeteer": "^20.7.4",
25
  "temp-dir": "^3.0.0",
26
+ "ts-node": "^10.9.1",
27
+ "uuid": "^9.0.0"
28
  }
29
  }
src/callZeroscope.mts CHANGED
@@ -22,10 +22,7 @@ export const callZeroscope = async (prompt: string, options?: {
22
  nbSteps, // 10, (numeric value between 10 and 50) in 'Number of inference steps' Slider component
23
  ]) as any
24
 
25
- const { name, orig_name } = rawResponse?.data?.[0]?.[0] as { name: string, orig_name: string }
26
 
27
- return {
28
- url: `${videoSpaceApiUrl}/file=${name}`,
29
- name: orig_name
30
- }
31
  }
 
22
  nbSteps, // 10, (numeric value between 10 and 50) in 'Number of inference steps' Slider component
23
  ]) as any
24
 
25
+ const { name } = rawResponse?.data?.[0]?.[0] as { name: string, orig_name: string }
26
 
27
+ return `${videoSpaceApiUrl}/file=${name}`
 
 
 
28
  }
src/downloadVideo.mts CHANGED
@@ -3,9 +3,7 @@ import fs from 'node:fs'
3
 
4
  import tmpDir from 'temp-dir'
5
 
6
- export const downloadVideo = async (remoteUrl: string, options?: { fileName: string; }): Promise<string> => {
7
-
8
- const fileName = options?.fileName || `${Date.now()}.mp4`
9
 
10
  const filePath = path.resolve(tmpDir, fileName)
11
 
 
3
 
4
  import tmpDir from 'temp-dir'
5
 
6
+ export const downloadVideo = async (remoteUrl: string, fileName: string): Promise<string> => {
 
 
7
 
8
  const filePath = path.resolve(tmpDir, fileName)
9
 
src/generateVideo.mts DELETED
@@ -1,10 +0,0 @@
1
- import { callZeroscope } from './callZeroscope.mts'
2
- import { downloadVideo } from './downloadVideo.mts'
3
-
4
- export const generateVideo = async (prompt: string): Promise<string> => {
5
- const { url } = await callZeroscope(prompt)
6
-
7
- const rawVideo = await downloadVideo(url)
8
-
9
- return rawVideo
10
- }
 
 
 
 
 
 
 
 
 
 
 
src/index.mts CHANGED
@@ -1,3 +1,4 @@
 
1
  import { generateVideo } from './generateVideo.mts'
2
  import { upscaleVideo } from './upscaleVideo.mts'
3
  import { keepVideo } from './keepVideo.mts'
@@ -5,15 +6,20 @@ import { keepVideo } from './keepVideo.mts'
5
  import { demoPrompts } from './prompts.mts'
6
  import { getStats } from './getStats.mts'
7
  import { enhanceVideo } from './enhanceVideo.mts'
 
 
8
 
9
  const main = async () => {
10
  console.log('Generating ideas..')
11
  const ideas = demoPrompts
12
 
13
- console.log('Generating videos..')
 
14
 
15
  for (const { input, captions } of ideas) {
16
- console.log(`\nVideo to generate: ${input}`)
 
 
17
 
18
  const silentVideos: string[] = []
19
 
@@ -21,30 +27,34 @@ const main = async () => {
21
  const videoDurationInSecs = 3
22
 
23
  for (const caption of captions) {
24
- console.log(`- generating video.. prompt: ${caption}`)
25
  try {
26
- const rawVideo = await generateVideo(caption)
 
 
 
 
 
27
 
28
- console.log(`- downloaded ${rawVideo}`)
29
 
30
  console.log('- upscaling video..')
31
 
32
- let upscaledVideo = rawVideo
33
  try {
34
- upscaledVideo = await upscaleVideo(rawVideo, caption)
35
  } catch (err) {
36
  // upscaling is finicky, if it fails we try again
37
  console.log('- trying again to upscale video..')
38
- upscaledVideo = await upscaleVideo(rawVideo, caption)
39
  }
40
 
41
  console.log('- enhancing video..')
42
- const enhancedVideo = await enhanceVideo(upscaledVideo)
43
 
44
  console.log('- saving final video..')
45
- await keepVideo(enhancedVideo, process.env.WEBTV_VIDEO_STORAGE_PATH_NEXT)
46
 
47
- silentVideos.push(enhancedVideo)
48
 
49
  console.log('- done!')
50
  } catch (err) {
 
1
+ import { v4 as uuid } from 'uuid'
2
  import { generateVideo } from './generateVideo.mts'
3
  import { upscaleVideo } from './upscaleVideo.mts'
4
  import { keepVideo } from './keepVideo.mts'
 
6
  import { demoPrompts } from './prompts.mts'
7
  import { getStats } from './getStats.mts'
8
  import { enhanceVideo } from './enhanceVideo.mts'
9
+ import { callZeroscope } from './callZeroscope.mts'
10
+ import { downloadVideo } from './downloadVideo.mts'
11
 
12
  const main = async () => {
13
  console.log('Generating ideas..')
14
  const ideas = demoPrompts
15
 
16
+ console.log('Generating videos sequences..')
17
+ const instanceId = process.env.WEBTV_WORKER_INSTANCE_ID || '0'
18
 
19
  for (const { input, captions } of ideas) {
20
+ console.log(`\nVideo sequence to generate: ${input}`)
21
+
22
+ const sequenceId = uuid()
23
 
24
  const silentVideos: string[] = []
25
 
 
27
  const videoDurationInSecs = 3
28
 
29
  for (const caption of captions) {
30
+ console.log(`- generating shot: ${caption}`)
31
  try {
32
+ const generatedVideoUrl = await callZeroscope(caption)
33
+
34
+ const videoName = `inst_${instanceId}_seq_${sequenceId}_shot_${Date.now()}.mp4`
35
+
36
+ console.log(`- downloading ${videoName} from ${generatedVideoUrl}`)
37
+ await downloadVideo(generatedVideoUrl, videoName)
38
 
39
+ console.log(`- downloaded ${videoName}`)
40
 
41
  console.log('- upscaling video..')
42
 
 
43
  try {
44
+ await upscaleVideo(videoName, caption)
45
  } catch (err) {
46
  // upscaling is finicky, if it fails we try again
47
  console.log('- trying again to upscale video..')
48
+ await upscaleVideo(videoName, caption)
49
  }
50
 
51
  console.log('- enhancing video..')
52
+ await enhanceVideo(videoName)
53
 
54
  console.log('- saving final video..')
55
+ await keepVideo(videoName, process.env.WEBTV_VIDEO_STORAGE_PATH_NEXT)
56
 
57
+ silentVideos.push(videoName)
58
 
59
  console.log('- done!')
60
  } catch (err) {
src/prompts.mts CHANGED
@@ -1,6 +1,8 @@
1
 
2
  export interface Scene {
 
3
  input: string
 
4
  captions: string[]
5
  }
6
 
@@ -70,7 +72,7 @@ The output must be in JSON (here is the type signature:
70
  - Input: a movie about a police car chase in Los Angeles (NOT a 3D render!), in term of total timeline film starts at golden hour, then sunset, then night. There is a light rain, the ground is wet. We can see a police car going at speed after a red lambo (to help the AI generator, you must mention police car and the rend lambo in ALL videos shots!). The police car has its lights on, reflecting on the wet ground. The police chase the lambo across all los angeles, including some iconic places. More police cars should join the chase, and even a helicopter at some point. We should see the light of the helicopter ont he ground, like in movies. Everything should be enveloped in a mist, haze, fog, wet ground. The camera should alternate between point of view to give it an intense, fast paced style (drone shots, helicopter shot etc). Please always mention (for each video) the time era and period, clothes of the characters, colors and textures, background, camera positions (note: add the keywords "cinematic", "imax", "movie", "film grain" to help the AI generator)
71
  */
72
 
73
- export const demoPrompts = [
74
  {
75
  "input": "Slow-mo footage of various objects falling and exploding or being hit by bullets. Very colorful, dramatic lighting, mesmerizing.",
76
  "captions": [
 
1
 
2
  export interface Scene {
3
+ id?: string // TODO: make it mandatory
4
  input: string
5
+ audio?: string // TODO: make it mandatory
6
  captions: string[]
7
  }
8
 
 
72
  - Input: a movie about a police car chase in Los Angeles (NOT a 3D render!), in term of total timeline film starts at golden hour, then sunset, then night. There is a light rain, the ground is wet. We can see a police car going at speed after a red lambo (to help the AI generator, you must mention police car and the rend lambo in ALL videos shots!). The police car has its lights on, reflecting on the wet ground. The police chase the lambo across all los angeles, including some iconic places. More police cars should join the chase, and even a helicopter at some point. We should see the light of the helicopter ont he ground, like in movies. Everything should be enveloped in a mist, haze, fog, wet ground. The camera should alternate between point of view to give it an intense, fast paced style (drone shots, helicopter shot etc). Please always mention (for each video) the time era and period, clothes of the characters, colors and textures, background, camera positions (note: add the keywords "cinematic", "imax", "movie", "film grain" to help the AI generator)
73
  */
74
 
75
+ export const demoPrompts: Scene[] = [
76
  {
77
  "input": "Slow-mo footage of various objects falling and exploding or being hit by bullets. Very colorful, dramatic lighting, mesmerizing.",
78
  "captions": [
src/upscaleVideo.mts CHANGED
@@ -59,7 +59,9 @@ export async function upscaleVideo(fileName: string, prompt: string) {
59
  const tmpFileName = `${fileName}_xl`
60
 
61
  // console.log('downloading file from space..')
62
- await downloadVideo(upscaledFileUrl, { fileName: tmpFileName })
 
 
63
 
64
  const tmpFilePath = path.join(tmpDir, tmpFileName)
65
  const filePath = path.join(tmpDir, fileName)
 
59
  const tmpFileName = `${fileName}_xl`
60
 
61
  // console.log('downloading file from space..')
62
+ console.log(`- downloading ${fileName} from ${upscaledFileUrl}`)
63
+
64
+ await downloadVideo(upscaledFileUrl, tmpFileName)
65
 
66
  const tmpFilePath = path.join(tmpDir, tmpFileName)
67
  const filePath = path.join(tmpDir, fileName)
start.sh CHANGED
@@ -5,7 +5,7 @@ bash ./scripts/init.sh
5
 
6
  # ------ background processes ---------
7
 
8
- # starts the streaming server
9
  node ./media-server.js &
10
 
11
  sleep 1
@@ -23,4 +23,6 @@ bash scripts/stream.sh &
23
 
24
  sleep 1
25
 
26
- npm run start
 
 
 
5
 
6
  # ------ background processes ---------
7
 
8
+ # starts the streaming server first, otherwise ffmpeg won't find it
9
  node ./media-server.js &
10
 
11
  sleep 1
 
23
 
24
  sleep 1
25
 
26
+ # here we have the possibility of using multiple workers
27
+ # buf if we do that, we will have to split the workload (split the prompts)
28
+ WEBTV_WORKER_INSTANCE_ID=1 npm run start