Skip to content

Commit

Permalink
Save the redundant audio worker code during build time so that the wo…
Browse files Browse the repository at this point in the history
…rker code stays intact and is able to be loaded

The redundant audio worker code string may vary based on the build system of different projects. Because of this, certain build systems will cause invalid worker code to be generated and the redundant audio worker will not be able to run. Now, the redundant audio worker code is saved at build time so that all clients can run the redundant audio worker with the same exact code, regardless of the client's build system.

This issue was originally found in #2771.
  • Loading branch information
dinmin-amzn committed Oct 6, 2023
1 parent 12418f3 commit 3cb7500
Show file tree
Hide file tree
Showing 16 changed files with 1,510 additions and 1,213 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

### Fixed
- Save the redundant audio worker code during build time so that the worker code stays intact and is able to be loaded

## [3.18.1] - 2023-09-29

Expand Down
10 changes: 10 additions & 0 deletions config/tsconfig.red.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"outDir": "../build",
"rootDir": "../src"
},
"include": [
"../src/redundantaudioencoder/RedundantAudioEncoder.ts",
]
}
2,161 changes: 1,088 additions & 1,073 deletions docs/assets/js/search.js

Large diffs are not rendered by default.

64 changes: 32 additions & 32 deletions docs/classes/defaulttransceivercontroller.html

Large diffs are not rendered by default.

213 changes: 213 additions & 0 deletions docs/classes/redundantaudioencoderworkercode.html

Large diffs are not rendered by default.

56 changes: 28 additions & 28 deletions docs/classes/simulcastcontentsharetransceivercontroller.html

Large diffs are not rendered by default.

56 changes: 28 additions & 28 deletions docs/classes/simulcasttransceivercontroller.html

Large diffs are not rendered by default.

