From 0716f97a3ad84310ee8c7745cf9f5351d84898b4 Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 30 Apr 2025 14:48:44 +0000 Subject: [PATCH] web/workers: refactor remux worker into ffmpeg worker --- web/src/lib/task-manager/run-worker.ts | 6 ++++-- .../runners/{remux.ts => ffmpeg.ts} | 16 ++++++++------- .../workers/{remux.ts => ffmpeg.ts} | 20 +++++++++---------- 3 files changed, 22 insertions(+), 20 deletions(-) rename web/src/lib/task-manager/runners/{remux.ts => ffmpeg.ts} (87%) rename web/src/lib/task-manager/workers/{remux.ts => ffmpeg.ts} (85%) diff --git a/web/src/lib/task-manager/run-worker.ts b/web/src/lib/task-manager/run-worker.ts index 16d6059b..0c25d8ec 100644 --- a/web/src/lib/task-manager/run-worker.ts +++ b/web/src/lib/task-manager/run-worker.ts @@ -1,7 +1,7 @@ import { get } from "svelte/store"; import { queue } from "$lib/state/task-manager/queue"; -import { runRemuxWorker } from "$lib/task-manager/runners/remux"; +import { runFFmpegWorker } from "$lib/task-manager/runners/ffmpeg"; import { runFetchWorker } from "$lib/task-manager/runners/fetch"; import type { CobaltPipelineItem } from "$lib/types/workers"; @@ -18,6 +18,7 @@ export const startWorker = async ({ worker, workerId, parentId, workerArgs }: Co switch (worker) { case "remux": + case "encode": if (workerArgs.files) { files = workerArgs.files; } @@ -30,12 +31,13 @@ export const startWorker = async ({ worker, workerId, parentId, workerArgs }: Co } if (files.length > 0 && workerArgs.ffargs && workerArgs.output) { - await runRemuxWorker( + await runFFmpegWorker( workerId, parentId, files, workerArgs.ffargs, workerArgs.output, + worker, /*resetStartCounter=*/true, ); } diff --git a/web/src/lib/task-manager/runners/remux.ts b/web/src/lib/task-manager/runners/ffmpeg.ts similarity index 87% rename from web/src/lib/task-manager/runners/remux.ts rename to web/src/lib/task-manager/runners/ffmpeg.ts index 53b881f3..6ade990c 100644 --- a/web/src/lib/task-manager/runners/remux.ts +++ b/web/src/lib/task-manager/runners/ffmpeg.ts @@ -1,4 +1,4 @@ -import RemuxWorker from "$lib/task-manager/workers/remux?worker"; +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"; @@ -10,15 +10,16 @@ import type { CobaltFileReference } from "$lib/types/storage"; let startAttempts = 0; -export const runRemuxWorker = async ( +export const runFFmpegWorker = async ( workerId: string, parentId: string, files: CobaltFileReference[], args: string[], output: FileInfo, + variant: 'remux' | 'encode', resetStartCounter = false ) => { - const worker = new RemuxWorker(); + 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 @@ -35,7 +36,7 @@ export const runRemuxWorker = async ( if (startAttempts <= 10) { killWorker(worker, unsubscribe, startCheck); console.error("worker didn't start after 5 seconds, so it was killed and started again"); - return await runRemuxWorker(workerId, parentId, files, args, output); + return await runFFmpegWorker(workerId, parentId, files, args, output, variant); } else { killWorker(worker, unsubscribe, startCheck); console.error("worker didn't start after 10 attempts, so we're giving up"); @@ -55,7 +56,8 @@ export const runRemuxWorker = async ( }); worker.postMessage({ - cobaltRemuxWorker: { + cobaltFFmpegWorker: { + variant, files, args, output, @@ -63,7 +65,7 @@ export const runRemuxWorker = async ( }); worker.onerror = (e) => { - console.error("remux worker exploded:", e); + console.error("ffmpeg worker exploded:", e); killWorker(worker, unsubscribe, startCheck); // TODO: proper error code @@ -73,7 +75,7 @@ export const runRemuxWorker = async ( let totalDuration: number | null = null; worker.onmessage = (event) => { - const eventData = event.data.cobaltRemuxWorker; + const eventData = event.data.cobaltFFmpegWorker; if (!eventData) return; clearInterval(startCheck); diff --git a/web/src/lib/task-manager/workers/remux.ts b/web/src/lib/task-manager/workers/ffmpeg.ts similarity index 85% rename from web/src/lib/task-manager/workers/remux.ts rename to web/src/lib/task-manager/workers/ffmpeg.ts index 281b2594..0f79e5b9 100644 --- a/web/src/lib/task-manager/workers/remux.ts +++ b/web/src/lib/task-manager/workers/ffmpeg.ts @@ -5,18 +5,18 @@ import type { CobaltFileReference } from "$lib/types/storage"; const error = (code: string) => { self.postMessage({ - cobaltRemuxWorker: { + cobaltFFmpegWorker: { error: `error.${code}`, } }) } -const remux = async (files: CobaltFileReference[], args: string[], output: FileInfo) => { +const remux = async (variant: string, files: CobaltFileReference[], args: string[], output: FileInfo) => { if (!(files && output && args)) return; const ff = new LibAVWrapper((progress) => { self.postMessage({ - cobaltRemuxWorker: { + cobaltFFmpegWorker: { progress: { durationProcessed: progress.out_time_sec, speed: progress.speed, @@ -28,7 +28,7 @@ const remux = async (files: CobaltFileReference[], args: string[], output: FileI }) }); - ff.init(); + ff.init({ variant }); try { // probing just the first file in files array (usually audio) for duration progress @@ -50,7 +50,7 @@ const remux = async (files: CobaltFileReference[], args: string[], output: FileI } self.postMessage({ - cobaltRemuxWorker: { + cobaltFFmpegWorker: { progress: { duration: Number(file_info.format.duration), } @@ -85,7 +85,7 @@ const remux = async (files: CobaltFileReference[], args: string[], output: FileI await ff.terminate(); self.postMessage({ - cobaltRemuxWorker: { + cobaltFFmpegWorker: { render } }); @@ -96,10 +96,8 @@ const remux = async (files: CobaltFileReference[], args: string[], output: FileI } self.onmessage = async (event: MessageEvent) => { - const ed = event.data.cobaltRemuxWorker; - if (ed) { - if (ed.files && ed.args && ed.output) { - await remux(ed.files, ed.args, ed.output); - } + const ed = event.data.cobaltFFmpegWorker; + if (ed?.variant && ed?.files && ed?.args && ed?.output) { + await remux(ed.variant, ed.files, ed.args, ed.output); } }