web/ffmpeg: accept and return blob, proper types & extensions, clean up

This commit is contained in:
wukko 2024-08-11 18:24:29 +06:00
parent f87f6fa9c9
commit b33bd39484
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
3 changed files with 50 additions and 23 deletions

View file

@ -109,6 +109,9 @@ importers:
'@vitejs/plugin-basic-ssl': '@vitejs/plugin-basic-ssl':
specifier: ^1.1.0 specifier: ^1.1.0
version: 1.1.0(vite@5.3.5(@types/node@20.14.14)) version: 1.1.0(vite@5.3.5(@types/node@20.14.14))
mime:
specifier: ^4.0.4
version: 4.0.4
sveltekit-i18n: sveltekit-i18n:
specifier: ^2.4.2 specifier: ^2.4.2
version: 2.4.2(svelte@4.2.18) version: 2.4.2(svelte@4.2.18)
@ -1591,6 +1594,11 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
hasBin: true hasBin: true
mime@4.0.4:
resolution: {integrity: sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==}
engines: {node: '>=16'}
hasBin: true
mimic-fn@2.1.0: mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -3583,6 +3591,8 @@ snapshots:
mime@1.6.0: {} mime@1.6.0: {}
mime@4.0.4: {}
mimic-fn@2.1.0: {} mimic-fn@2.1.0: {}
min-indent@1.0.1: {} min-indent@1.0.1: {}

View file

@ -51,6 +51,7 @@
"@imput/version-info": "workspace:^", "@imput/version-info": "workspace:^",
"@tabler/icons-svelte": "3.6.0", "@tabler/icons-svelte": "3.6.0",
"@vitejs/plugin-basic-ssl": "^1.1.0", "@vitejs/plugin-basic-ssl": "^1.1.0",
"mime": "^4.0.4",
"sveltekit-i18n": "^2.4.2", "sveltekit-i18n": "^2.4.2",
"ts-deepmerge": "^7.0.0" "ts-deepmerge": "^7.0.0"
} }

View file

@ -1,19 +1,20 @@
import { FFmpeg } from "@imput/ffmpeg.wasm";
import ffmpegCore from "@imput/ffmpeg-core?url"; import ffmpegCore from "@imput/ffmpeg-core?url";
import ffmpegCoreWASM from "@imput/ffmpeg-core/wasm?url"; import ffmpegCoreWASM from "@imput/ffmpeg-core/wasm?url";
import { FFmpeg } from "@imput/ffmpeg.wasm"; import mime from "mime";
import { fetchFile } from "@imput/ffmpeg-util";
type renderParams = { type InputFileKind = "video" | "audio";
url: string,
input: { type FileInfo = {
type: string, type?: string | null,
format: string, kind: InputFileKind,
}, extension: string,
output: { }
type: string,
format: string, type RenderParams = {
}, file: File,
output?: FileInfo,
args: string[], args: string[],
} }
@ -51,26 +52,41 @@ export default class FFmpegWrapper {
return this.ffmpeg.terminate(); return this.ffmpeg.terminate();
} }
async renderFile({ url, input, output, args }: renderParams) { async renderFile({ file, output, args }: RenderParams) {
const inputFile = `input.${input.format}`; const inputKind = file.type.split("/")[0];
const inputExtension = mime.getExtension(file.type);
if (inputKind !== "video" && inputKind !== "audio") return;
if (!inputExtension) return;
const input: FileInfo = {
kind: inputKind,
extension: inputExtension,
}
if (!output) output = input;
output.type = mime.getType(output.extension);
if (!output.type) return;
const buffer = new Uint8Array(await file.arrayBuffer());
await this.ffmpeg.writeFile( await this.ffmpeg.writeFile(
inputFile, 'input',
await fetchFile(url) buffer
) );
await this.ffmpeg.exec([ await this.ffmpeg.exec([
'-threads', this.concurrency.toString(), '-threads', this.concurrency.toString(),
'-i', inputFile, '-i', 'input',
...args, ...args,
`output.${output.format}` `output.${output.extension}`
]); ]);
const data = await this.ffmpeg.readFile(`output.${output.format}`); const renderBlob = new Blob(
const finalBlob = URL.createObjectURL( [await this.ffmpeg.readFile(`output.${output.extension}`)],
new Blob([data], { type: `${output.type}/${output.format}` }) { type: output.type }
); );
return finalBlob return renderBlob;
} }
} }