From 5855930221203679b5755866f98144b4969862a5 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 13 Nov 2023 19:52:15 +0100 Subject: [PATCH] Extra worklet module loading and mock it in tests --- jest.config.ts | 2 +- src/audio/VoiceRecording.ts | 13 ++----------- src/audio/recorderWorkletFactory.ts | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 src/audio/recorderWorkletFactory.ts diff --git a/jest.config.ts b/jest.config.ts index 3e282958aa..4c62324bcc 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -33,7 +33,7 @@ const config: Config = { "waveWorker\\.min\\.js": "/__mocks__/empty.js", "workers/(.+)Factory": "/__mocks__/workerFactoryMock.js", "^!!raw-loader!.*": "jest-raw-loader", - "RecorderWorklet": "/__mocks__/empty.js", + "recorderWorkletFactory": "/__mocks__/empty.js", }, transformIgnorePatterns: ["/node_modules/(?!matrix-js-sdk).+$"], collectCoverageFrom: [ diff --git a/src/audio/VoiceRecording.ts b/src/audio/VoiceRecording.ts index 53656c1a34..9f12dc33f7 100644 --- a/src/audio/VoiceRecording.ts +++ b/src/audio/VoiceRecording.ts @@ -28,11 +28,7 @@ import { UPDATE_EVENT } from "../stores/AsyncStore"; import { createAudioContext } from "./compat"; import { FixedRollingArray } from "../utils/FixedRollingArray"; import { clamp } from "../utils/numbers"; -// This import is needed for dead code analysis but not actually used because the -// built-in worker / worklet handling in Webpack 5 only supports static paths -// @ts-ignore no-unused-locals -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import mxRecorderWorkletPath from "./RecorderWorklet"; +import recorderWorkletFactory from "./recorderWorkletFactory"; const CHANNELS = 1; // stereo isn't important export const SAMPLE_RATE = 48000; // 48khz is what WebRTC uses. 12khz is where we lose quality. @@ -133,12 +129,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable { if (this.recorderContext.audioWorklet) { // Set up our worklet. We use this for timing information and waveform analysis: the // web audio API prefers this be done async to avoid holding the main thread with math. - - // The audioWorklet.addModule syntax is required for Webpack 5 to correctly recognise - // this as a worklet rather than an asset. This also requires the parser.javascript.worker - // configuration described in https://github.com/webpack/webpack.js.org/issues/6869. - const audioWorklet = this.recorderContext.audioWorklet; - await audioWorklet.addModule(new URL("./RecorderWorklet.ts", import.meta.url)); + await recorderWorkletFactory(this.recorderContext); this.recorderWorklet = new AudioWorkletNode(this.recorderContext, WORKLET_NAME); this.recorderSource.connect(this.recorderWorklet); diff --git a/src/audio/recorderWorkletFactory.ts b/src/audio/recorderWorkletFactory.ts new file mode 100644 index 0000000000..697d8bd7d2 --- /dev/null +++ b/src/audio/recorderWorkletFactory.ts @@ -0,0 +1,28 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +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. +*/ + +// This import is needed for dead code analysis but not actually used because the +// built-in worker / worklet handling in Webpack 5 only supports static paths +// @ts-ignore no-unused-locals +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import mxRecorderWorkletPath from "./RecorderWorklet"; + +export default function recorderWorkletFactory(context: AudioContext): Promise { + // The context.audioWorklet.addModule syntax is required for Webpack 5 to correctly recognise + // this as a worklet rather than an asset. This also requires the parser.javascript.worker + // configuration described in https://github.com/webpack/webpack.js.org/issues/6869. + return context.audioWorklet.addModule(new URL("./RecorderWorklet.ts", import.meta.url)); +}