Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
·
25b858c
1
Parent(s):
b2bd451
add audio
Browse files
src/production/addAudioToVideo.mts
CHANGED
@@ -1,12 +1,11 @@
|
|
1 |
-
import { promises as fs } from "node:fs"
|
2 |
import path from "node:path"
|
3 |
|
4 |
import tmpDir from "temp-dir"
|
5 |
import { v4 as uuidv4 } from "uuid"
|
6 |
-
|
7 |
import ffmpeg from "fluent-ffmpeg"
|
|
|
8 |
import { pendingFilesDirFilePath } from "../config.mts"
|
9 |
-
import {
|
10 |
|
11 |
export const addAudioToVideo = async (
|
12 |
videoFileName: string,
|
@@ -20,11 +19,14 @@ export const addAudioToVideo = async (
|
|
20 |
*/
|
21 |
volume: number = 1.0
|
22 |
) => {
|
23 |
-
const
|
24 |
-
const audioFilePath = path.resolve(
|
|
|
|
|
|
|
25 |
|
26 |
await new Promise((resolve, reject) => {
|
27 |
-
ffmpeg(
|
28 |
.input(audioFilePath)
|
29 |
.audioFilters({ filter: 'volume', options: volume }) // add audio filter for volume
|
30 |
.outputOptions("-c:v copy") // use video copy codec
|
@@ -37,7 +39,5 @@ export const addAudioToVideo = async (
|
|
37 |
.on("error", reject)
|
38 |
.run()
|
39 |
})
|
40 |
-
|
41 |
-
// Now we want to replace the original video file with the new file that has been created
|
42 |
-
await moveFile(tempOutputFilePath, videoFileName)
|
43 |
};
|
|
|
|
|
1 |
import path from "node:path"
|
2 |
|
3 |
import tmpDir from "temp-dir"
|
4 |
import { v4 as uuidv4 } from "uuid"
|
|
|
5 |
import ffmpeg from "fluent-ffmpeg"
|
6 |
+
|
7 |
import { pendingFilesDirFilePath } from "../config.mts"
|
8 |
+
import { moveFileFromTmpToPending } from "../utils/moveFileFromTmpToPending.mts"
|
9 |
|
10 |
export const addAudioToVideo = async (
|
11 |
videoFileName: string,
|
|
|
19 |
*/
|
20 |
volume: number = 1.0
|
21 |
) => {
|
22 |
+
const inputFilePath = path.join(pendingFilesDirFilePath, videoFileName)
|
23 |
+
const audioFilePath = path.resolve(pendingFilesDirFilePath, audioFileName)
|
24 |
+
|
25 |
+
const tmpFileName = `${uuidv4()}.mp4`
|
26 |
+
const tempOutputFilePath = path.join(tmpDir, tmpFileName)
|
27 |
|
28 |
await new Promise((resolve, reject) => {
|
29 |
+
ffmpeg(inputFilePath)
|
30 |
.input(audioFilePath)
|
31 |
.audioFilters({ filter: 'volume', options: volume }) // add audio filter for volume
|
32 |
.outputOptions("-c:v copy") // use video copy codec
|
|
|
39 |
.on("error", reject)
|
40 |
.run()
|
41 |
})
|
42 |
+
await moveFileFromTmpToPending(tmpFileName, videoFileName)
|
|
|
|
|
43 |
};
|
src/production/generateAudio.mts
CHANGED
@@ -16,10 +16,8 @@ export async function generateAudio(prompt: string, audioFileName: string) {
|
|
16 |
const instance = instances.shift()
|
17 |
instances.push(instance)
|
18 |
|
19 |
-
console.log("instance:", instance)
|
20 |
-
|
21 |
const browser = await puppeteer.launch({
|
22 |
-
headless:
|
23 |
protocolTimeout: 800000,
|
24 |
})
|
25 |
|
|
|
16 |
const instance = instances.shift()
|
17 |
instances.push(instance)
|
18 |
|
|
|
|
|
19 |
const browser = await puppeteer.launch({
|
20 |
+
headless: true,
|
21 |
protocolTimeout: 800000,
|
22 |
})
|
23 |
|
src/scheduler/processTask.mts
CHANGED
@@ -197,34 +197,6 @@ export const processTask = async (task: VideoTask) => {
|
|
197 |
}
|
198 |
}
|
199 |
|
200 |
-
|
201 |
-
let foregroundAudioFileName = `${task.ownerId}_${task.id}_${shot.id}_${uuidv4()}.m4a`
|
202 |
-
|
203 |
-
if (!shot.hasGeneratedForegroundAudio && shot.foregroundAudioPrompt) {
|
204 |
-
console.log("generating foreground audio..")
|
205 |
-
|
206 |
-
try {
|
207 |
-
await generateAudio(shot.foregroundAudioPrompt, foregroundAudioFileName)
|
208 |
-
|
209 |
-
shot.hasGeneratedForegroundAudio = true
|
210 |
-
shot.nbCompletedSteps++
|
211 |
-
nbCompletedSteps++
|
212 |
-
shot.progressPercent = Math.round((shot.nbCompletedSteps / shot.nbTotalSteps) * 100)
|
213 |
-
task.progressPercent = Math.round((nbCompletedSteps / nbTotalSteps) * 100)
|
214 |
-
|
215 |
-
await addAudioToVideo(shot.fileName, foregroundAudioFileName)
|
216 |
-
|
217 |
-
await updatePendingTask(task)
|
218 |
-
|
219 |
-
} catch (err) {
|
220 |
-
console.error(`failed to generate foreground audio for ${shot.id} (${err})`)
|
221 |
-
// something is wrong, let's put the whole thing back into the queue
|
222 |
-
task.error = `failed to generate foreground audio ${shot.id} (will try again later)`
|
223 |
-
await updatePendingTask(task)
|
224 |
-
break
|
225 |
-
}
|
226 |
-
}
|
227 |
-
|
228 |
|
229 |
if (!shot.hasPostProcessedVideo) {
|
230 |
console.log("post-processing video..")
|
@@ -257,6 +229,45 @@ export const processTask = async (task: VideoTask) => {
|
|
257 |
}
|
258 |
}
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
shot.completed = true
|
261 |
shot.completedAt = new Date().toISOString()
|
262 |
shot.progressPercent = 100
|
|
|
197 |
}
|
198 |
}
|
199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
|
201 |
if (!shot.hasPostProcessedVideo) {
|
202 |
console.log("post-processing video..")
|
|
|
229 |
}
|
230 |
}
|
231 |
|
232 |
+
|
233 |
+
let foregroundAudioFileName = `${task.ownerId}_${task.id}_${shot.id}_${uuidv4()}.m4a`
|
234 |
+
|
235 |
+
if (!shot.hasGeneratedForegroundAudio) {
|
236 |
+
if (shot.foregroundAudioPrompt) {
|
237 |
+
console.log("generating foreground audio..")
|
238 |
+
|
239 |
+
try {
|
240 |
+
await generateAudio(shot.foregroundAudioPrompt, foregroundAudioFileName)
|
241 |
+
|
242 |
+
shot.hasGeneratedForegroundAudio = true
|
243 |
+
shot.nbCompletedSteps++
|
244 |
+
nbCompletedSteps++
|
245 |
+
shot.progressPercent = Math.round((shot.nbCompletedSteps / shot.nbTotalSteps) * 100)
|
246 |
+
task.progressPercent = Math.round((nbCompletedSteps / nbTotalSteps) * 100)
|
247 |
+
|
248 |
+
await addAudioToVideo(shot.fileName, foregroundAudioFileName)
|
249 |
+
|
250 |
+
await copyVideoFromPendingToCompleted(shot.fileName, task.fileName)
|
251 |
+
|
252 |
+
await updatePendingTask(task)
|
253 |
+
|
254 |
+
} catch (err) {
|
255 |
+
console.error(`failed to generate foreground audio for ${shot.id} (${err})`)
|
256 |
+
// something is wrong, let's put the whole thing back into the queue
|
257 |
+
task.error = `failed to generate foreground audio ${shot.id} (will try again later)`
|
258 |
+
await updatePendingTask(task)
|
259 |
+
break
|
260 |
+
}
|
261 |
+
} else {
|
262 |
+
shot.hasGeneratedForegroundAudio = true
|
263 |
+
shot.nbCompletedSteps++
|
264 |
+
nbCompletedSteps++
|
265 |
+
shot.progressPercent = Math.round((shot.nbCompletedSteps / shot.nbTotalSteps) * 100)
|
266 |
+
task.progressPercent = Math.round((nbCompletedSteps / nbTotalSteps) * 100)
|
267 |
+
await updatePendingTask(task)
|
268 |
+
}
|
269 |
+
}
|
270 |
+
|
271 |
shot.completed = true
|
272 |
shot.completedAt = new Date().toISOString()
|
273 |
shot.progressPercent = 100
|