jbilcke-hf HF staff commited on
Commit
caa2240
·
1 Parent(s): c64e57c

added an upscaler for images

Browse files
src/production/generateAudio.mts CHANGED
@@ -37,7 +37,7 @@ export async function generateAudio(prompt: string, audioFileName: string) {
37
  waitUntil: "networkidle2",
38
  })
39
 
40
- await new Promise(r => setTimeout(r, 3000))
41
 
42
  const firstTextboxInput = await page.$('input[data-testid="textbox"]')
43
 
 
37
  waitUntil: "networkidle2",
38
  })
39
 
40
+ // await new Promise(r => setTimeout(r, 1000))
41
 
42
  const firstTextboxInput = await page.$('input[data-testid="textbox"]')
43
 
src/production/generateVoice.mts CHANGED
@@ -36,7 +36,7 @@ export async function generateVoice(prompt: string, voiceFileName: string) {
36
  waitUntil: "networkidle2",
37
  })
38
 
39
- await new Promise(r => setTimeout(r, 3000))
40
 
41
  const firstTextarea = await page.$('textarea[data-testid="textbox"]')
42
 
 
36
  waitUntil: "networkidle2",
37
  })
38
 
39
+ // await new Promise(r => setTimeout(r, 1000))
40
 
41
  const firstTextarea = await page.$('textarea[data-testid="textbox"]')
42
 
