2024-08-10 12:21:39 +01:00
|
|
|
import ffmpegCore from "@imput/ffmpeg-core?url";
|
|
|
|
import ffmpegCoreWASM from "@imput/ffmpeg-core/wasm?url";
|
|
|
|
|
|
|
|
import { FFmpeg } from "@imput/ffmpeg.wasm";
|
|
|
|
import { fetchFile } from "@imput/ffmpeg-util";
|
|
|
|
|
2024-08-11 08:04:40 +01:00
|
|
|
type renderParams = {
|
|
|
|
url: string,
|
|
|
|
input: {
|
|
|
|
type: string,
|
|
|
|
format: string,
|
|
|
|
},
|
|
|
|
output: {
|
|
|
|
type: string,
|
|
|
|
format: string,
|
|
|
|
},
|
|
|
|
args: string[],
|
|
|
|
}
|
|
|
|
|
2024-08-10 12:21:39 +01:00
|
|
|
export default class FFmpegWrapper {
|
|
|
|
initialized: boolean;
|
|
|
|
ffmpeg: FFmpeg;
|
|
|
|
concurrency: number;
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.ffmpeg = new FFmpeg();
|
|
|
|
this.initialized = false;
|
|
|
|
|
|
|
|
this.concurrency = Math.min(4, navigator.hardwareConcurrency);
|
|
|
|
}
|
|
|
|
|
|
|
|
async init() {
|
|
|
|
if (this.initialized) {
|
|
|
|
this.ffmpeg.terminate();
|
|
|
|
} else {
|
|
|
|
this.initialized = true;
|
|
|
|
this.ffmpeg.on("log", ({ message }) => {
|
|
|
|
console.log(message);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
await this.ffmpeg.load({
|
|
|
|
coreURL: ffmpegCore,
|
|
|
|
wasmURL: ffmpegCoreWASM,
|
|
|
|
workerURL: "/ffmpeg-core.worker.js",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
terminate() {
|
|
|
|
this.initialized = false;
|
|
|
|
return this.ffmpeg.terminate();
|
|
|
|
}
|
|
|
|
|
2024-08-11 08:04:40 +01:00
|
|
|
async renderFile({ url, input, output, args }: renderParams) {
|
|
|
|
const inputFile = `input.${input.format}`;
|
2024-08-10 12:21:39 +01:00
|
|
|
|
|
|
|
await this.ffmpeg.writeFile(
|
2024-08-11 08:04:40 +01:00
|
|
|
inputFile,
|
2024-08-10 12:21:39 +01:00
|
|
|
await fetchFile(url)
|
|
|
|
)
|
|
|
|
|
|
|
|
await this.ffmpeg.exec([
|
|
|
|
'-threads', this.concurrency.toString(),
|
2024-08-11 08:04:40 +01:00
|
|
|
'-i', inputFile,
|
|
|
|
...args,
|
|
|
|
`output.${output.format}`
|
2024-08-10 12:21:39 +01:00
|
|
|
]);
|
|
|
|
|
2024-08-11 08:04:40 +01:00
|
|
|
const data = await this.ffmpeg.readFile(`output.${output.format}`);
|
2024-08-10 12:21:39 +01:00
|
|
|
const finalBlob = URL.createObjectURL(
|
2024-08-11 08:04:40 +01:00
|
|
|
new Blob([data], { type: `${output.type}/${output.format}` })
|
2024-08-10 12:21:39 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
return finalBlob
|
|
|
|
}
|
|
|
|
}
|