-
Notifications
You must be signed in to change notification settings - Fork 53
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
VBLOCKS-2214 | Remove unnecessary enumerateDevices calls #199
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,6 @@ import { InvalidArgumentError, NotSupportedError } from './errors'; | |
import Log from './log'; | ||
import OutputDeviceCollection from './outputdevicecollection'; | ||
import MediaDeviceInfoShim from './shims/mediadeviceinfo'; | ||
import getMediaDevicesInstance from './shims/mediadevices'; | ||
import { average, difference, isFirefox } from './util'; | ||
|
||
/** | ||
|
@@ -176,11 +175,11 @@ class AudioHelper extends EventEmitter { | |
}, options); | ||
|
||
this._getUserMedia = getUserMedia; | ||
this._mediaDevices = options.mediaDevices || getMediaDevicesInstance() as AudioHelper.MediaDevicesLike; | ||
this._mediaDevices = options.mediaDevices || navigator.mediaDevices; | ||
this._onActiveInputChanged = onActiveInputChanged; | ||
this._enumerateDevices = typeof options.enumerateDevices === 'function' | ||
? options.enumerateDevices | ||
: this._mediaDevices && this._mediaDevices.enumerateDevices; | ||
: this._mediaDevices && this._mediaDevices.enumerateDevices.bind(this._mediaDevices); | ||
|
||
const isAudioContextSupported: boolean = !!(options.AudioContext || options.audioContext); | ||
const isEnumerationSupported: boolean = !!this._enumerateDevices; | ||
|
@@ -308,10 +307,41 @@ class AudioHelper extends EventEmitter { | |
|
||
if (this._mediaDevices.removeEventListener) { | ||
this._mediaDevices.removeEventListener('devicechange', this._updateAvailableDevices); | ||
this._mediaDevices.removeEventListener('deviceinfochange', this._updateAvailableDevices); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this a browser compatibility thing we no longer need? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
} | ||
} | ||
|
||
/** | ||
* Update the available input and output devices | ||
* @private | ||
*/ | ||
_updateAvailableDevices = (): Promise<void> => { | ||
if (!this._mediaDevices || !this._enumerateDevices) { | ||
return Promise.reject('Enumeration not supported'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to reject an error here, or just a string? Also, could we make this an async function and then use await and throw in the function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was the original implementation and did not see any reason to change it. The only change that was required is to make it an internal-only public API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see. Let's leave it as-is then. |
||
} | ||
|
||
return this._enumerateDevices().then((devices: MediaDeviceInfo[]) => { | ||
this._updateDevices(devices.filter((d: MediaDeviceInfo) => d.kind === 'audiooutput'), | ||
this.availableOutputDevices, | ||
this._removeLostOutput); | ||
|
||
this._updateDevices(devices.filter((d: MediaDeviceInfo) => d.kind === 'audioinput'), | ||
this.availableInputDevices, | ||
this._removeLostInput); | ||
|
||
const defaultDevice = this.availableOutputDevices.get('default') | ||
|| Array.from(this.availableOutputDevices.values())[0]; | ||
|
||
[this.speakerDevices, this.ringtoneDevices].forEach(outputDevices => { | ||
if (!outputDevices.get().size && this.availableOutputDevices.size && this.isOutputSelectionSupported) { | ||
outputDevices.set(defaultDevice.deviceId) | ||
.catch((reason) => { | ||
this._log.warn(`Unable to set audio output devices. ${reason}`); | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
/** | ||
* Enable or disable the disconnect sound. | ||
* @param doEnable Passing `true` will enable the sound and `false` will disable the sound. | ||
|
@@ -426,7 +456,6 @@ class AudioHelper extends EventEmitter { | |
|
||
if (this._mediaDevices.addEventListener) { | ||
this._mediaDevices.addEventListener('devicechange', this._updateAvailableDevices); | ||
this._mediaDevices.addEventListener('deviceinfochange', this._updateAvailableDevices); | ||
} | ||
|
||
this._updateAvailableDevices().then(() => { | ||
|
@@ -542,37 +571,6 @@ class AudioHelper extends EventEmitter { | |
}); | ||
} | ||
|
||
/** | ||
* Update the available input and output devices | ||
*/ | ||
private _updateAvailableDevices = (): Promise<void> => { | ||
if (!this._mediaDevices || !this._enumerateDevices) { | ||
return Promise.reject('Enumeration not supported'); | ||
} | ||
|
||
return this._enumerateDevices().then((devices: MediaDeviceInfo[]) => { | ||
this._updateDevices(devices.filter((d: MediaDeviceInfo) => d.kind === 'audiooutput'), | ||
this.availableOutputDevices, | ||
this._removeLostOutput); | ||
|
||
this._updateDevices(devices.filter((d: MediaDeviceInfo) => d.kind === 'audioinput'), | ||
this.availableInputDevices, | ||
this._removeLostInput); | ||
|
||
const defaultDevice = this.availableOutputDevices.get('default') | ||
|| Array.from(this.availableOutputDevices.values())[0]; | ||
|
||
[this.speakerDevices, this.ringtoneDevices].forEach(outputDevices => { | ||
if (!outputDevices.get().size && this.availableOutputDevices.size && this.isOutputSelectionSupported) { | ||
outputDevices.set(defaultDevice.deviceId) | ||
.catch((reason) => { | ||
this._log.warn(`Unable to set audio output devices. ${reason}`); | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
/** | ||
* Update a set of devices. | ||
* @param updatedDevices - An updated list of available Devices | ||
|
@@ -680,7 +678,6 @@ namespace AudioHelper { | |
* that were lost as a result of this deviceChange event. | ||
* @example `device.audio.on('deviceChange', lostActiveDevices => { })` | ||
* @event | ||
* @private | ||
*/ | ||
declare function deviceChangeEvent(lostActiveDevices: MediaDeviceInfo[]): void; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -939,7 +939,15 @@ class Device extends EventEmitter { | |
|
||
const config: Call.Config = { | ||
audioHelper: this._audio, | ||
getUserMedia: this._options.getUserMedia || getUserMedia, | ||
getUserMedia: (...args) => | ||
(this._options.getUserMedia || getUserMedia)(...args) | ||
.then((gumResponse: any) => { | ||
this._audio?._updateAvailableDevices().catch(error => { | ||
// Ignore error, we don't want to break the call flow | ||
this._log.warn('Unable to updateAvailableDevices after gUM call', error); | ||
}); | ||
return Promise.resolve(gumResponse); | ||
}), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like we're attaching extra responsibility to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did consider it. However, the Call object does not know anything about the audio helper. The Device object has that responsibility. Putting audio helper inside the Call object means, we're now sharing that between Call and Device, which is not necessary. We're not attaching extra responsibility to gUM. The Device is responsible for audio devices, including the sequence of MediaDevice's API calls (gUM, enumerateDevices). This implementation is doing that. Also, no need to call _updateAvailableDevices in other places where we call gUM. We only need it at the start of the call. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we rename the Call configuration parameter from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that might create more confusion. Instead, I changed the implementation to use a callback instead. Please take another look. |
||
isUnifiedPlanDefault: Device._isUnifiedPlanDefault, | ||
onIgnore: (): void => { | ||
this._soundcache.get(Device.SoundName.Incoming).stop(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Love to see us not needing these shims anymore. |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.