mirror of
https://github.com/imputnet/cobalt.git
synced 2025-07-08 14:28:30 +00:00

Some checks are pending
there's no navigator.maxTouchPoints in web worker context, so previously there was no way to detect whether safari is running on ipad or not
106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
import FFmpegWorker from "$lib/task-manager/workers/ffmpeg?worker";
|
|
|
|
import { device } from "$lib/device";
|
|
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',
|
|
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, device.supports.multithreading
|
|
);
|
|
} 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,
|
|
}
|
|
});
|
|
|
|
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);
|
|
}
|
|
};
|
|
}
|