-
Notifications
You must be signed in to change notification settings - Fork 53
/
webm-worker.js
105 lines (98 loc) · 3.21 KB
/
webm-worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import webmWasm from "../../dist/webm-wasm.js";
// Below you find the “Interop between Node and Web is fun” section.
// On the web you can communicate with the main thread via `self`.
// In node land you need to get the `parentPort` from the `worker_threads`
// module.
let parentPort;
try {
({ parentPort } = require("worker_threads"));
} catch (_) {
parentPort = self;
}
// On the web you get a `MessageEvent` which has the message payload on
// it’s `.data` property.
// In node land the event is the message payload itself.
function onMessage(target, f) {
if ("on" in target) {
return target.on("message", f);
}
return target.addEventListener("message", e => f(e.data));
}
function nextMessage(target) {
return new Promise(resolve => {
if ("once" in target) {
return target.once("message", resolve);
}
return target.addEventListener("message", e => resolve(e.data), {
once: true
});
});
}
export function initWasmModule(moduleFactory, wasmUrl) {
return new Promise(resolve => {
const module = moduleFactory({
// Just to be safe, don't automatically invoke any wasm functions
noInitialRun: true,
locateFile(url) {
if (url.endsWith(".wasm")) {
return wasmUrl;
}
return url;
},
onRuntimeInitialized() {
// An Emscripten is a then-able that resolves with itself, causing an infite loop when you
// wrap it in a real promise. Delete the `then` prop solves this for now.
// https://github.com/kripken/emscripten/issues/5820
delete module.then;
resolve(module);
}
});
});
}
import defaultConfig from "./defaults.js";
async function init() {
const wasmPath = await nextMessage(parentPort, "message");
const module = await initWasmModule(webmWasm, wasmPath);
parentPort.postMessage("READY");
const userParams = await nextMessage(parentPort, "message");
const params = Object.assign({}, defaultConfig, userParams);
const instance = new module.WebmEncoder(
params.timebaseNum,
params.timebaseDen,
params.width,
params.height,
params.bitrate,
params.realtime,
params.kLive,
chunk => {
const copy = new Uint8Array(chunk);
parentPort.postMessage(copy.buffer, [copy.buffer]);
}
);
onMessage(parentPort, msg => {
// A false-y message indicates the end-of-stream.
if (!msg) {
// This will invoke the callback to flush
instance.finalize();
// Signal the end-of-stream
parentPort.postMessage(null);
// Free up the memory.
instance.delete();
return;
}
instance.addRGBAFrame(msg);
});
}
init();