Merge pull request #5250 from oswaldoacauan/fix-4690

Remove getUserMedia in the first join as listen only
This commit is contained in:
Anton Georgiev 2018-04-03 13:26:09 -04:00 committed by GitHub
commit 0b03fb5a58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 42 deletions

View File

@ -36,9 +36,9 @@ export default {
init, init,
exitAudio: () => AudioManager.exitAudio(), exitAudio: () => AudioManager.exitAudio(),
transferCall: () => AudioManager.transferCall(), transferCall: () => AudioManager.transferCall(),
joinListenOnly: () => AudioManager.joinAudio({ isListenOnly: true }), joinListenOnly: () => AudioManager.joinListenOnly(),
joinMicrophone: () => AudioManager.joinAudio(), joinMicrophone: () => AudioManager.joinMicrophone(),
joinEchoTest: () => AudioManager.joinAudio({ isEchoTest: true }), joinEchoTest: () => AudioManager.joinEchoTest(),
toggleMuteMicrophone: () => AudioManager.toggleMuteMicrophone(), toggleMuteMicrophone: () => AudioManager.toggleMuteMicrophone(),
changeInputDevice: inputDeviceId => AudioManager.changeInputDevice(inputDeviceId), changeInputDevice: inputDeviceId => AudioManager.changeInputDevice(inputDeviceId),
changeOutputDevice: outputDeviceId => AudioManager.changeOutputDevice(outputDeviceId), changeOutputDevice: outputDeviceId => AudioManager.changeOutputDevice(outputDeviceId),

View File

@ -64,49 +64,99 @@ class AudioManager {
}); });
} }
joinAudio(options = {}) { askDevicesPermissions() {
const { // Only change the isWaitingPermissions for the case where the user didnt allowed it yet
isListenOnly, const permTimeout = setTimeout(() => {
isEchoTest, if (!this.devicesInitialized) { this.isWaitingPermissions = true; }
} = options;
const permissionsTimeout = setTimeout(() => {
this.isWaitingPermissions = true;
}, 100); }, 100);
const doCall = () => { this.isWaitingPermissions = false;
clearTimeout(permissionsTimeout); this.devicesInitialized = false;
this.isWaitingPermissions = false;
this.devicesInitialized = true;
this.isConnecting = true;
this.isMuted = false;
this.error = null;
this.isListenOnly = isListenOnly || false;
this.isEchoTest = isEchoTest || false;
const callOptions = {
isListenOnly: this.isListenOnly,
extension: isEchoTest ? ECHO_TEST_NUMBER : null,
inputStream: this.isListenOnly ? this.createListenOnlyStream() : this.inputStream,
};
return this.bridge.joinAudio(callOptions, this.callStateCallback.bind(this));
};
if (this.devicesInitialized) return doCall();
return Promise.all([ return Promise.all([
this.setDefaultInputDevice(), this.setDefaultInputDevice(),
this.setDefaultOutputDevice(), this.setDefaultOutputDevice(),
]).then(doCall) ]).then(() => {
this.devicesInitialized = true;
this.isWaitingPermissions = false;
}).catch((err) => {
clearTimeout(permTimeout);
this.isConnecting = false;
this.isWaitingPermissions = false;
throw err;
});
}
joinMicrophone() {
this.isListenOnly = false;
this.isEchoTest = false;
const callOptions = {
isListenOnly: false,
extension: null,
inputStream: this.inputStream,
};
return this.askDevicesPermissions()
.then(this.onAudioJoining.bind(this))
.then(() => this.bridge.joinAudio(callOptions, this.callStateCallback.bind(this)));
}
joinEchoTest() {
this.isListenOnly = false;
this.isEchoTest = true;
const callOptions = {
isListenOnly: false,
extension: ECHO_TEST_NUMBER,
inputStream: this.inputStream,
};
return this.askDevicesPermissions()
.then(this.onAudioJoining.bind(this))
.then(() => this.bridge.joinAudio(callOptions, this.callStateCallback.bind(this)));
}
joinListenOnly() {
this.isListenOnly = true;
this.isEchoTest = false;
const callOptions = {
isListenOnly: true,
extension: null,
inputStream: this.createListenOnlyStream(),
};
// We need this until we upgrade to SIP 9x. See #4690
const iceGatheringErr = 'ICE_TIMEOUT';
const iceGatheringTimeout = new Promise((resolve, reject) => {
setTimeout(reject, 12000, iceGatheringErr);
});
return this.onAudioJoining()
.then(() => Promise.race([
this.bridge.joinAudio(callOptions, this.callStateCallback.bind(this)),
iceGatheringTimeout,
]))
.catch((err) => { .catch((err) => {
clearTimeout(permissionsTimeout); // If theres a iceGathering timeout we retry to join after asking device permissions
this.isWaitingPermissions = false; if (err === iceGatheringErr && !this.devicesInitialized) {
this.error = err; return this.askDevicesPermissions()
this.notify(err.message); .then(() => this.joinListenOnly());
return Promise.reject(err); }
throw err;
}); });
} }
onAudioJoining() {
this.isConnecting = true;
this.isMuted = false;
this.error = false;
return Promise.resolve();
}
exitAudio() { exitAudio() {
if (!this.isConnected) return Promise.resolve(); if (!this.isConnected) return Promise.resolve();
@ -128,7 +178,7 @@ class AudioManager {
this.isConnected = true; this.isConnected = true;
// listen to the VoiceUsers changes and update the flag // listen to the VoiceUsers changes and update the flag
if(!this.muteHandle) { if (!this.muteHandle) {
const query = VoiceUsers.find({ intId: Auth.userID }); const query = VoiceUsers.find({ intId: Auth.userID });
this.muteHandle = query.observeChanges({ this.muteHandle = query.observeChanges({
changed: (id, fields) => { changed: (id, fields) => {
@ -153,11 +203,9 @@ class AudioManager {
this.isConnecting = false; this.isConnecting = false;
this.isHangingUp = false; this.isHangingUp = false;
if (!this.error && !this.isEchoTest) { if (!this.error && !this.isEchoTest) {
this.notify(this.messages.info.LEFT_AUDIO); this.notify(this.messages.info.LEFT_AUDIO);
} }
this.isEchoTest = false;
} }
callStateCallback(response) { callStateCallback(response) {
@ -181,7 +229,7 @@ class AudioManager {
this.onAudioExit(); this.onAudioExit();
} else if (status === FAILED) { } else if (status === FAILED) {
this.error = error; this.error = error;
this.notify(this.messages.error[error]); this.notify(this.messages.error[error], true);
console.error('Audio Error:', error, bridgeError); console.error('Audio Error:', error, bridgeError);
this.onAudioExit(); this.onAudioExit();
} }
@ -256,10 +304,10 @@ class AudioManager {
return this._userData; return this._userData;
} }
notify(message) { notify(message, error = false) {
notify( notify(
message, message,
this.error ? 'error' : 'info', error ? 'error' : 'info',
this.isListenOnly ? 'audio_on' : 'unmute', this.isListenOnly ? 'audio_on' : 'unmute',
); );
} }