Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 1,554 Bytes
3165afb 2cae2a9 3165afb 2cae2a9 3165afb 2cae2a9 3165afb 2cae2a9 3165afb 2cae2a9 3165afb 2cae2a9 3165afb 2cae2a9 3165afb 2cae2a9 3165afb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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 57 58 59 60 61 |
import { existsSync } from "node:fs"
import path from "node:path"
import { v4 as uuidv4 } from "uuid"
import ffmpeg, { FfmpegCommand } from "fluent-ffmpeg"
import { getRandomDirectory } from "@aitube/io"
import { getMediaInfo } from "../analyze/getMediaInfo"
export type ConcatenateVideoOutput = {
filepath: string;
durationInSec: number;
}
export async function concatenateVideos({
output,
videoFilePaths = [],
}: {
output?: string;
// those are videos PATHs, not base64 strings!
videoFilePaths: string[];
}): Promise<ConcatenateVideoOutput> {
if (!Array.isArray(videoFilePaths)) {
throw new Error("Videos must be provided in an array")
}
videoFilePaths = videoFilePaths.filter((videoPath) => existsSync(videoPath))
// Create a temporary working directory
const tempDir = await getRandomDirectory()
const filePath = output ? output : path.join(tempDir, `${uuidv4()}.mp4`)
if (!filePath) {
throw new Error("Failed to generate a valid temporary file path")
}
let cmd: FfmpegCommand = ffmpeg()
videoFilePaths.forEach((video) => {
cmd = cmd.addInput(video)
})
return new Promise<{ filepath: string; durationInSec: number }>(
(resolve, reject) => {
cmd
.on('error', reject)
.on('end', async () => {
try {
const { durationInSec } = await getMediaInfo(filePath);
resolve({ filepath: filePath, durationInSec });
} catch (err) {
reject(err);
}
})
.mergeToFile(filePath, tempDir);
}
)
}
|