Remove the support for iframe postMessage API (recording and self-muting)

This commit is contained in:
Maxim Khlobystov 2021-11-29 22:53:12 +00:00
parent 5664883b68
commit b7cf670aec
10 changed files with 0 additions and 345 deletions

View File

@ -1,243 +0,0 @@
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2018 by respective authors (see below). All rights reserved.
BigBlueButton is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
Authors: James Jung
Anton Georgiev
-->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Join Meeting via HTML5 Client (API)</title>
<style>
#controls {
width:50%;
height:200px;
float:left;
}
#client {
width:100%;
height:700px;
float:left;
}
#client-content {
width:100%;
height:100%;
}
</style>
</head>
<body>
<p>You must have the BigBlueButton HTML5 client installed to use this API demo.</p>
<%@ include file="bbb_api.jsp"%>
<%
if (request.getParameterMap().isEmpty()) {
//
// Assume we want to create a meeting
//
%>
<%@ include file="demo_header.jsp"%>
<h2>Join Meeting via HTML5 Client (API)</h2>
<FORM NAME="form1" METHOD="GET">
<table cellpadding="5" cellspacing="5" style="width: 400px; ">
<tbody>
<tr>
<td>&nbsp;</td>
<td style="text-align: right; ">Full Name:</td>
<td style="width: 5px; ">&nbsp;</td>
<td style="text-align: left "><input type="text" autofocus required name="username" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td style="text-align: right; ">Meeting Name:</td>
<td style="width: 5px; ">&nbsp;</td>
<td style="text-align: left "><input type="text" required name="meetingname" value="Demo Meeting" /></td>
<tr>
<tr>
<td>&nbsp;</td>
<td style="text-align: right; ">Moderator Role:</td>
<td style="width: 5px; ">&nbsp;</td>
<td style="text-align: left "><input type=checkbox name=isModerator value="true" checked></td>
<tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="submit" value="Join" /></td>
<tr>
</tbody>
</table>
<INPUT TYPE=hidden NAME=action VALUE="create">
</FORM>
<%
} else if (request.getParameter("action").equals("create")) {
String username = request.getParameter("username");
// set defaults and overwrite them if custom values exist
String meetingname = "Demo Meeting";
if (request.getParameter("meetingname") != null) {
meetingname = request.getParameter("meetingname");
}
Boolean isModerator = new Boolean(false);
Boolean isHTML5 = new Boolean(true);
Boolean isRecorded = new Boolean(true);
if (request.getParameter("isModerator") != null) {
isModerator = Boolean.parseBoolean(request.getParameter("isModerator"));
}
String joinURL = getJoinURLExtended(username, meetingname, isRecorded.toString(), null, null, null, isHTML5.toString(), isModerator.toString());
if (joinURL.startsWith("http://") || joinURL.startsWith("https://")) {
%>
<script language="javascript" type="text/javascript">
const recButton = document.createElement('button');
recButton.id = 'recButton';
const muteButton = document.createElement('button');
muteButton.id = 'muteButton';
function getInitialState() {
document.getElementById('client-content').contentWindow.postMessage('c_recording_status', '*');
document.getElementById('client-content').contentWindow.postMessage('get_audio_joined_status', '*');
}
function handleMessage(e) {
switch (e) {
case 'readyToConnect': {
// get initial state
getInitialState(); break; }
case 'recordingStarted': {
recButton.innerHTML = 'Stop Recording';
break;
}
case 'recordingStopped': {
recButton.innerHTML = 'Start Recording';
break;
}
case 'selfMuted': {
muteButton.innerHTML = 'Unmute me';
break;
}
case 'selfUnmuted': {
muteButton.innerHTML = 'Mute me';
break;
}
case 'notInAudio': {
muteButton.innerHTML = 'Not in audio';
document.getElementById('muteButton').disabled = true;
break;
}
case 'joinedAudio': {
muteButton.innerHTML = '';
document.getElementById('muteButton').disabled = false;
document.getElementById('client-content').contentWindow.postMessage('c_mute_status', '*');
break;
}
default: console.log('neither', { e });
}
}
// EventListener(Getting message from iframe)
window.addEventListener('message', function(e) {
handleMessage(e.data.response);
});
// Clean up the body node before loading controls and the client
document.body.innerHTML = '';
// Node for the Client
const client = document.createElement('div');
client.setAttribute('id', 'client');
const clientContent = document.createElement('iframe');
clientContent.setAttribute('id', 'client-content');
clientContent.setAttribute('src','<%=joinURL%>');
// // in case your iframe is on a different domain MYDOMAIN.com
// clientContent.setAttribute('src','https://MYDOMAIN.com/demo/demoHTML5.jsp');
// to enable microphone or camera use allow your iframe domain explicitly
// clientContent.setAttribute('allow','microphone https://MYDOMAIN.com; camera https://MYDOMAIN.com');
client.appendChild(clientContent);
// Node for the Controls
const controls = document.createElement('div');
controls.setAttribute('id', 'controls');
controls.setAttribute('align', 'middle');
controls.setAttribute('float', 'left');
// ****************** Controls *****************************/
function recToggle(){
document.getElementById("client-content").contentWindow.postMessage('c_record', '*');
}
function muteToggle(){
document.getElementById("client-content").contentWindow.postMessage('c_mute', '*');
}
// Node for the control which controls recording functionality of the html5Client
recButton.setAttribute('onClick', 'recToggle();');
controls.appendChild(recButton);
muteButton.setAttribute('onClick', 'muteToggle();');
controls.appendChild(muteButton);
// Append the nodes of contents to the body node
document.body.appendChild(controls);
document.body.appendChild(client);
</script>
<%
} else {
%>
Error: getJoinURL() failed
<p/>
<%=joinURL %>
<%
}
}
%>
<%@ include file="demo_footer.jsp"%>
</body>
</html>