60 changes: 30 additions & 30 deletions docs/classes/videoonlytransceivercontroller.html

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions docs/globals.html
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ <h3>Classes</h3>
<li class="tsd-kind-class"><a href="classes/receivevideostreamindextask.html" class="tsd-kind-icon">Receive<wbr>Video<wbr>Stream<wbr>Index<wbr>Task</a></li>
<li class="tsd-kind-class"><a href="classes/reconnectionhealthpolicy.html" class="tsd-kind-icon">Reconnection<wbr>Health<wbr>Policy</a></li>
<li class="tsd-kind-class"><a href="classes/redundantaudioencoder.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder</a></li>
<li class="tsd-kind-class"><a href="classes/redundantaudioencoderworkercode.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder<wbr>Worker<wbr>Code</a></li>
<li class="tsd-kind-class"><a href="classes/redundantaudiorecoverymetricreport.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Recovery<wbr>Metric<wbr>Report</a></li>
<li class="tsd-kind-class tsd-has-type-parameter"><a href="classes/runnabletask.html" class="tsd-kind-icon">Runnable<wbr>Task</a></li>
<li class="tsd-kind-class"><a href="classes/sdp.html" class="tsd-kind-icon">SDP</a></li>
Expand Down Expand Up @@ -1448,6 +1449,9 @@ <h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">device</s
<li class=" tsd-kind-class">
<a href="classes/redundantaudioencoder.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder</a>
</li>
<li class=" tsd-kind-class">
<a href="classes/redundantaudioencoderworkercode.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder<wbr>Worker<wbr>Code</a>
</li>
<li class=" tsd-kind-class">
<a href="classes/redundantaudiorecoverymetricreport.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Recovery<wbr>Metric<wbr>Report</a>
</li>
Expand Down
3 changes: 3 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1831,6 +1831,9 @@ <h2>Notice</h2>
<li class=" tsd-kind-class">
<a href="classes/redundantaudioencoder.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder</a>
</li>
<li class=" tsd-kind-class">
<a href="classes/redundantaudioencoderworkercode.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder<wbr>Worker<wbr>Code</a>
</li>
<li class=" tsd-kind-class">
<a href="classes/redundantaudiorecoverymetricreport.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Recovery<wbr>Metric<wbr>Report</a>
</li>
Expand Down
4 changes: 4 additions & 0 deletions docs/modules.html
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ <h3>Classes</h3>
<li class="tsd-kind-class"><a href="classes/receivevideostreamindextask.html" class="tsd-kind-icon">Receive<wbr>Video<wbr>Stream<wbr>Index<wbr>Task</a></li>
<li class="tsd-kind-class"><a href="classes/reconnectionhealthpolicy.html" class="tsd-kind-icon">Reconnection<wbr>Health<wbr>Policy</a></li>
<li class="tsd-kind-class"><a href="classes/redundantaudioencoder.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder</a></li>
<li class="tsd-kind-class"><a href="classes/redundantaudioencoderworkercode.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder<wbr>Worker<wbr>Code</a></li>
<li class="tsd-kind-class"><a href="classes/redundantaudiorecoverymetricreport.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Recovery<wbr>Metric<wbr>Report</a></li>
<li class="tsd-kind-class tsd-has-type-parameter"><a href="classes/runnabletask.html" class="tsd-kind-icon">Runnable<wbr>Task</a></li>
<li class="tsd-kind-class"><a href="classes/sdp.html" class="tsd-kind-icon">SDP</a></li>
Expand Down Expand Up @@ -1448,6 +1449,9 @@ <h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">device</s
<li class=" tsd-kind-class">
<a href="classes/redundantaudioencoder.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder</a>
</li>
<li class=" tsd-kind-class">
<a href="classes/redundantaudioencoderworkercode.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Encoder<wbr>Worker<wbr>Code</a>
</li>
<li class=" tsd-kind-class">
<a href="classes/redundantaudiorecoverymetricreport.html" class="tsd-kind-icon">Redundant<wbr>Audio<wbr>Recovery<wbr>Metric<wbr>Report</a>
</li>
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
"login": "node script/login.js",
"logout": "node script/logout.js",
"lint": "eslint --config config/eslintrc.json src test --ext .ts,.tsx,.js --fix",
"red": "tsc --build config/tsconfig.red.json && node script/generate-red-worker-code.js",
"tsc:guides": "tsc --build guides/tsconfig.json",
"tsc:watch": "tsc --build --watch config/tsconfig.json",
"tsc:src": "tsc --build config/tsconfig.json",
"build": "node script/barrelize.js && node script/generate-version.js && npm run tsc:src && npm run tsc:guides && npm run copy",
"build": "node script/barrelize.js && node script/generate-version.js && npm run red && npm run tsc:src && npm run tsc:guides && npm run copy",
"prebuild": "ruby script/conditional-install",
"prebuild:release": "node script/check-lockfile-version.js && node script/check-voice-focus-version.js && script/prebuild",
"build:release": "npm run build && npm run lint && npm run check && npm run doc && npm run test:retry",
Expand Down
35 changes: 35 additions & 0 deletions script/generate-red-worker-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env node

/**
* This script takes the transpiled JavaScript code for `RedundantAudioEncoder` and places all of that code into a
* string that can be used to run a worker.
*/

const fs = require('fs');
const RedundantAudioEncoder = require('../build/redundantaudioencoder/RedundantAudioEncoder.js').default;

const debugLine = 'RedundantAudioEncoder.shouldLogDebug = true;';
const withDebug = `${RedundantAudioEncoder.toString().replace(/"/g, '\'').replace(/\n/g, "\\n")}\\n${debugLine}\\nRedundantAudioEncoder.shouldReportStats = true;\\nRedundantAudioEncoder.initializeWorker();`

const workerFileContent = `// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/**
* This file was generated with the \`generate-red-worker-code.js\` script.
*/
export default class RedundantAudioEncoderWorkerCode {
static readonly withDebug =
"${withDebug}";
static readonly withoutDebug = RedundantAudioEncoderWorkerCode.withDebug.replace(
'${debugLine}',
''
);
}
`;

const redDir = './src/redundantaudioencoder';
if (!fs.existsSync(redDir)) fs.mkdirSync(redDir, { recursive: true });

