File size: 3,184 Bytes
11fcc5a |
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
import FFmpegWorker from "$lib/task-manager/workers/ffmpeg?worker";
import { killWorker } from "$lib/task-manager/run-worker";
import { updateWorkerProgress } from "$lib/state/task-manager/current-tasks";
import { pipelineTaskDone, itemError, queue } from "$lib/state/task-manager/queue";
import type { FileInfo } from "$lib/types/libav";
import type { CobaltQueue } from "$lib/types/queue";
let startAttempts = 0;
export const runFFmpegWorker = async (
workerId: string,
parentId: string,
files: File[],
args: string[],
output: FileInfo,
variant: 'remux' | 'encode',
yesthreads: boolean,
resetStartCounter = false,
) => {
const worker = new FFmpegWorker();
// sometimes chrome refuses to start libav wasm,
// so we check if it started, try 10 more times if not, and kill self if it still doesn't work
// TODO: fix the underlying issue because this is ridiculous
if (resetStartCounter) startAttempts = 0;
let bumpAttempts = 0;
const startCheck = setInterval(async () => {
bumpAttempts++;
if (bumpAttempts === 10) {
startAttempts++;
if (startAttempts <= 10) {
killWorker(worker, unsubscribe, startCheck);
return await runFFmpegWorker(
workerId, parentId,
files, args, output,
variant, yesthreads
);
} else {
killWorker(worker, unsubscribe, startCheck);
return itemError(parentId, workerId, "queue.worker_didnt_start");
}
}
}, 500);
const unsubscribe = queue.subscribe((queue: CobaltQueue) => {
if (!queue[parentId]) {
killWorker(worker, unsubscribe, startCheck);
}
});
worker.postMessage({
cobaltFFmpegWorker: {
variant,
files,
args,
output,
yesthreads,
}
});
worker.onerror = (e) => {
console.error("ffmpeg worker crashed:", e);
killWorker(worker, unsubscribe, startCheck);
return itemError(parentId, workerId, "queue.generic_error");
};
let totalDuration: number | null = null;
worker.onmessage = (event) => {
const eventData = event.data.cobaltFFmpegWorker;
if (!eventData) return;
clearInterval(startCheck);
if (eventData.progress) {
if (eventData.progress.duration) {
totalDuration = eventData.progress.duration;
}
updateWorkerProgress(workerId, {
percentage: totalDuration ? (eventData.progress.durationProcessed / totalDuration) * 100 : 0,
size: eventData.progress.size,
})
}
if (eventData.render) {
killWorker(worker, unsubscribe, startCheck);
return pipelineTaskDone(
parentId,
workerId,
eventData.render,
);
}
if (eventData.error) {
killWorker(worker, unsubscribe, startCheck);
return itemError(parentId, workerId, eventData.error);
}
};
}
|