Fire an optional JitsiMediaDevices.PERMISSION_PROMPT_IS_SHOWN event when browser shows user media permission prompt when calling createLocalTracks

This commit is contained in:
tsareg 2016-06-24 12:47:13 +03:00
parent 8ca282079a
commit d149ba6fc5
5 changed files with 99 additions and 74 deletions

View File

@ -27,8 +27,6 @@ let room, connection, localAudio, localVideo, roomLocker;
import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/LargeVideo";
const USER_MEDIA_PERMISSIONS_GUIDANCE_OVERLAY_TIMEOUT = 500;
/**
* Known custom conference commands.
*/
@ -68,32 +66,26 @@ function connect(roomName) {
*/
function createInitialLocalTracksAndConnect(roomName) {
let audioAndVideoError,
audioOnlyError,
tracksCreated;
audioOnlyError;
JitsiMeetJS.mediaDevices.addEventListener(
JitsiMeetJS.events.mediaDevices.PERMISSION_PROMPT_IS_SHOWN,
browser => APP.UI.showUserMediaPermissionsGuidanceOverlay(browser));
// First try to retrieve both audio and video.
let tryCreateLocalTracks = createLocalTracks(['audio', 'video'])
let tryCreateLocalTracks = createLocalTracks(
{ devices: ['audio', 'video'] }, true)
.catch(err => {
// If failed then try to retrieve only audio.
audioAndVideoError = err;
return createLocalTracks(['audio']);
return createLocalTracks({ devices: ['audio'] }, true);
})
.catch(err => {
// If audio failed too then just return empty array for tracks.
audioOnlyError = err;
return [];
})
.then(tracks => {
tracksCreated = true;
return tracks;
});
window.setTimeout(() => {
if (!audioAndVideoError && !audioOnlyError && !tracksCreated) {
APP.UI.showUserMediaPermissionsGuidanceOverlay();
}
}, USER_MEDIA_PERMISSIONS_GUIDANCE_OVERLAY_TIMEOUT);
return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
.then(([tracks, con]) => {
APP.UI.hideUserMediaPermissionsGuidanceOverlay();
@ -245,32 +237,42 @@ function hangup (requestFeedback = false) {
/**
* Create local tracks of specified types.
* @param {string[]} devices - required track types ('audio', 'video' etc.)
* @param {string|null} [cameraDeviceId] - camera device id, if undefined - one
* from settings will be used
* @param {string|null} [micDeviceId] - microphone device id, if undefined - one
* from settings will be used
* @param {Object} options
* @param {string[]} options.devices - required track types
* ('audio', 'video' etc.)
* @param {string|null} (options.cameraDeviceId) - camera device id, if
* undefined - one from settings will be used
* @param {string|null} (options.micDeviceId) - microphone device id, if
* undefined - one from settings will be used
* @param {boolean} (checkForPermissionPrompt) - if lib-jitsi-meet should check
* for gUM permission prompt
* @returns {Promise<JitsiLocalTrack[]>}
*/
function createLocalTracks (devices, cameraDeviceId, micDeviceId) {
return JitsiMeetJS.createLocalTracks({
function createLocalTracks (options, checkForPermissionPrompt) {
options || (options = {});
return JitsiMeetJS
.createLocalTracks({
// copy array to avoid mutations inside library
devices: devices.slice(0),
devices: options.devices.slice(0),
resolution: config.resolution,
cameraDeviceId: typeof cameraDeviceId === 'undefined'
|| cameraDeviceId === null
cameraDeviceId: typeof options.cameraDeviceId === 'undefined' ||
options.cameraDeviceId === null
? APP.settings.getCameraDeviceId()
: cameraDeviceId,
micDeviceId: typeof micDeviceId === 'undefined' || micDeviceId === null
: options.cameraDeviceId,
micDeviceId: typeof options.micDeviceId === 'undefined' ||
options.micDeviceId === null
? APP.settings.getMicDeviceId()
: micDeviceId,
: options.micDeviceId,
// adds any ff fake device settings if any
firefox_fake_device: config.firefox_fake_device
}).catch(function (err) {
console.error('failed to create local tracks', ...devices, err);
}, checkForPermissionPrompt)
.catch(function (err) {
console.error(
'failed to create local tracks', options.devices, err);
return Promise.reject(err);
});
}
}
/**
* Changes the email for the local user
@ -861,7 +863,7 @@ export default {
this.videoSwitchInProgress = true;
if (shareScreen) {
createLocalTracks(['desktop']).then(([stream]) => {
createLocalTracks({ devices: ['desktop'] }).then(([stream]) => {
stream.on(
TrackEvents.LOCAL_TRACK_STOPPED,
() => {
@ -918,7 +920,7 @@ export default {
APP.UI.messageHandler.openDialog(dialogTitle, dialogTxt, false);
});
} else {
createLocalTracks(['video']).then(
createLocalTracks({ devices: ['video'] }).then(
([stream]) => this.useVideoStream(stream)
).then(() => {
this.videoSwitchInProgress = false;
@ -1260,7 +1262,11 @@ export default {
APP.UI.addListener(
UIEvents.VIDEO_DEVICE_CHANGED,
(cameraDeviceId) => {
createLocalTracks(['video'], cameraDeviceId, null)
createLocalTracks({
devices: ['video'],
cameraDeviceId: cameraDeviceId,
micDeviceId: null
})
.then(([stream]) => {
this.useVideoStream(stream);
console.log('switched local video device');
@ -1276,7 +1282,11 @@ export default {
APP.UI.addListener(
UIEvents.AUDIO_DEVICE_CHANGED,
(micDeviceId) => {
createLocalTracks(['audio'], null, micDeviceId)
createLocalTracks({
devices: ['audio'],
cameraDeviceId: null,
micDeviceId: micDeviceId
})
.then(([stream]) => {
this.useAudioStream(stream);
console.log('switched local audio device');

View File

@ -14,6 +14,7 @@
"userMedia": {
"react-nativeGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
"chromeGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
"androidGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
"firefoxGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Share Selected Device</i> button",
"operaGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
"iexplorerGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>OK</i> button",

View File

@ -1388,9 +1388,11 @@ UI.hideRingOverLay = function () {
/**
* Shows browser-specific overlay with guidance how to proceed with gUM prompt.
* @param {string} browser - name of browser for which to show the guidance
* overlay.
*/
UI.showUserMediaPermissionsGuidanceOverlay = function () {
GumPermissionsOverlay.show();
UI.showUserMediaPermissionsGuidanceOverlay = function (browser) {
GumPermissionsOverlay.show(browser);
};
/**

View File

@ -5,11 +5,10 @@ let $overlay;
/**
* Internal function that constructs overlay with guidance how to proceed with
* gUM prompt.
* @param {string} browser - name of browser for which to construct the
* guidance overlay.
*/
function buildOverlayHtml() {
let browser = JitsiMeetJS.environment.getBrowserType()
.split('rtc_browser.')[1] || 'chrome';
function buildOverlayHtml(browser) {
$overlay = $(`
<div class='overlay_container'>
<div class='overlay overlay_transparent' />
@ -28,11 +27,13 @@ export default {
/**
* Shows browser-specific overlay with guidance how to proceed with
* gUM prompt.
* @param {string} browser - name of browser for which to show the
* guidance overlay.
*/
show() {
!$overlay && buildOverlayHtml();
show(browser) {
!$overlay && buildOverlayHtml(browser);
$overlay && $overlay.appendTo('body');
!$overlay.parents('body').length && $overlay.appendTo('body');
},
/**

View File

@ -191,8 +191,11 @@ export default {
if (audioRequested && videoRequested) {
// First we try to create both audio and video tracks together.
return createLocalTracks(
['audio', 'video'], cameraDeviceId, micDeviceId)
return createLocalTracks({
devices: ['audio', 'video'],
cameraDeviceId: cameraDeviceId,
micDeviceId: micDeviceId
})
// If we fail to do this, try to create them separately.
.catch(() => Promise.all(
[createAudioTrack(false), createVideoTrack(false)]))
@ -213,7 +216,11 @@ export default {
}
function createAudioTrack(showError) {
return createLocalTracks(['audio'], null, micDeviceId)
return createLocalTracks({
devices: ['audio'],
cameraDeviceId: null,
micDeviceId: micDeviceId
})
.catch(err => {
audioTrackError = err;
showError && APP.UI.showDeviceErrorDialog(err, null);
@ -222,7 +229,11 @@ export default {
}
function createVideoTrack(showError) {
return createLocalTracks(['video'], cameraDeviceId, null)
return createLocalTracks({
devices: ['video'],
cameraDeviceId: cameraDeviceId,
micDeviceId: null
})
.catch(err => {
videoTrackError = err;
showError && APP.UI.showDeviceErrorDialog(null, err);