const workerFile = 'RedundantAudioEncoderWorkerCode.ts';
fs.writeFileSync(`${redDir}/${workerFile}`, workerFileContent);
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ import ReceiveVideoStreamIndexTask from './task/ReceiveVideoStreamIndexTask';
import ReconnectController from './reconnectcontroller/ReconnectController';
import ReconnectionHealthPolicy from './connectionhealthpolicy/ReconnectionHealthPolicy';
import RedundantAudioEncoder from './redundantaudioencoder/RedundantAudioEncoder';
import RedundantAudioEncoderWorkerCode from './redundantaudioencoder/RedundantAudioEncoderWorkerCode';
import RedundantAudioRecoveryMetricReport from './clientmetricreport/RedundantAudioRecoveryMetricReport';
import RedundantAudioRecoveryMetricsObserver from './redundantaudiorecoverymetricsobserver/RedundantAudioRecoveryMetricsObserver';
import RemovableAnalyserNode from './devicecontroller/RemovableAnalyserNode';
Expand Down Expand Up @@ -565,6 +566,7 @@ export {
ReconnectController,
ReconnectionHealthPolicy,
RedundantAudioEncoder,
RedundantAudioEncoderWorkerCode,
RedundantAudioRecoveryMetricReport,
RedundantAudioRecoveryMetricsObserver,
RemovableAnalyserNode,
Expand Down
15 changes: 15 additions & 0 deletions src/redundantaudioencoder/RedundantAudioEncoderWorkerCode.ts

Large diffs are not rendered by default.

36 changes: 15 additions & 21 deletions src/transceivercontroller/DefaultTransceiverController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import RedundantAudioRecoveryMetricReport from '../clientmetricreport/RedundantA
import Logger from '../logger/Logger';
import LogLevel from '../logger/LogLevel';
import RedundantAudioEncoder from '../redundantaudioencoder/RedundantAudioEncoder';
import RedundantAudioEncoderWorkerCode from '../redundantaudioencoder/RedundantAudioEncoderWorkerCode';
import RedundantAudioRecoveryMetricsObserver from '../redundantaudiorecoverymetricsobserver/RedundantAudioRecoveryMetricsObserver';
import AsyncScheduler from '../scheduler/AsyncScheduler';
import VideoStreamIdSet from '../videostreamidset/VideoStreamIdSet';
Expand Down Expand Up @@ -474,9 +475,7 @@ export default class DefaultTransceiverController

if (supportsRTCScriptTransform) {
// This is the prefered approach according to
// https://github.com/w3c/webrtc-encoded-transform/blob/main/explainer.md
// but chrome doesn't seem to support it as of chrome 111.0
// Safari 16.3 seems to support this.
// https://github.com/w3c/webrtc-encoded-transform/blob/main/explainer.md.
this.logger.info(
'[AudioRed] Supports encoded insertable streams using RTCRtpScriptTransform'
);
Expand All @@ -493,25 +492,20 @@ export default class DefaultTransceiverController
);
}

// Stringify the `RedundantAudioEncoder` class code and get the new name of the `RedundantAudioEncoder` class since
// its name is changed in the browser.
const redWorkerCode = RedundantAudioEncoder.toString();
const redClassName = redWorkerCode.match(/class\s*(\w+)\s*\{/)[1];

const blobParts: BlobPart[] = [redWorkerCode];
if (this.logger.getLogLevel() === LogLevel.DEBUG) {
blobParts.push(`${redClassName}.shouldLogDebug=1;`);
}
blobParts.push(`${redClassName}.shouldReportStats=1;`);
blobParts.push(`${redClassName}.initializeWorker();`);

this.audioRedWorkerURL = URL.createObjectURL(
new Blob(blobParts, {
type: 'application/javascript',
})
);
this.logger.info(`[AudioRed] Redundant audio worker URL ${this.audioRedWorkerURL}`);
// Run the entire redundant audio worker setup in a `try` block to allow any errors to trigger a reconnect with
// audio redundancy disabled.
try {
let redWorkerCode = RedundantAudioEncoderWorkerCode.withoutDebug;
if (this.logger.getLogLevel() === LogLevel.DEBUG) {
redWorkerCode = RedundantAudioEncoderWorkerCode.withDebug;
}

this.audioRedWorkerURL = URL.createObjectURL(
new Blob([redWorkerCode], {
type: 'application/javascript',
})
);
this.logger.info(`[AudioRed] Redundant audio worker URL ${this.audioRedWorkerURL}`);
this.audioRedWorker = new Worker(this.audioRedWorkerURL);
} catch (error) {
this.logger.error(`[AudioRed] Unable to create audio red worker due to ${error}`);
Expand Down

0 comments on commit 3cb7500

Please sign in to comment.