web/libav: always clean up files on function exit

This commit is contained in:
dumbmoron 2024-09-07 14:23:33 +00:00
parent 0ce743d13f
commit 0a37c84e93
No known key found for this signature in database

View file

@ -29,22 +29,25 @@ export default class LibAVWrapper {
const libav = await this.libav; const libav = await this.libav;
await libav.mkreadaheadfile('input', blob); await libav.mkreadaheadfile('input', blob);
await libav.ffprobe([
'-v', 'quiet',
'-print_format', 'json',
'-show_format',
'-show_streams',
'input',
'-o', 'output.json'
]);
await libav.unlinkreadaheadfile('input'); try {
await libav.ffprobe([
'-v', 'quiet',
'-print_format', 'json',
'-show_format',
'-show_streams',
'input',
'-o', 'output.json'
]);
const copy = await libav.readFile('output.json'); const copy = await libav.readFile('output.json');
const text = new TextDecoder().decode(copy); const text = new TextDecoder().decode(copy);
await libav.unlink('output.json'); await libav.unlink('output.json');
return JSON.parse(text) as FfprobeData; return JSON.parse(text) as FfprobeData;
} finally {
await libav.unlinkreadaheadfile('input');
}
} }
static getExtensionFromType(blob: Blob) { static getExtensionFromType(blob: Blob) {
@ -82,62 +85,67 @@ export default class LibAVWrapper {
const outputName = `output.${output.extension}`; const outputName = `output.${output.extension}`;
await libav.mkreadaheadfile("input", blob); try {
await libav.mkreadaheadfile("input", blob);
// 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 libav.mkwriterdev(outputName); await libav.mkwriterdev(outputName);
await libav.mkwriterdev('progress.txt'); await libav.mkwriterdev('progress.txt');
// since we expect the output file to be roughly the same size // since we expect the output file to be roughly the same size
// as the original, preallocate its size for the output // as the original, preallocate its size for the output
let writtenData = new Uint8Array(blob.size), actualSize = 0; let writtenData = new Uint8Array(blob.size), actualSize = 0;
libav.onwrite = (name, pos, data) => { libav.onwrite = (name, pos, data) => {
if (name === 'progress.txt') { if (name === 'progress.txt') {
try { try {
return this.#emitProgress(data); return this.#emitProgress(data);
} catch(e) { } catch(e) {
console.error(e); console.error(e);
}
} else if (name !== outputName) return;
actualSize = Math.max(pos + data.length, actualSize);
const newLen = Math.max(pos + data.length, writtenData.length);
if (newLen > writtenData.length) {
const newData = new Uint8Array(newLen);
newData.set(writtenData);
writtenData = newData;
} }
} else if (name !== outputName) return; writtenData.set(data, pos);
};
actualSize = Math.max(pos + data.length, actualSize); await libav.ffmpeg([
const newLen = Math.max(pos + data.length, writtenData.length); '-nostdin', '-y',
if (newLen > writtenData.length) { '-loglevel', 'error',
const newData = new Uint8Array(newLen); '-progress', 'progress.txt',
newData.set(writtenData); '-threads', this.concurrency.toString(),
writtenData = newData; '-i', 'input',
...args,
outputName
]);
// if we didn't need as much space as we allocated for some reason,
// shrink the buffer so that we don't inflate the file with zeros
if (writtenData.length > actualSize) {
writtenData = writtenData.slice(0, actualSize);
} }
writtenData.set(data, pos);
};
await libav.ffmpeg([ const renderBlob = new Blob(
'-nostdin', '-y', [ writtenData ],
'-loglevel', 'error', { type: output.type }
'-progress', 'progress.txt', );
'-threads', this.concurrency.toString(),
'-i', 'input',
...args,
outputName
]);
await libav.unlink(outputName); if (renderBlob.size === 0) return;
await libav.unlink('progress.txt'); return renderBlob;
await libav.unlinkreadaheadfile("input");
// if we didn't need as much space as we allocated for some reason, } finally {
// shrink the buffer so that we don't inflate the file with zeros try {
if (writtenData.length > actualSize) { await libav.unlink(outputName);
writtenData = writtenData.slice(0, actualSize); await libav.unlink('progress.txt');
await libav.unlinkreadaheadfile("input");
} catch {}
} }
const renderBlob = new Blob(
[ writtenData ],
{ type: output.type }
);
if (renderBlob.size === 0) return;
return renderBlob;
} }
#emitProgress(data: Uint8Array | Int8Array) { #emitProgress(data: Uint8Array | Int8Array) {