src/production/interpolateVideo.mts CHANGED
@@ -42,7 +42,7 @@ export async function interpolateVideo(fileName: string, steps: number, fps: num
42
  const page = await browser.newPage()
43
  await page.goto(instance, { waitUntil: 'networkidle2' })
44
 
45
- await new Promise(r => setTimeout(r, 3000))
46
 
47
  const fileField = await page.$('input[type=file]')
48
 
 
42
  const page = await browser.newPage()
43
  await page.goto(instance, { waitUntil: 'networkidle2' })
44
 
45
+ // await new Promise(r => setTimeout(r, 1000))
46
 
47
  const fileField = await page.$('input[type=file]')
48
 
src/production/renderImageSegmentation.mts CHANGED
@@ -17,7 +17,6 @@ export async function renderImageSegmentation(
17
 
18
  if (actionnables.length > 0) {
19
  console.log("we have some actionnables:", actionnables)
20
- console.log("going to grab the first frame")
21
 
22
  const tmpImageFilePath = path.join(tmpDir, `${uuidv4()}.png`)
23
 
@@ -26,7 +25,7 @@ export async function renderImageSegmentation(
26
  console.log("wrote the image to ", tmpImageFilePath)
27
 
28
  if (!tmpImageFilePath) {
29
- console.error("failed to get the image")
30
  response.error = "failed to segment the image"
31
  response.status = "error"
32
  } else {
 
17
 
18
  if (actionnables.length > 0) {
19
  console.log("we have some actionnables:", actionnables)
 
20
 
21
  const tmpImageFilePath = path.join(tmpDir, `${uuidv4()}.png`)
22
 
 
25
  console.log("wrote the image to ", tmpImageFilePath)
26
 
27
  if (!tmpImageFilePath) {
28
+ console.error("failed to segment the image")
29
  response.error = "failed to segment the image"
30
  response.status = "error"
31
  } else {
src/production/renderImageUpscaling.mts ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { RenderedScene, RenderRequest } from "../types.mts"
2
+ import { upscaleImage } from "../utils/upscaleImage.mts"
3
+
4
+ export async function renderImageUpscaling(
5
+ request: RenderRequest,
6
+ response: RenderedScene,
7
+ ): Promise<RenderedScene> {
8
+
9
+ try {
10
+ // note: this converts a base64 PNG to a base64 JPG (which is good, actually!)
11
+ response.assetUrl = await upscaleImage(response.assetUrl)
12
+ console.log(`upscaling worked on the first try!`)
13
+ } catch (err) {
14
+ console.error(`upscaling failed the first time.. let's try again..`)
15
+ try {
16
+ response.assetUrl = await upscaleImage(response.assetUrl)
17
+ console.log(`upscaling worked on the second try!`)
18
+ } catch (err) {
19
+ console.error(`upscaling failed on the second attempt.. let's keep the low-res image then :|`)
20
+ // no need to log a catastrophic failure here, since we still have the original (low-res image)
21
+ // to work with
22
+ }
23
+ }
24
+
25
+ return response
26
+ }
src/production/renderPipeline.mts CHANGED
@@ -5,6 +5,8 @@ import { renderImage } from "./renderImage.mts"
5
  import { renderVideo } from "./renderVideo.mts"
6
  import { renderImageSegmentation } from "./renderImageSegmentation.mts"
7
  import { renderVideoSegmentation } from "./renderVideoSegmentation.mts"
 
 
8
 
9
  export async function renderPipeline(request: RenderRequest, response: RenderedScene) {
10
  const isVideo = request?.nbFrames > 1
@@ -18,7 +20,18 @@ export async function renderPipeline(request: RenderRequest, response: RenderedS
18
  console.log(`rendering an image..`)
19
  }
20
  await renderContent(request, response)
21
- await renderSegmentation(request, response)
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  /*
24
  this is the optimized pipeline
 
5
  import { renderVideo } from "./renderVideo.mts"
6
  import { renderImageSegmentation } from "./renderImageSegmentation.mts"
7
  import { renderVideoSegmentation } from "./renderVideoSegmentation.mts"
8
+ import { upscaleImage } from "../utils/upscaleImage.mts"
9
+ import { renderImageUpscaling } from "./renderImageUpscaling.mts"
10
 
11
  export async function renderPipeline(request: RenderRequest, response: RenderedScene) {
12
  const isVideo = request?.nbFrames > 1
 
20
  console.log(`rendering an image..`)
21
  }
22
  await renderContent(request, response)
23
+
24
+ // we upscale images with esrgan
25
+ // and for videos, well.. let's just skip this part,
26
+ // but later we could use Zeroscope V2 XL maybe?
27
+ const optionalUpscalingStep = isVideo
28
+ ? Promise.resolve()
29
+ : renderImageUpscaling(request, response)
30
+
31
+ await Promise.all([
32
+ renderSegmentation(request, response),
33
+ optionalUpscalingStep
34
+ ])
35
 
36
  /*
37
  this is the optimized pipeline
src/production/upscaleVideo.mts CHANGED
@@ -35,7 +35,7 @@ export async function upscaleVideo(fileName: string, prompt: string) {
35
  const inputFilePath = path.join(pendingFilesDirFilePath, fileName)
36
  // console.log(`local file to upscale: ${inputFilePath}`)
37
 
38
- await new Promise(r => setTimeout(r, 3000))
39
 
40
  const fileField = await page.$('input[type=file]')
41
 
 
35
  const inputFilePath = path.join(pendingFilesDirFilePath, fileName)
36
  // console.log(`local file to upscale: ${inputFilePath}`)
37
 
38
+ // await new Promise(r => setTimeout(r, 1000))
39
 
40
  const fileField = await page.$('input[type=file]')
41
 
src/utils/segmentImage.mts CHANGED
@@ -40,7 +40,7 @@ export async function segmentImage(
40
  const page = await browser.newPage()
41
  await page.goto(instance, { waitUntil: 'networkidle2' })
42
 
43
- await new Promise(r => setTimeout(r, 3000))
44
 
45
  const fileField = await page.$('input[type="file"]')
46
 
 
40
  const page = await browser.newPage()
41
  await page.goto(instance, { waitUntil: 'networkidle2' })
42
 
43
+ // await new Promise(r => setTimeout(r, 1000))
44
 
45
  const fileField = await page.$('input[type="file"]')
46
 
src/utils/upscaleImage.mts ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import { client } from "@gradio/client"
3
+
4
+ import { getValidNumber } from "./getValidNumber.mts"
5
+
6
+ // we don't use replicas yet, because it ain't easy to get their hostname
7
+ const instances: string[] = [
8
+ `${process.env.VC_UPSCALING_SPACE_API_URL_1 || ""}`,
9
+ // `${process.env.VC_UPSCALING_SPACE_API_URL_2 || ""}`,
10
+ ].filter(instance => instance?.length > 0)
11
+
12
+ // this doesn't work because of this error.. I think the version of Gradio is too old/young?
13
+ // ReferenceError: addEventListener is not defined
14
+ // at file:///Users/jbilcke/Projects/VideoChain-API/node_modules/@gradio/client/dist/index.js:551:15
15
+ // at processTicksAndRejections (node:internal/process/task_queues:95:5)
16
+ export async function upscaleImage(src: string, factor?: number) {
17
+
18
+ // bu default we do a 4X scale
19
+ const scaleFactor = getValidNumber(factor, 2, 10, 4)
20
+
21
+ const instance = instances.shift()
22
+ instances.push(instance)
23
+
24
+ const api = await client(instance, {
25
+ hf_token: `${process.env.VC_HF_API_TOKEN}` as any
26
+ })
27
+
28
+ const result = await api.predict("/upscale", [
29
+ src, // blob in 'Source Image' Image component
30
+ "realesr-general-x4v3", // string (Option from: ['RealESRGAN_x4plus', 'RealESRNet_x4plus', 'RealESRGAN_x4plus_anime_6B', 'RealESRGAN_x2plus', 'realesr-general-x4v3']) in 'Real-ESRGAN inference model to be used' Dropdown component
31
+ 0.5, // number (numeric value between 0 and 1) in 'Denoise Strength (Used only with the realesr-general-x4v3 model)' Slider component
32
+ false, // boolean in 'Face Enhancement using GFPGAN (Doesn't work for anime images)' Checkbox component
33
+ scaleFactor, // number (numeric value between 1 and 10) in 'Image Upscaling Factor' Slider component
34
+ ]);
35
+
36
+
37
+ const rawResponse = result as any
38
+
39
+ // console.log("rawResponse:", rawResponse)
40
+
41
+ return rawResponse?.data?.[0] as string
42
+ }