Running FFMPEG with WASM in a Web Worker

Me encanta FFMPEG.js, es una buena herramienta compilada con asm.js` y me permite crear aplicaciones web JS que pueden editar videos rápidamente. FFMPEG.js también trabaja con trabajadores web para que pueda codificar videos sin bloquear el hilo principal.

También me encanta Comlink. Comlink me permite interactuar fácilmente con los trabajadores web al exponer funciones y clases sin tener que lidiar con una compleja máquina de estados postMessage.

Recientemente pude combinar los dos juntos. Estaba experimentando para que FFMPEG fuera exportado a Web Assembly (funciona - yay) y quería limpiar todo el trabajo posterior al mensaje en el proyecto FFMPEG.js actual. A continuación se muestra cómo se ve el código: creo que es bastante claro. Tenemos un trabajador que importa ffmpeg.js y comlink y simplemente expone la interfaz ffmpeg, y luego tenemos la página web que carga al trabajador y luego usa comlink para crear un proxy para la API de ffmpeg.

Ordenado.

worker.js

importScripts('https://cdn.jsdelivr.net/npm/comlinkjs@3.0.2/umd/comlink.js');
importScripts('../ffmpeg-webm.js'); 
Comlink.expose(ffmpegjs, self);

client.html

let ffmpegjs = await Comlink.proxy(worker);
let result = await ffmpegjs({
   arguments: ['-y','-i', file.name, 'output.webm'],
   MEMFS: [{name: file.name, data: data}],
   stdin: Comlink.proxyValue(() => {}),
   onfilesready: Comlink.proxyValue((e) => {
     let data = e.MEMFS[0].data;
     output.src = URL.createObjectURL(new Blob([data]))
     console.log('ready', e)
   }),
   print: Comlink.proxyValue(function(data) { console.log(data); stdout += data + "\n"; }),
   printErr: Comlink.proxyValue(function(data) { console.log('error', data); stderr += data + "\n"; }),
   postRun: Comlink.proxyValue(function(result) { console.log('DONE', result); }),
   onExit: Comlink.proxyValue(function(code) {
     console.log("Process exited with code " + code);
     console.log(stdout);
   }),
});

Me gusta mucho cómo pueden jugar juntos los módulos compilados de Comlink, Workers y WASM. Obtengo JavaScript idiomático que interactúa con el módulo WASM directamente y se ejecuta fuera del hilo principal.

Leer publicación completa.

About Me: Paul Kinlan

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.