Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reuse audio context #3379

Draft
wants to merge 8 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class AudioSinkManager {
*/
async unblockAutoplay() {
if (this.autoPausedTracks.size > 0) {
this.unpauseAudioTracks();
await this.unpauseAudioTracks();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,13 @@ import AnalyticsEventFactory from '../../analytics/AnalyticsEventFactory';
import { ErrorFactory } from '../../error/ErrorFactory';
import { HMSAction } from '../../error/HMSAction';
import { EventBus } from '../../events/EventBus';
import { HMSAudioContextHandler } from '../../internal';
import { HMSLocalAudioTrack } from '../../media/tracks';
import Room from '../../sdk/models/HMSRoom';
import HMSLogger from '../../utils/logger';

const DEFAULT_SAMPLE_RATE = 48000;

//Handling sample rate error in case of firefox
const checkBrowserSupport = () => {
return navigator.userAgent.indexOf('Firefox') !== -1;
};

/**
* This class manages applying different plugins on a local audio track. Plugins which need to modify the audio
* are called in the order they were added. Plugins which do not need to modify the audio are called
Expand Down Expand Up @@ -48,7 +44,7 @@ export class HMSAudioPluginsManager {
this.hmsTrack = track;
this.pluginsMap = new Map();
this.analytics = new AudioPluginsAnalytics(eventBus);
this.createAudioContext();
this.audioContext = HMSAudioContextHandler.getAudioContext({ sampleRate: DEFAULT_SAMPLE_RATE });
this.room = room;
}

Expand Down Expand Up @@ -214,7 +210,7 @@ export class HMSAudioPluginsManager {
for (const plugin of plugins) {
await this.addPlugin(plugin);
}
this.updateProcessedTrack();
await this.updateProcessedTrack();
}

private async initAudioNodes() {
Expand Down Expand Up @@ -282,19 +278,4 @@ export class HMSAudioPluginsManager {
plugin.stop();
this.analytics.removed(name);
}

private createAudioContext() {
if (!this.audioContext) {
if (checkBrowserSupport()) {
/**
Not setting default sample rate for firefox since connecting
audio nodes from context with different sample rate is not
supported in firefox
*/
this.audioContext = new AudioContext();
} else {
this.audioContext = new AudioContext({ sampleRate: DEFAULT_SAMPLE_RATE });
}
}
}
}
35 changes: 20 additions & 15 deletions packages/hms-video-store/src/reactive-store/HMSSDKActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1534,24 +1534,29 @@ export class HMSSDKActions<T extends HMSGenericTypes = { sessionStore: Record<st
}
}

//eslint-disable-next-line complexity
private async addRemoveAudioPlugin(plugin: HMSAudioPlugin, action: 'add' | 'remove') {
if (!plugin) {
HMSLogger.w('Invalid plugin received in store');
return;
}
const trackID = this.store.getState(selectLocalAudioTrackID);
if (trackID) {
const sdkTrack = this.getLocalTrack(trackID);
if (sdkTrack) {
if (action === 'add') {
await (sdkTrack as SDKHMSLocalAudioTrack).addPlugin(plugin);
} else if (action === 'remove') {
await (sdkTrack as SDKHMSLocalAudioTrack).removePlugin(plugin);
try {
if (!plugin) {
HMSLogger.w('Invalid plugin received in store');
return;
}
const trackID = this.store.getState(selectLocalAudioTrackID);
if (trackID) {
const sdkTrack = this.getLocalTrack(trackID);
if (sdkTrack) {
if (action === 'add') {
await (sdkTrack as SDKHMSLocalAudioTrack).addPlugin(plugin);
} else if (action === 'remove') {
await (sdkTrack as SDKHMSLocalAudioTrack).removePlugin(plugin);
}
this.syncRoomState(`${action}AudioPlugin`);
} else {
this.logPossibleInconsistency(`track ${trackID} not present, unable to ${action} plugin`);
}
this.syncRoomState(`${action}AudioPlugin`);
} else {
this.logPossibleInconsistency(`track ${trackID} not present, unable to ${action} plugin`);
}
} catch (err) {
console.error(err);
}
}

Expand Down
20 changes: 15 additions & 5 deletions packages/hms-video-store/src/utils/media.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import HMSLogger from './logger';
import { isFirefox } from './support';
import { BuildGetMediaError } from '../error/utils';
import { HMSTrackExceptionTrackType } from '../media/tracks/HMSTrackExceptionTrackType';

Expand Down Expand Up @@ -44,17 +45,26 @@ export async function getLocalDevices(): Promise<MediaDeviceGroups> {

export interface HMSAudioContext {
audioContext: AudioContext | null;
getAudioContext: () => AudioContext;
getAudioContext: (options?: AudioContextOptions) => AudioContext;
resumeContext: () => Promise<void>;
}

export const HMSAudioContextHandler: HMSAudioContext = {
audioContext: null,
getAudioContext() {
if (!this.audioContext) {
this.audioContext = new AudioContext();
getAudioContext(options?: AudioContextOptions) {
const newAudioContextNeeded =
!this.audioContext || (options?.sampleRate && this.audioContext.sampleRate !== options.sampleRate);

if (newAudioContextNeeded) {
/**
* Not setting default sample rate for firefox since connecting
* audio nodes from context with different sample rate is not
* supported in firefox
*/
this.audioContext = isFirefox ? new AudioContext() : new AudioContext(options);
}
return this.audioContext;

return this.audioContext!;
},
async resumeContext() {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export function AutoplayBlockedModal() {
return (
<Dialog.Root
open={!!error}
onOpenChange={value => {
onOpenChange={async value => {
if (!value) {
unblockAudio();
await unblockAudio();
}
resetError();
}}
Expand All @@ -25,8 +25,8 @@ export function AutoplayBlockedModal() {
<DialogRow justify="end">
<Button
variant="primary"
onClick={() => {
unblockAudio();
onClick={async () => {
await unblockAudio();
resetError();
}}
>
Expand Down