Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
·
caa2240
1
Parent(s):
c64e57c
added an upscaler for images
Browse files- src/production/generateAudio.mts +1 -1
- src/production/generateVoice.mts +1 -1
- src/production/interpolateVideo.mts +1 -1
- src/production/renderImageSegmentation.mts +1 -2
- src/production/renderImageUpscaling.mts +26 -0
- src/production/renderPipeline.mts +14 -1
- src/production/upscaleVideo.mts +1 -1
- src/utils/segmentImage.mts +1 -1
- src/utils/upscaleImage.mts +42 -0
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,
|
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,
|
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,
|
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
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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,
|
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,
|
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 |
+
}
|