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
-sEXPORTED_FUNCTIONS=$(node src/bind/ffmpeg/export.js) # exported 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
# ffmpeg source code
src/fftools/cmdutils.c

View File

@ -13,6 +13,10 @@ import {
LogEventCallback,
ProgressEventCallback,
FileData,
WorkerFSMountData,
FFFSType,
FFFSMountOptions,
FFFSPath,
} from "./types.js";
import { getMessageID } from "./utils.js";
import { ERROR_TERMINATED, ERROR_NOT_LOADED } from "./errors.js";
@ -56,6 +60,8 @@ export class FFmpeg {
this.loaded = true;
this.#resolves[id](data);
break;
case FFMessageType.MOUNT:
case FFMessageType.UNMOUNT:
case FFMessageType.EXEC:
case FFMessageType.WRITE_FILE:
case FFMessageType.READ_FILE:
@ -292,6 +298,28 @@ export class FFmpeg {
) 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.
*

View File

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

View File

@ -64,6 +64,41 @@ export interface FFMessageDeleteDirData {
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 =
| FFMessageLoadConfig
| FFMessageExecData
@ -73,7 +108,9 @@ export type FFMessageData =
| FFMessageRenameData
| FFMessageCreateDirData
| FFMessageListDirData
| FFMessageDeleteDirData;
| FFMessageDeleteDirData
| FFMessageMountData
| FFMessageUnmountData;
export interface Message {
type: string;
@ -134,4 +171,4 @@ export interface FFMessageEventCallback {
type: string;
data: CallbackData;
};
}
}

View File

@ -14,6 +14,8 @@ import type {
FFMessageCreateDirData,
FFMessageListDirData,
FFMessageDeleteDirData,
FFMessageMountData,
FFMessageUnmountData,
CallbackData,
IsFirst,
OK,
@ -137,6 +139,19 @@ const deleteDir = ({ path }: FFMessageDeleteDirData): OK => {
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 ({
data: { id, type, data: _data },
}: FFMessageEvent): Promise<void> => {
@ -173,6 +188,12 @@ self.onmessage = async ({
case FFMessageType.DELETE_DIR:
data = deleteDir(_data as FFMessageDeleteDirData);
break;
case FFMessageType.MOUNT:
data = mount(_data as FFMessageMountData);
break;
case FFMessageType.UNMOUNT:
data = unmount(_data as FFMessageUnmountData);
break;
default:
throw ERROR_UNKNOWN_MESSAGE_TYPE;
}

View File

@ -39,6 +39,23 @@ export interface Stat {
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.
*
@ -58,6 +75,9 @@ export interface FS {
isFile: (mode: number) => boolean;
/** mode is a numeric notation of permission, @see [Numeric Notation](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation) */
isDir: (mode: number) => boolean;
mount: (fileSystemType: FSFilesystem, data: WorkerFSMountConfig, path: string) => void;
unmount: (path: string) => void;
filesystems: FSFilesystems;
}
/**