@meframe/core
Version:
Next generation media processing framework based on WebCodecs
145 lines (144 loc) • 3.76 kB
JavaScript
import { BaseWorker } from "./BaseWorker.js";
import { WorkerMessageType } from "./types.js";
const WORKER_FILE_NAMES = {
videoDemux: "video-demux",
audioDemux: "audio-demux",
videoDecode: "video-decode",
audioDecode: "audio-decode",
videoCompose: "video-compose",
audioCompose: "audio-compose",
videoEncode: "video-encode"
};
class WorkerPool {
pool = /* @__PURE__ */ new Map();
eventBus;
workerConfigs;
workerPath;
workerExtension;
constructor(config) {
this.eventBus = config.eventBus;
this.workerConfigs = config.workerConfigs || {};
this.workerPath = config.workerPath || "/meframe-workers";
this.workerExtension = config.workerExtension || ".js";
}
/**
* Get worker URL for a specific worker type
*/
getWorkerUrl(type) {
const fileName = WORKER_FILE_NAMES[type];
const stageMap = {
"video-demux": "demux",
"audio-demux": "demux",
"video-decode": "decode",
"audio-decode": "decode",
decode: "decode",
"video-compose": "compose",
"audio-compose": "compose",
"video-encode": "encode",
encode: "encode"
};
const stage = stageMap[fileName];
const url = `${this.workerPath}/stages/${stage}/${fileName}.worker${this.workerExtension}`;
return url;
}
get(type, id) {
const key = id ? `${type}#${id}` : type;
return this.pool.get(key) ?? void 0;
}
/**
* Get or create a worker instance
* @param type - Worker type
* @param id - Optional ID for per-resource or per-clip workers
* @param options - Optional configuration
* - lazy: If true, skip initial configure (default: false)
*/
async getOrCreate(type, id, options) {
const key = id ? `${type}#${id}` : type;
const existing = this.pool.get(key);
if (!existing) {
const url = this.getWorkerUrl(type);
const worker = new BaseWorker({
type,
url,
eventBus: this.eventBus,
clipId: id
});
if (!options?.lazy) {
const config = this.workerConfigs[type];
await worker.initialize(config);
}
this.pool.set(key, worker);
return worker;
}
if (!options?.lazy) {
const config = this.workerConfigs[type];
if (config) {
await existing.send(WorkerMessageType.Configure, {
config,
initial: false
});
}
}
return existing;
}
async setConfig(type, config) {
const existing = this.workerConfigs[type] || {};
const mergedConfig = { ...existing, ...config };
this.workerConfigs[type] = mergedConfig;
for (const [key, worker] of this.pool.entries()) {
if (key === type || key.startsWith(`${type}#`)) {
await worker.send(WorkerMessageType.Configure, {
config: mergedConfig,
initial: false
});
}
}
}
/**
* Terminate a specific worker
*/
terminate(type, id) {
const key = id ? `${type}#${id}` : type;
const worker = this.pool.get(key);
if (worker) {
worker.terminate();
this.pool.delete(key);
}
}
/**
* Terminate all workers
*/
terminateAll() {
for (const worker of this.pool.values()) {
worker.terminate();
}
this.pool.clear();
}
/**
* Get status of all workers
*/
get status() {
const result = {};
for (const [key, worker] of this.pool.entries()) {
result[key] = worker.status;
}
return result;
}
/**
* Get list of active worker keys
*/
get activeWorkers() {
return Array.from(this.pool.keys());
}
/**
* Check if a worker exists
*/
has(type, id) {
const key = id ? `${type}#${id}` : type;
return this.pool.has(key);
}
}
export {
WorkerPool
};
//# sourceMappingURL=WorkerPool.js.map