Add WORKERFS support (#581)

* README.md update

* Workflow update

* Action update

* Workflow update

* Workflow update

* Added workerLoadURL to FFMessageLoadConfig

* Add WORKERFS support

* Imported WORKERFS types

* Import WORKERFS types

* Action update

* Type updates

* Export update

* Updated classes

* Package together workflow  update

* Cleanup

* Restore CI.yml to upstream

* Restore README.md to upstream

* Restore classes.ts changes that are not related tp WORKERFS

* Restore types.ts changes unrelated to WORERFS

* Restore const.ts changes unrelated to WORKERFS

* Updated mount to support any enabled filesystems.

---------

Co-authored-by: Todd <todd@3dgamemarket.net>
This commit is contained in:
Todd T 2023-10-09 11:22:49 -04:00 committed by GitHub
parent e8fa42296f
commit c39143b08b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 3 deletions

View File

@ -39,6 +39,7 @@ CONF_FLAGS=(
-sEXPORT_NAME="$EXPORT_NAME" # required in browser env, so that user can access this module from window object -sEXPORT_NAME="$EXPORT_NAME" # required in browser env, so that user can access this module from window object
-sEXPORTED_FUNCTIONS=$(node src/bind/ffmpeg/export.js) # exported functions -sEXPORTED_FUNCTIONS=$(node src/bind/ffmpeg/export.js) # exported functions
-sEXPORTED_RUNTIME_METHODS=$(node src/bind/ffmpeg/export-runtime.js) # exported built-in functions -sEXPORTED_RUNTIME_METHODS=$(node src/bind/ffmpeg/export-runtime.js) # exported built-in functions
-lworkerfs.js
--pre-js src/bind/ffmpeg/bind.js # extra bindings, contains most of the ffmpeg.wasm javascript code --pre-js src/bind/ffmpeg/bind.js # extra bindings, contains most of the ffmpeg.wasm javascript code
# ffmpeg source code # ffmpeg source code
src/fftools/cmdutils.c src/fftools/cmdutils.c

View File

@ -13,6 +13,10 @@ import {
LogEventCallback, LogEventCallback,
ProgressEventCallback, ProgressEventCallback,
FileData, FileData,
WorkerFSMountData,
FFFSType,
FFFSMountOptions,
FFFSPath,
} from "./types.js"; } from "./types.js";
import { getMessageID } from "./utils.js"; import { getMessageID } from "./utils.js";
import { ERROR_TERMINATED, ERROR_NOT_LOADED } from "./errors.js"; import { ERROR_TERMINATED, ERROR_NOT_LOADED } from "./errors.js";
@ -56,6 +60,8 @@ export class FFmpeg {
this.loaded = true; this.loaded = true;
this.#resolves[id](data); this.#resolves[id](data);
break; break;
case FFMessageType.MOUNT:
case FFMessageType.UNMOUNT:
case FFMessageType.EXEC: case FFMessageType.EXEC:
case FFMessageType.WRITE_FILE: case FFMessageType.WRITE_FILE:
case FFMessageType.READ_FILE: case FFMessageType.READ_FILE:
@ -292,6 +298,28 @@ export class FFmpeg {
) as Promise<OK>; ) as Promise<OK>;
}; };
public mount = (fsType: FFFSType, options: FFFSMountOptions, mountPoint: FFFSPath, ): Promise<OK> => {
const trans: Transferable[] = [];
return this.#send(
{
type: FFMessageType.MOUNT,
data: { fsType, options, mountPoint },
},
trans
) as Promise<OK>;
};
public unmount = (mountPoint: FFFSPath): Promise<OK> => {
const trans: Transferable[] = [];
return this.#send(
{
type: FFMessageType.UNMOUNT,
data: { mountPoint },
},
trans
) as Promise<OK>;
};
/** /**
* Read data from ffmpeg.wasm. * Read data from ffmpeg.wasm.
* *

View File

@ -19,4 +19,6 @@ export enum FFMessageType {
DOWNLOAD = "DOWNLOAD", DOWNLOAD = "DOWNLOAD",
PROGRESS = "PROGRESS", PROGRESS = "PROGRESS",
LOG = "LOG", LOG = "LOG",
MOUNT = "MOUNT",
UNMOUNT = "UNMOUNT",
} }

View File

@ -64,6 +64,41 @@ export interface FFMessageDeleteDirData {
path: FFFSPath; path: FFFSPath;
} }
export enum FFFSType {
MEMFS = "MEMFS",
NODEFS = "NODEFS",
NODERAWFS = "NODERAWFS",
IDBFS = "IDBFS",
WORKERFS = "WORKERFS",
PROXYFS = "PROXYFS",
}
export type WorkerFSFileEntry =
| File;
export interface WorkerFSBlobEntry {
name: string;
data: Blob;
}
export interface WorkerFSMountData {
blobs?: WorkerFSBlobEntry[];
files?: WorkerFSFileEntry[];
}
export type FFFSMountOptions =
| WorkerFSMountData;
export interface FFMessageMountData {
fsType: FFFSType;
options: FFFSMountOptions;
mountPoint: FFFSPath;
}
export interface FFMessageUnmountData {
mountPoint: FFFSPath;
}
export type FFMessageData = export type FFMessageData =
| FFMessageLoadConfig | FFMessageLoadConfig
| FFMessageExecData | FFMessageExecData
@ -73,7 +108,9 @@ export type FFMessageData =
| FFMessageRenameData | FFMessageRenameData
| FFMessageCreateDirData | FFMessageCreateDirData
| FFMessageListDirData | FFMessageListDirData
| FFMessageDeleteDirData; | FFMessageDeleteDirData
| FFMessageMountData
| FFMessageUnmountData;
export interface Message { export interface Message {
type: string; type: string;

View File

@ -14,6 +14,8 @@ import type {
FFMessageCreateDirData, FFMessageCreateDirData,
FFMessageListDirData, FFMessageListDirData,
FFMessageDeleteDirData, FFMessageDeleteDirData,
FFMessageMountData,
FFMessageUnmountData,
CallbackData, CallbackData,
IsFirst, IsFirst,
OK, OK,
@ -137,6 +139,19 @@ const deleteDir = ({ path }: FFMessageDeleteDirData): OK => {
return true; return true;
}; };
const mount = ({ fsType, options, mountPoint }: FFMessageMountData): OK => {
let str = fsType as keyof typeof ffmpeg.FS.filesystems;
let fs = ffmpeg.FS.filesystems[str];
if (!fs) return false;
ffmpeg.FS.mount(fs, options, mountPoint);
return true;
};
const unmount = ({ mountPoint }: FFMessageUnmountData): OK => {
ffmpeg.FS.unmount(mountPoint);
return true;
};
self.onmessage = async ({ self.onmessage = async ({
data: { id, type, data: _data }, data: { id, type, data: _data },
}: FFMessageEvent): Promise<void> => { }: FFMessageEvent): Promise<void> => {
@ -173,6 +188,12 @@ self.onmessage = async ({
case FFMessageType.DELETE_DIR: case FFMessageType.DELETE_DIR:
data = deleteDir(_data as FFMessageDeleteDirData); data = deleteDir(_data as FFMessageDeleteDirData);
break; break;
case FFMessageType.MOUNT:
data = mount(_data as FFMessageMountData);
break;
case FFMessageType.UNMOUNT:
data = unmount(_data as FFMessageUnmountData);
break;
default: default:
throw ERROR_UNKNOWN_MESSAGE_TYPE; throw ERROR_UNKNOWN_MESSAGE_TYPE;
} }

View File

@ -39,6 +39,23 @@ export interface Stat {
blocks: number; blocks: number;
} }
export interface FSFilesystemWORKERFS {
}
export interface FSFilesystemMEMFS {
}
export interface FSFilesystems {
WORKERFS: FSFilesystemWORKERFS;
MEMFS: FSFilesystemMEMFS;
}
export type FSFilesystem =
| FSFilesystemWORKERFS
| FSFilesystemMEMFS;
/** /**
* Functions to interact with Emscripten FS library. * Functions to interact with Emscripten FS library.
* *
@ -58,6 +75,9 @@ export interface FS {
isFile: (mode: number) => boolean; isFile: (mode: number) => boolean;
/** mode is a numeric notation of permission, @see [Numeric Notation](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation) */ /** mode is a numeric notation of permission, @see [Numeric Notation](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation) */
isDir: (mode: number) => boolean; isDir: (mode: number) => boolean;
mount: (fileSystemType: FSFilesystem, data: WorkerFSMountConfig, path: string) => void;
unmount: (path: string) => void;
filesystems: FSFilesystems;
} }
/** /**