From 7d163e3db24783bb4e4fbfb88b0ccfb88d749bca Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 9 May 2024 21:20:03 +0800 Subject: [PATCH] Add AudioWorklet globals (#249) --- data/browser.mjs | 7 +++++ globals.json | 7 +++++ scripts/get-browser-globals.mjs | 45 +++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/data/browser.mjs b/data/browser.mjs index 604015c..24a9279 100644 --- a/data/browser.mjs +++ b/data/browser.mjs @@ -33,7 +33,9 @@ export default { AudioScheduledSourceNode: false, AudioSinkInfo: false, AudioWorklet: false, + AudioWorkletGlobalScope: false, AudioWorkletNode: false, + AudioWorkletProcessor: false, AuthenticatorAssertionResponse: false, AuthenticatorAttestationResponse: false, AuthenticatorResponse: false, @@ -162,6 +164,8 @@ export default { CSSUnitValue: false, CSSUnparsedValue: false, CSSVariableReferenceValue: false, + currentFrame: false, + currentTime: false, CustomElementRegistry: false, customElements: false, CustomEvent: false, @@ -729,6 +733,7 @@ export default { ReadableStreamBYOBRequest: false, ReadableStreamDefaultController: false, ReadableStreamDefaultReader: false, + registerProcessor: false, RelativeOrientationSensor: false, RemotePlayback: false, removeEventListener: false, @@ -766,6 +771,7 @@ export default { RTCSessionDescription: false, RTCStatsReport: false, RTCTrackEvent: false, + sampleRate: false, scheduler: false, Scheduler: false, Scheduling: false, @@ -1037,6 +1043,7 @@ export default { WindowControlsOverlayGeometryChangeEvent: false, Worker: false, Worklet: false, + WorkletGlobalScope: false, WritableStream: false, WritableStreamDefaultController: false, WritableStreamDefaultWriter: false, diff --git a/globals.json b/globals.json index c924228..79213e3 100644 --- a/globals.json +++ b/globals.json @@ -355,7 +355,9 @@ "AudioScheduledSourceNode": false, "AudioSinkInfo": false, "AudioWorklet": false, + "AudioWorkletGlobalScope": false, "AudioWorkletNode": false, + "AudioWorkletProcessor": false, "AuthenticatorAssertionResponse": false, "AuthenticatorAttestationResponse": false, "AuthenticatorResponse": false, @@ -484,6 +486,8 @@ "CSSUnitValue": false, "CSSUnparsedValue": false, "CSSVariableReferenceValue": false, + "currentFrame": false, + "currentTime": false, "CustomElementRegistry": false, "customElements": false, "CustomEvent": false, @@ -1051,6 +1055,7 @@ "ReadableStreamBYOBRequest": false, "ReadableStreamDefaultController": false, "ReadableStreamDefaultReader": false, + "registerProcessor": false, "RelativeOrientationSensor": false, "RemotePlayback": false, "removeEventListener": false, @@ -1088,6 +1093,7 @@ "RTCSessionDescription": false, "RTCStatsReport": false, "RTCTrackEvent": false, + "sampleRate": false, "scheduler": false, "Scheduler": false, "Scheduling": false, @@ -1359,6 +1365,7 @@ "WindowControlsOverlayGeometryChangeEvent": false, "Worker": false, "Worklet": false, + "WorkletGlobalScope": false, "WritableStream": false, "WritableStreamDefaultController": false, "WritableStreamDefaultWriter": false, diff --git a/scripts/get-browser-globals.mjs b/scripts/get-browser-globals.mjs index d9ca47e..c82f7e6 100644 --- a/scripts/get-browser-globals.mjs +++ b/scripts/get-browser-globals.mjs @@ -3,6 +3,7 @@ import http from 'node:http'; import assert from 'node:assert/strict'; import puppeteer from 'puppeteer'; import getPort from 'get-port'; +import {outdent} from 'outdent'; import {getGlobalThisProperties, createGlobals} from './utilities.mjs'; const ignoredGlobals = new Set([ @@ -134,7 +135,11 @@ async function navigateToSecureContext(page, responses) { }; } -async function runInBrowser(function_, {product, secureContext = false} = {}) { +async function runInBrowser(function_, { + product, + secureContext = false, + arguments: arguments_ = [], +} = {}) { await downloadBrowser({product}); const browser = await puppeteer.launch({product}); @@ -150,13 +155,47 @@ async function runInBrowser(function_, {product, secureContext = false} = {}) { ); } - return await page.evaluate(function_); + return await page.evaluate(function_, arguments_); } finally { await browser.close(); await server?.close(); } } +async function runInAudioWorklet(function_) { + const workletCode = outdent` + registerProcessor('execute-processor', class extends AudioWorkletProcessor { + constructor() { + super(); + + this.port.postMessage(${function_}()); + } + process() { + return true; + } + }); + `; + + return runInBrowser(async workletCode => { + // eslint-disable-next-line no-undef -- execute in browser + const context = new AudioContext(); + const workletUrl = URL.createObjectURL(new Blob([workletCode], {type: 'application/javascript'})); + await context.audioWorklet.addModule(workletUrl); + URL.revokeObjectURL(workletUrl); + return new Promise(resolve => { + // eslint-disable-next-line no-undef -- execute in browser + const node = new AudioWorkletNode(context, 'execute-processor'); + // eslint-disable-next-line unicorn/prefer-add-event-listener -- not working + node.port.onmessage = ({data}) => { + resolve(data); + }; + }); + }, { + secureContext: true, + arguments: [workletCode], + }); +} + async function runInWebWorker(function_) { await downloadBrowser(); @@ -196,11 +235,13 @@ async function runInWebWorker(function_) { async function getBrowserGlobals() { const chromeGlobals = await runInBrowser(getGlobalThisProperties, {secureContext: true}); const firefoxGlobals = await runInBrowser(getGlobalThisProperties, {product: 'firefox', secureContext: true}); + const audioWorkletGlobals = await runInAudioWorklet(getGlobalThisProperties); return createGlobals( [ ...chromeGlobals, ...firefoxGlobals, + ...audioWorkletGlobals, ], { shouldExclude,