Merge pull request #8888 from pedrobmarin/fix-mod-webcams

Fix webcamsOnlyForModerator
This commit is contained in:
Anton Georgiev 2020-06-30 16:19:15 -04:00 committed by GitHub
commit ec94b0f781
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 18 deletions

View File

@ -234,6 +234,8 @@ class VideoPreview extends Component {
const webcams = []; const webcams = [];
let initialDeviceId; let initialDeviceId;
VideoService.updateNumberOfDevices(devices);
if (!this._isMounted) return; if (!this._isMounted) return;
// set webcam // set webcam

View File

@ -19,6 +19,7 @@ const SKIP_VIDEO_PREVIEW = Meteor.settings.public.kurento.skipVideoPreview;
const SFU_URL = Meteor.settings.public.kurento.wsUrl; const SFU_URL = Meteor.settings.public.kurento.wsUrl;
const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator; const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator;
const ROLE_VIEWER = Meteor.settings.public.user.role_viewer;
const ENABLE_NETWORK_MONITORING = Meteor.settings.public.networkMonitoring.enableNetworkMonitoring; const ENABLE_NETWORK_MONITORING = Meteor.settings.public.networkMonitoring.enableNetworkMonitoring;
const TOKEN = '_'; const TOKEN = '_';
@ -29,11 +30,8 @@ class VideoService {
isConnecting: false, isConnecting: false,
isConnected: false, isConnected: false,
}); });
this.skipVideoPreview = getFromUserSettings('bbb_skip_video_preview', false) || SKIP_VIDEO_PREVIEW; this.skipVideoPreview = null;
this.userParameterProfile = getFromUserSettings( this.userParameterProfile = null;
'bbb_preferred_camera_profile',
(CAMERA_PROFILES.filter(i => i.default) || {}).id,
);
const BROWSER_RESULTS = browser(); const BROWSER_RESULTS = browser();
this.isMobile = BROWSER_RESULTS.mobile || BROWSER_RESULTS.os.includes('Android'); this.isMobile = BROWSER_RESULTS.mobile || BROWSER_RESULTS.os.includes('Android');
this.isSafari = BROWSER_RESULTS.name === 'safari'; this.isSafari = BROWSER_RESULTS.name === 'safari';
@ -72,16 +70,26 @@ class VideoService {
}); });
} }
updateNumberOfDevices() { fetchNumberOfDevices(devices) {
navigator.mediaDevices.enumerateDevices().then((devices) => { const deviceIds = [];
const deviceIds = []; devices.forEach(d => {
devices.forEach((d) => { const validDeviceId = d.deviceId !== '' && !deviceIds.includes(d.deviceId)
if (d.kind === 'videoinput' && !deviceIds.includes(d.deviceId)) { if (d.kind === 'videoinput' && validDeviceId) {
deviceIds.push(d.deviceId); deviceIds.push(d.deviceId);
} }
});
this.numberOfDevices = deviceIds.length;
}); });
return deviceIds.length;
}
updateNumberOfDevices(devices = null) {
if (devices) {
this.numberOfDevices = this.fetchNumberOfDevices(devices);
} else {
navigator.mediaDevices.enumerateDevices().then(devices => {
this.numberOfDevices = this.fetchNumberOfDevices(devices);
});
}
} }
joinVideo(deviceId) { joinVideo(deviceId) {
@ -154,7 +162,7 @@ class VideoService {
} }
getVideoStreams() { getVideoStreams() {
const streams = VideoStreams.find( let streams = VideoStreams.find(
{ meetingId: Auth.meetingID }, { meetingId: Auth.meetingID },
{ {
fields: { fields: {
@ -163,8 +171,11 @@ class VideoService {
}, },
).fetch(); ).fetch();
const connectingStream = this.getConnectingStream(streams); const hideUsers = this.hideUserList();
const moderatorOnly = this.webcamsOnlyForModerator();
if (hideUsers || moderatorOnly) streams = this.filterModeratorOnly(streams);
const connectingStream = this.getConnectingStream(streams);
if (connectingStream) streams.push(connectingStream); if (connectingStream) streams.push(connectingStream);
return streams.map(vs => ({ return streams.map(vs => ({
@ -215,12 +226,46 @@ class VideoService {
return streams.find(s => s.stream === stream); return streams.find(s => s.stream === stream);
} }
filterModeratorOnly(streams) {
const me = Users.findOne({ userId: Auth.userID });
const amIViewer = me.role === ROLE_VIEWER;
if (amIViewer) {
const moderators = Users.find(
{
meetingId: Auth.meetingID,
connectionStatus: 'online',
role: ROLE_MODERATOR,
},
{ fields: { userId: 1 } },
).fetch().map(user => user.userId);
return streams.reduce((result, stream) => {
const { userId } = stream;
const isModerator = moderators.includes(userId);
const isMe = me.userId === userId;
if (isModerator || isMe) result.push(stream);
return result;
}, []);
}
return streams;
}
disableCam() { disableCam() {
const m = Meetings.findOne({ meetingId: Auth.meetingID }, const m = Meetings.findOne({ meetingId: Auth.meetingID },
{ fields: { 'lockSettingsProps.disableCam': 1 } }); { fields: { 'lockSettingsProps.disableCam': 1 } });
return m.lockSettingsProps ? m.lockSettingsProps.disableCam : false; return m.lockSettingsProps ? m.lockSettingsProps.disableCam : false;
} }
webcamsOnlyForModerator() {
const m = Meetings.findOne({ meetingId: Auth.meetingID },
{ fields: { 'usersProp.webcamsOnlyForModerator': 1 } });
return m.usersProp ? m.usersProp.webcamsOnlyForModerator : false;
}
hideUserList() { hideUserList() {
const m = Meetings.findOne({ meetingId: Auth.meetingID }, const m = Meetings.findOne({ meetingId: Auth.meetingID },
{ fields: { 'lockSettingsProps.hideUserList': 1 } }); { fields: { 'lockSettingsProps.hideUserList': 1 } });
@ -329,11 +374,22 @@ class VideoService {
return isLocal ? 'share' : 'viewer'; return isLocal ? 'share' : 'viewer';
} }
getSkipVideoPreview(fromInterface) { getSkipVideoPreview(fromInterface = false) {
if (this.skipVideoPreview === null) {
this.skipVideoPreview = getFromUserSettings('bbb_skip_video_preview', false) || SKIP_VIDEO_PREVIEW;
}
return this.skipVideoPreview && !fromInterface; return this.skipVideoPreview && !fromInterface;
} }
getUserParameterProfile() { getUserParameterProfile() {
if (this.userParameterProfile === null) {
this.userParameterProfile = getFromUserSettings(
'bbb_preferred_camera_profile',
(CAMERA_PROFILES.filter(i => i.default) || {}).id,
);
}
return this.userParameterProfile; return this.userParameterProfile;
} }
@ -342,7 +398,7 @@ class VideoService {
// Mobile shouldn't be able to share more than one camera at the same time // Mobile shouldn't be able to share more than one camera at the same time
// Safari needs to implement devicechange event for safe device control // Safari needs to implement devicechange event for safe device control
return MULTIPLE_CAMERAS return MULTIPLE_CAMERAS
&& !this.skipVideoPreview && !this.getSkipVideoPreview()
&& !this.isMobile && !this.isMobile
&& !this.isSafari && !this.isSafari
&& this.numberOfDevices > 1; && this.numberOfDevices > 1;
@ -380,4 +436,5 @@ export default {
monitor: conn => videoService.monitor(conn), monitor: conn => videoService.monitor(conn),
onBeforeUnload: () => videoService.onBeforeUnload(), onBeforeUnload: () => videoService.onBeforeUnload(),
notify: message => notify(message, 'error', 'video'), notify: message => notify(message, 'error', 'video'),
updateNumberOfDevices: devices => videoService.updateNumberOfDevices(devices),
}; };