Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
·
816a8b6
1
Parent(s):
8aee623
fix HUUUGE memory leak
Browse files- src/production/generateAudio.mts +27 -21
- src/production/generateVoice.mts +27 -21
- src/production/interpolateVideo.mts +26 -20
- src/production/upscaleVideo.mts +40 -34
- src/utils/segmentImage.mts +40 -34
src/production/generateAudio.mts
CHANGED
|
@@ -21,36 +21,42 @@ export async function generateAudio(prompt: string, audioFileName: string) {
|
|
| 21 |
protocolTimeout: 120000,
|
| 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 |
}
|
|
|
|
| 21 |
protocolTimeout: 120000,
|
| 22 |
})
|
| 23 |
|
| 24 |
+
try {
|
| 25 |
+
const page = await browser.newPage()
|
| 26 |
|
| 27 |
+
await page.goto(instance, {
|
| 28 |
+
waitUntil: "networkidle2",
|
| 29 |
+
})
|
| 30 |
|
| 31 |
+
await new Promise(r => setTimeout(r, 3000))
|
| 32 |
|
| 33 |
+
const firstTextboxInput = await page.$('input[data-testid="textbox"]')
|
| 34 |
|
| 35 |
+
await firstTextboxInput.type(prompt)
|
| 36 |
|
| 37 |
+
// console.log("looking for the button to submit")
|
| 38 |
+
const submitButton = await page.$("button.lg")
|
| 39 |
|
| 40 |
+
// console.log("clicking on the button")
|
| 41 |
+
await submitButton.click()
|
| 42 |
|
| 43 |
+
await page.waitForSelector("a[download]", {
|
| 44 |
+
timeout: 120000, // no need to wait for too long, generation is quick
|
| 45 |
+
})
|
| 46 |
|
| 47 |
+
const audioRemoteUrl = await page.$$eval("a[download]", el => el.map(x => x.getAttribute("href"))[0])
|
| 48 |
|
| 49 |
|
| 50 |
+
// it is always a good idea to download to a tmp dir before saving to the pending dir
|
| 51 |
+
// because there is always a risk that the download will fail
|
| 52 |
+
|
| 53 |
+
const tmpFileName = `${uuidv4()}.mp4`
|
| 54 |
|
| 55 |
+
await downloadFileToTmp(audioRemoteUrl, tmpFileName)
|
| 56 |
+
await moveFileFromTmpToPending(tmpFileName, audioFileName)
|
| 57 |
+
} catch (err) {
|
| 58 |
+
throw err
|
| 59 |
+
} finally {
|
| 60 |
+
await browser.close()
|
| 61 |
+
}
|
| 62 |
}
|
src/production/generateVoice.mts
CHANGED
|
@@ -18,39 +18,45 @@ export async function generateVoice(prompt: string, voiceFileName: string) {
|
|
| 18 |
protocolTimeout: 800000,
|
| 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 |
}
|
|
|
|
| 18 |
protocolTimeout: 800000,
|
| 19 |
})
|
| 20 |
|
| 21 |
+
try {
|
| 22 |
+
const page = await browser.newPage()
|
| 23 |
|
| 24 |
+
await page.goto(instance, {
|
| 25 |
+
waitUntil: "networkidle2",
|
| 26 |
+
})
|
| 27 |
|
| 28 |
+
await new Promise(r => setTimeout(r, 3000))
|
| 29 |
|
| 30 |
+
const firstTextarea = await page.$('textarea[data-testid="textbox"]')
|
| 31 |
|
| 32 |
+
await firstTextarea.type(prompt)
|
| 33 |
|
| 34 |
+
// console.log("looking for the button to submit")
|
| 35 |
+
const submitButton = await page.$("button.lg")
|
| 36 |
|
| 37 |
+
// console.log("clicking on the button")
|
| 38 |
+
await submitButton.click()
|
| 39 |
|
| 40 |
+
await page.waitForSelector("audio", {
|
| 41 |
+
timeout: 800000, // need to be large enough in case someone else attemps to use our space
|
| 42 |
+
})
|
| 43 |
|
| 44 |
+
const voiceRemoteUrl = await page.$$eval("audio", el => el.map(x => x.getAttribute("src"))[0])
|
| 45 |
|
| 46 |
|
| 47 |
+
console.log({
|
| 48 |
+
voiceRemoteUrl,
|
| 49 |
+
})
|
| 50 |
|
| 51 |
|
| 52 |
+
console.log(`- downloading ${voiceFileName} from ${voiceRemoteUrl}`)
|
| 53 |
|
| 54 |
+
await downloadFileToTmp(voiceRemoteUrl, voiceFileName)
|
| 55 |
|
| 56 |
+
return voiceFileName
|
| 57 |
+
} catch (err) {
|
| 58 |
+
throw err
|
| 59 |
+
} finally {
|
| 60 |
+
await browser.close()
|
| 61 |
+
}
|
| 62 |
}
|
src/production/interpolateVideo.mts
CHANGED
|
@@ -28,33 +28,39 @@ export async function interpolateVideo(fileName: string, steps: number, fps: num
|
|
| 28 |
protocolTimeout: 400000,
|
| 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 |
}
|
|
|
|
| 28 |
protocolTimeout: 400000,
|
| 29 |
})
|
| 30 |
|
| 31 |
+
try {
|
| 32 |
+
const page = await browser.newPage()
|
| 33 |
+
await page.goto(instance, { waitUntil: 'networkidle2' })
|
| 34 |
+
|
| 35 |
+
await new Promise(r => setTimeout(r, 3000))
|
| 36 |
|
| 37 |
+
const fileField = await page.$('input[type=file]')
|
| 38 |
|
| 39 |
+
// console.log(`uploading file..`)
|
| 40 |
+
await fileField.uploadFile(inputFilePath)
|
| 41 |
|
| 42 |
+
// console.log('looking for the button to submit')
|
| 43 |
+
const submitButton = await page.$('button.lg')
|
| 44 |
|
| 45 |
+
// console.log('clicking on the button')
|
| 46 |
+
await submitButton.click()
|
| 47 |
|
| 48 |
+
await page.waitForSelector('a[download="interpolated_result.mp4"]', {
|
| 49 |
+
timeout: 400000, // need to be large enough in case someone else attemps to use our space
|
| 50 |
+
})
|
| 51 |
|
| 52 |
+
const interpolatedFileUrl = await page.$$eval('a[download="interpolated_result.mp4"]', el => el.map(x => x.getAttribute("href"))[0])
|
| 53 |
|
| 54 |
+
// it is always a good idea to download to a tmp dir before saving to the pending dir
|
| 55 |
+
// because there is always a risk that the download will fail
|
| 56 |
|
| 57 |
+
const tmpFileName = `${uuidv4()}.mp4`
|
| 58 |
|
| 59 |
+
await downloadFileToTmp(interpolatedFileUrl, tmpFileName)
|
| 60 |
+
await moveFileFromTmpToPending(tmpFileName, fileName)
|
| 61 |
+
} catch (err) {
|
| 62 |
+
throw err
|
| 63 |
+
} finally {
|
| 64 |
+
await browser.close()
|
| 65 |
+
}
|
| 66 |
}
|
src/production/upscaleVideo.mts
CHANGED
|
@@ -22,51 +22,57 @@ export async function upscaleVideo(fileName: string, prompt: string) {
|
|
| 22 |
protocolTimeout: 800000,
|
| 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 |
}
|
|
|
|
| 22 |
protocolTimeout: 800000,
|
| 23 |
})
|
| 24 |
|
| 25 |
+
try {
|
| 26 |
+
const page = await browser.newPage()
|
| 27 |
|
| 28 |
+
await page.goto(instance, {
|
| 29 |
+
waitUntil: 'networkidle2',
|
| 30 |
+
})
|
| 31 |
|
| 32 |
+
const promptField = await page.$('textarea')
|
| 33 |
+
await promptField.type(prompt)
|
| 34 |
|
| 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 |
|
| 42 |
+
// console.log(`uploading file..`)
|
| 43 |
+
await fileField.uploadFile(inputFilePath)
|
| 44 |
|
| 45 |
+
// console.log('looking for the button to submit')
|
| 46 |
+
const submitButton = await page.$('button.lg')
|
| 47 |
|
| 48 |
+
// console.log('clicking on the button')
|
| 49 |
+
await submitButton.click()
|
| 50 |
|
| 51 |
+
/*
|
| 52 |
+
const client = await page.target().createCDPSession()
|
| 53 |
|
| 54 |
+
await client.send('Page.setDownloadBehavior', {
|
| 55 |
+
behavior: 'allow',
|
| 56 |
+
downloadPath: tmpDir,
|
| 57 |
+
})
|
| 58 |
+
*/
|
| 59 |
|
| 60 |
+
await page.waitForSelector('a[download="xl_result.mp4"]', {
|
| 61 |
+
timeout: 800000, // need to be large enough in case someone else attemps to use our space
|
| 62 |
+
})
|
| 63 |
|
| 64 |
+
const upscaledFileUrl = await page.$$eval('a[download="xl_result.mp4"]', el => el.map(x => x.getAttribute("href"))[0])
|
| 65 |
|
| 66 |
+
// it is always a good idea to download to a tmp dir before saving to the pending dir
|
| 67 |
+
// because there is always a risk that the download will fail
|
| 68 |
+
|
| 69 |
+
const tmpFileName = `${uuidv4()}.mp4`
|
| 70 |
|
| 71 |
+
await downloadFileToTmp(upscaledFileUrl, tmpFileName)
|
| 72 |
+
await moveFileFromTmpToPending(tmpFileName, fileName)
|
| 73 |
+
} catch (err) {
|
| 74 |
+
throw err
|
| 75 |
+
} finally {
|
| 76 |
+
await browser.close()
|
| 77 |
+
}
|
| 78 |
}
|
src/utils/segmentImage.mts
CHANGED
|
@@ -36,54 +36,60 @@ export async function segmentImage(
|
|
| 36 |
protocolTimeout: 40000,
|
| 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 |
|
|
|
|
| 36 |
protocolTimeout: 40000,
|
| 37 |
})
|
| 38 |
|
| 39 |
+
try {
|
| 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 |
|
| 47 |
+
// console.log(`uploading file..`)
|
| 48 |
+
await fileField.uploadFile(inputImageFilePath)
|
| 49 |
|
| 50 |
+
const firstTextarea = await page.$('textarea[data-testid="textbox"]')
|
| 51 |
|
| 52 |
+
const conceptsToDetect = actionnables.join(" . ")
|
| 53 |
+
await firstTextarea.type(conceptsToDetect)
|
| 54 |
|
| 55 |
+
// console.log('looking for the button to submit')
|
| 56 |
+
const submitButton = await page.$('button.lg')
|
| 57 |
|
| 58 |
+
await sleep(300)
|
| 59 |
|
| 60 |
+
// console.log('clicking on the button')
|
| 61 |
+
await submitButton.click()
|
| 62 |
|
| 63 |
+
await page.waitForSelector('img[data-testid="detailed-image"]', {
|
| 64 |
+
timeout: 40000, // we keep it tight, to fail early
|
| 65 |
+
})
|
| 66 |
|
| 67 |
+
const maskUrl = await page.$$eval('img[data-testid="detailed-image"]', el => el.map(x => x.getAttribute("src"))[0])
|
| 68 |
|
| 69 |
+
let segments: ImageSegment[] = []
|
| 70 |
+
|
| 71 |
+
try {
|
| 72 |
+
segments = JSON.parse(await page.$$eval('textarea', el => el.map(x => x.value)[1]))
|
| 73 |
+
} catch (err) {
|
| 74 |
+
console.log(`failed to parse JSON: ${err}`)
|
| 75 |
+
segments = []
|
| 76 |
+
}
|
| 77 |
|
| 78 |
+
// const tmpMaskFileName = `${uuidv4()}.png`
|
| 79 |
+
// await downloadFileToTmp(maskUrl, tmpMaskFileName)
|
| 80 |
|
| 81 |
+
const rawPngInBase64 = await downloadImageAsBase64(maskUrl)
|
| 82 |
|
| 83 |
+
const pngInBase64 = await resizeBase64Image(rawPngInBase64, width, height)
|
| 84 |
|
| 85 |
+
return {
|
| 86 |
+
pngInBase64,
|
| 87 |
+
segments,
|
| 88 |
+
}
|
| 89 |
+
} catch (err) {
|
| 90 |
+
throw err
|
| 91 |
+
} finally {
|
| 92 |
+
await browser.close()
|
| 93 |
}
|
| 94 |
}
|
| 95 |
|