View File

@ -19,8 +19,6 @@ const oldParameters = {
listenOnlyMode: 'bbb_listen_only_mode',
multiUserPenOnly: 'bbb_multi_user_pen_only',
multiUserTools: 'bbb_multi_user_tools',
outsideToggleRecording: 'bbb_outside_toggle_recording',
outsideToggleSelfVoice: 'bbb_outside_toggle_self_voice',
presenterTools: 'bbb_presenter_tools',
shortcuts: 'bbb_shortcuts',
skipCheck: 'bbb_skip_check_audio',
@ -67,9 +65,6 @@ const currentParameters = [
'bbb_show_public_chat_on_login',
'bbb_hide_actions_bar',
'bbb_hide_nav_bar',
// OUTSIDE COMMANDS
'bbb_outside_toggle_self_voice',
'bbb_outside_toggle_recording',
];
function valueParser(val) {

View File

@ -30,7 +30,6 @@ const intlMessages = defineMessages({
const propTypes = {
shortcuts: PropTypes.objectOf(PropTypes.string).isRequired,
processToggleMuteFromOutside: PropTypes.func.isRequired,
handleToggleMuteMicrophone: PropTypes.func.isRequired,
handleJoinAudio: PropTypes.func.isRequired,
handleLeaveAudio: PropTypes.func.isRequired,
@ -54,14 +53,6 @@ class AudioControls extends PureComponent {
this.renderJoinLeaveButton = this.renderJoinLeaveButton.bind(this);
}
componentDidMount() {
const { processToggleMuteFromOutside } = this.props;
if (Meteor.settings.public.allowOutsideCommands.toggleSelfVoice
|| getFromUserSettings('bbb_outside_toggle_self_voice', false)) {
window.addEventListener('message', processToggleMuteFromOutside);
}
}
renderJoinButton() {
const {
handleJoinAudio,

View File

@ -2,7 +2,6 @@ import React from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import { withModalMounter } from '/imports/ui/components/modal/service';
import AudioManager from '/imports/ui/services/audio-manager';
import { makeCall } from '/imports/ui/services/api';
import lockContextContainer from '/imports/ui/components/lock-viewers/context/container';
import { withUsersConsumer } from '/imports/ui/components/components-data/users-context/context';
import logger from '/imports/startup/client/logger';
@ -29,28 +28,6 @@ const AudioControlsContainer = (props) => {
return <AudioControls {...newProps} />;
};
const processToggleMuteFromOutside = (e) => {
switch (e.data) {
case 'c_mute': {
makeCall('toggleVoice');
break;
}
case 'get_audio_joined_status': {
const audioJoinedState = AudioManager.isConnected ? 'joinedAudio' : 'notInAudio';
this.window.parent.postMessage({ response: audioJoinedState }, '*');
break;
}
case 'c_mute_status': {
const muteState = AudioManager.isMuted ? 'selfMuted' : 'selfUnmuted';
this.window.parent.postMessage({ response: muteState }, '*');
break;
}
default: {
// console.log(e.data);
}
}
};
const handleLeaveAudio = () => {
const meetingIsBreakout = AppService.meetingIsBreakout();
@ -100,7 +77,6 @@ export default withUsersConsumer(
}
return ({
processToggleMuteFromOutside: (arg) => processToggleMuteFromOutside(arg),
showMute: isConnected() && !isListenOnly() && !isEchoTest() && !userLocks.userMic,
muted: isConnected() && !isListenOnly() && isMuted(),
inAudio: isConnected() && !isEchoTest(),

View File

@ -2,7 +2,6 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withModalMounter } from '/imports/ui/components/modal/service';
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
import getFromUserSettings from '/imports/ui/services/users-settings';
import { defineMessages, injectIntl } from 'react-intl';
import Styled from './styles';
import RecordingIndicator from './recording-indicator/container';
@ -50,20 +49,12 @@ class NavBar extends Component {
componentDidMount() {
const {
processOutsideToggleRecording,
connectRecordingObserver,
shortcuts: TOGGLE_USERLIST_AK,
} = this.props;
const { isFirefox } = browserInfo;
const { isMacos } = deviceInfo;
if (Meteor.settings.public.allowOutsideCommands.toggleRecording
|| getFromUserSettings('bbb_outside_toggle_recording', false)) {
connectRecordingObserver();
window.addEventListener('message', processOutsideToggleRecording);
}
// accessKey U does not work on firefox for macOS for some unknown reason
if (isMacos && isFirefox && TOGGLE_USERLIST_AK === 'U') {
document.addEventListener('keyup', (event) => {

View File

@ -9,7 +9,6 @@ import { ChatContext } from '/imports/ui/components/components-data/chat-context
import { GroupChatContext } from '/imports/ui/components/components-data/group-chat-context/context';
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
import NoteService from '/imports/ui/components/note/service';
import Service from './service';
import NavBar from './component';
import { layoutSelectInput, layoutSelectOutput, layoutDispatch } from '../layout/context';
@ -100,12 +99,8 @@ export default withTracker(() => {
document.title = titleString;
}
const { connectRecordingObserver, processOutsideToggleRecording } = Service;
return {
currentUserId: Auth.userID,
processOutsideToggleRecording,
connectRecordingObserver,
meetingId,
presentationTitle: meetingTitle,
};

View File

@ -15,18 +15,6 @@ export default withTracker(() => {
const meetingId = Auth.meetingID;
const recordObeject = RecordMeetings.findOne({ meetingId });
RecordMeetings.find({ meetingId: Auth.meetingID }, { fields: { recording: 1 } }).observeChanges({
changed: (id, fields) => {
if (fields && fields.recording) {
this.window.parent.postMessage({ response: 'recordingStarted' }, '*');
}
if (fields && !fields.recording) {
this.window.parent.postMessage({ response: 'recordingStopped' }, '*');
}
},
});
const micUser = VoiceUsers.findOne({ meetingId, joined: true, listenOnly: false }, {
fields: {
joined: 1,

View File

@ -1,31 +0,0 @@
import Auth from '/imports/ui/services/auth';
import { makeCall } from '/imports/ui/services/api';
import Meetings from '/imports/api/meetings';
const processOutsideToggleRecording = (e) => {
switch (e.data) {
case 'c_record': {
makeCall('toggleRecording');
break;
}
case 'c_recording_status': {
const recordingState = (Meetings.findOne({ meetingId: Auth.meetingID })).recording;
const recordingMessage = recordingState ? 'recordingStarted' : 'recordingStopped';
this.window.parent.postMessage({ response: recordingMessage }, '*');
break;
}
default: {
// console.log(e.data);
}
}
};
const connectRecordingObserver = () => {
// notify on load complete
this.window.parent.postMessage({ response: 'readyToConnect' }, '*');
};
export default {
connectRecordingObserver: () => connectRecordingObserver(),
processOutsideToggleRecording: arg => processOutsideToggleRecording(arg),
};

View File

@ -393,8 +393,6 @@ class AudioManager {
muteState = 'selfUnmuted';
this.unmute();
}
window.parent.postMessage({ response: muteState }, '*');
}
if (fields.talking !== undefined && fields.talking !== this.isTalking) {
@ -431,7 +429,6 @@ class AudioManager {
}
if (!this.isEchoTest) {
window.parent.postMessage({ response: 'joinedAudio' }, '*');
this.notify(this.intl.formatMessage(this.messages.info.JOINED_AUDIO));
logger.info({ logCode: 'audio_joined' }, 'Audio Joined');
this.inputStream = (this.bridge ? this.bridge.inputStream : null);
@ -473,7 +470,6 @@ class AudioManager {
this.playHangUpSound();
}
window.parent.postMessage({ response: 'notInAudio' }, '*');
window.removeEventListener('audioPlayFailed', this.handlePlayElementFailed);
}

View File

@ -411,9 +411,6 @@ public:
syncUsersWithConnectionManager:
enabled: false
syncInterval: 60000
allowOutsideCommands:
toggleRecording: false
toggleSelfVoice: false
poll:
enabled: true
maxCustom: 5