web/libav: make it work & clean up

This commit is contained in:
dumbmoron 2024-08-12 17:06:45 +00:00
parent 75ef4604d8
commit 2198a696ce
No known key found for this signature in database
2 changed files with 21 additions and 14 deletions

View file

@ -10,7 +10,7 @@ type FileInfo = {
} }
type RenderParams = { type RenderParams = {
file: File, blob: Blob,
output?: FileInfo, output?: FileInfo,
args: string[], args: string[],
} }
@ -26,16 +26,17 @@ export default class LibAVWrapper {
async init() { async init() {
if (!this.libav) { if (!this.libav) {
this.libav = await LibAV.LibAV({ this.libav = await LibAV.LibAV({
yesthreads: true yesthreads: true,
base: '/_libav/'
}) })
} }
} }
async renderFile({ file, output, args }: RenderParams) { async render({ blob, output, args }: RenderParams) {
if (!this.libav) throw new Error("LibAV wasn't initialized"); if (!this.libav) throw new Error("LibAV wasn't initialized");
const inputKind = file.type.split("/")[0]; const inputKind = blob.type.split("/")[0];
const inputExtension = mime.getExtension(file.type); const inputExtension = mime.getExtension(blob.type);
if (inputKind !== "video" && inputKind !== "audio") return; if (inputKind !== "video" && inputKind !== "audio") return;
if (!inputExtension) return; if (!inputExtension) return;
@ -52,14 +53,15 @@ export default class LibAVWrapper {
const outputName = `output.${output.extension}`; const outputName = `output.${output.extension}`;
const buffer = new Blob([await file.arrayBuffer()]); await this.libav.mkreadaheadfile("input", blob);
await this.libav.mkreadaheadfile("input", buffer);
// https://github.com/Yahweasel/libav.js/blob/7d359f69/docs/IO.md#block-writer-devices // https://github.com/Yahweasel/libav.js/blob/7d359f69/docs/IO.md#block-writer-devices
await this.libav.mkwriterdev(outputName); await this.libav.mkwriterdev(outputName);
let writtenData = new Uint8Array(0); let writtenData = new Uint8Array(0);
this.libav.onwrite = (name, pos, data) => { this.libav.onwrite = (name, pos, data) => {
if (name !== outputName) return;
const newLen = Math.max(writtenData.length, pos + data.length); const newLen = Math.max(writtenData.length, pos + data.length);
if (newLen > writtenData.length) { if (newLen > writtenData.length) {
const newData = new Uint8Array(newLen); const newData = new Uint8Array(newLen);
@ -70,20 +72,25 @@ export default class LibAVWrapper {
}; };
await this.libav.ffmpeg([ await this.libav.ffmpeg([
'-nostdin', '-y',
'-threads', this.concurrency.toString(), '-threads', this.concurrency.toString(),
'-i', 'input', '-i', 'input',
...args, ...args,
outputName outputName
]); ]);
await this.libav.unlinkmkreadaheadfile("input"); await this.libav.unlink(outputName);
// FIXME: this is not correct, and needs to be replaced
// with unlinkmkreadaheadfile().
await this.libav.unlink("input");
const renderBlob = new Blob( const renderBlob = new Blob(
[writtenData], [ writtenData ],
{ type: output.type } { type: output.type }
); );
if (renderBlob.size === 0) return; if (renderBlob.size === 0) return;
return renderBlob; return renderBlob;
} }
} }

View file

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import FFmpegWrapper from "$lib/ffmpeg"; import LibAVWrapper from "$lib/libav";
import { openURL } from "$lib/download"; import { openURL } from "$lib/download";
import DragDropArea from "$components/misc/DragDropArea.svelte"; import DragDropArea from "$components/misc/DragDropArea.svelte";
@ -9,11 +9,11 @@
let file: File; let file: File;
const render = async () => { const render = async () => {
const ff = new FFmpegWrapper(); const ff = new LibAVWrapper();
await ff.init(); await ff.init();
const render = await ff.renderFile({ const render = await ff.render({
file, blob: file,
args: ["-c", "copy"], args: ["-c", "copy"],
}); });