Handle cases when new media devices are added/removed more precisely and more predictable

This commit is contained in:
Kostiantyn Tsaregradskyi 2016-05-18 14:23:12 +03:00
parent b270256a7a
commit c1807c3649
1 changed files with 47 additions and 15 deletions

View File

@ -22,6 +22,7 @@ const TrackEvents = JitsiMeetJS.events.track;
const TrackErrors = JitsiMeetJS.errors.track;
let room, connection, localAudio, localVideo, roomLocker;
let currentAudioInputDevices, currentVideoInputDevices;
import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/LargeVideo";
@ -197,6 +198,17 @@ function createLocalTracks (devices, cameraDeviceId, micDeviceId) {
});
}
/**
* Stores lists of current 'audioinput' and 'videoinput' devices
* @param {MediaDeviceInfo[]} devices
*/
function setCurrentMediaDevices(devices) {
currentAudioInputDevices = devices.filter(
d => d.kind === 'audioinput');
currentVideoInputDevices = devices.filter(
d => d.kind === 'videoinput');
}
class ConferenceConnector {
constructor(resolve, reject) {
this._resolve = resolve;
@ -408,6 +420,8 @@ export default {
localVideo.getDeviceId());
}
setCurrentMediaDevices(devices);
APP.UI.onAvailableDevicesChanged(devices);
});
@ -419,6 +433,8 @@ export default {
window.setTimeout(() => {
checkLocalDevicesAfterDeviceListChanged(devices)
.then(() => {
setCurrentMediaDevices(devices);
APP.UI.onAvailableDevicesChanged(devices);
});
}, 0);
@ -453,6 +469,12 @@ export default {
}
function checkLocalDevicesAfterDeviceListChanged(newDevices) {
// Event handler can be fire before direct enumerateDevices()
// call, so handle this situation here.
if (!currentAudioInputDevices && !currentVideoInputDevices) {
setCurrentMediaDevices(newDevices);
}
checkAudioOutputDeviceAfterDeviceListChanged(newDevices);
let availableAudioInputDevices = newDevices.filter(
@ -555,39 +577,49 @@ export default {
}
function onTracksCreated(tracks) {
tracks && tracks.forEach(track => {
return Promise.all((tracks || []).map(track => {
if (track.isAudioTrack()) {
self.useAudioStream(track).then(() => {
let audioWasMuted = self.audioMuted;
return self.useAudioStream(track).then(() => {
console.log('switched local audio');
// If we have more than 1 device - mute.
// We check with 2 for audio, because
// it always has 'default' if device is
// available at all.
// TODO: this is not 100% solution - need
// to investigate more
if (availableAudioInputDevices.length > 2) {
// If we plugged-in new device (and switched to
// it), but video was muted before, or we
// unplugged current device and selected new
// one, then mute new video track.
if (audioWasMuted ||
currentAudioInputDevices.length >
availableAudioInputDevices.length) {
muteLocalAudio(true);
}
});
} else if (track.isVideoTrack()) {
self.useVideoStream(track).then(() => {
let videoWasMuted = self.videoMuted;
return self.useVideoStream(track).then(() => {
console.log('switched local video');
// TODO: maybe make video large if we
// are not in conference yet
// If we have more than 1 device - mute.
// TODO: this is not 100% solution - need
// to investigate more
if (availableVideoInputDevices.length > 1) {
// If we plugged-in new device (and switched to
// it), but video was muted before, or we
// unplugged current device and selected new
// one, then mute new video track.
if (videoWasMuted ||
(currentVideoInputDevices.length >
availableVideoInputDevices.length)) {
muteLocalVideo(true);
}
});
} else {
console.error("Ignored not an audio nor a "
+ "video track: ", track);
return Promise.resolve();
}
});
}));
}
}
});