Merge branch 'feat-audiocontext' into develop
commit
23948f09d9
|
|
@ -53,7 +53,7 @@ export default class RoomClient
|
|||
'constructor() [roomId:"%s", peerName:"%s", displayName:"%s", device:%s]',
|
||||
roomId, peerName, displayName, device.flag);
|
||||
|
||||
const signalingUrl = getSignalingUrl(peerName, roomId);
|
||||
this._signalingUrl = getSignalingUrl(peerName, roomId);
|
||||
|
||||
// window element to external login site
|
||||
this._loginWindow;
|
||||
|
|
@ -76,18 +76,21 @@ export default class RoomClient
|
|||
// My peer name.
|
||||
this._peerName = peerName;
|
||||
|
||||
// My display name
|
||||
this._displayName = peerName;
|
||||
|
||||
// Alert sound
|
||||
this._soundAlert = new Audio('/resources/sounds/notify.mp3');
|
||||
|
||||
// AudioContext
|
||||
this._audioContext;
|
||||
|
||||
// Socket.io peer connection
|
||||
this._signalingSocket = io(signalingUrl);
|
||||
this._signalingSocket = null;
|
||||
|
||||
if (this._device.flag === 'firefox')
|
||||
ROOM_OPTIONS = Object.assign({ iceTransportPolicy: 'relay' }, ROOM_OPTIONS);
|
||||
|
||||
// mediasoup-client Room instance.
|
||||
this._room = new mediasoupClient.Room(ROOM_OPTIONS);
|
||||
this._room.roomId = roomId;
|
||||
// The mediasoup room instance
|
||||
this._room = null;
|
||||
this._roomId = roomId;
|
||||
|
||||
// Our WebTorrent client
|
||||
this._webTorrent = this._torrentSupport && new WebTorrent({
|
||||
|
|
@ -102,7 +105,7 @@ export default class RoomClient
|
|||
this._maxSpotlights = ROOM_OPTIONS.maxSpotlights;
|
||||
|
||||
// Manager of spotlight
|
||||
this._spotlights = new Spotlights(this._maxSpotlights, this._room);
|
||||
this._spotlights = null;
|
||||
|
||||
// Transport for sending.
|
||||
this._sendTransport = null;
|
||||
|
|
@ -140,7 +143,9 @@ export default class RoomClient
|
|||
|
||||
this._startKeyListener();
|
||||
|
||||
this._join({ displayName, device });
|
||||
this._audioContext = null;
|
||||
|
||||
this.join();
|
||||
}
|
||||
|
||||
close()
|
||||
|
|
@ -983,8 +988,36 @@ export default class RoomClient
|
|||
}, 500);
|
||||
}
|
||||
|
||||
_join({ displayName, device })
|
||||
async resumeAudio()
|
||||
{
|
||||
logger.debug('resumeAudio()');
|
||||
try
|
||||
{
|
||||
await this._audioContext.resume();
|
||||
|
||||
store.dispatch(
|
||||
stateActions.setAudioSuspended({ audioSuspended: false }));
|
||||
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
logger.error('resumeAudioJoin() failed: %o', error);
|
||||
}
|
||||
}
|
||||
|
||||
join()
|
||||
{
|
||||
this._signalingSocket = io(this._signalingUrl);
|
||||
|
||||
if (this._device.flag === 'firefox')
|
||||
ROOM_OPTIONS = Object.assign({ iceTransportPolicy: 'relay' }, ROOM_OPTIONS);
|
||||
|
||||
// mediasoup-client Room instance.
|
||||
this._room = new mediasoupClient.Room(ROOM_OPTIONS);
|
||||
this._room.roomId = this._roomId;
|
||||
|
||||
this._spotlights = new Spotlights(this._maxSpotlights, this._room);
|
||||
|
||||
store.dispatch(stateActions.setRoomState('connecting'));
|
||||
|
||||
this._signalingSocket.on('connect', () =>
|
||||
|
|
@ -996,7 +1029,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('signaling Peer "room-ready" event');
|
||||
|
||||
this._joinRoom({ displayName, device });
|
||||
this._joinRoom();
|
||||
});
|
||||
|
||||
this._signalingSocket.on('room-locked', () =>
|
||||
|
|
@ -1180,7 +1213,7 @@ export default class RoomClient
|
|||
});
|
||||
}
|
||||
|
||||
async _joinRoom({ displayName, device })
|
||||
async _joinRoom()
|
||||
{
|
||||
logger.debug('_joinRoom()');
|
||||
|
||||
|
|
@ -1236,7 +1269,13 @@ export default class RoomClient
|
|||
|
||||
try
|
||||
{
|
||||
await this._room.join(this._peerName, { displayName, device });
|
||||
await this._room.join(
|
||||
this._peerName,
|
||||
{
|
||||
displayName : this._displayName,
|
||||
device : this._device
|
||||
}
|
||||
);
|
||||
|
||||
store.dispatch(
|
||||
stateActions.setFileSharingSupported(this._torrentSupport));
|
||||
|
|
@ -1277,7 +1316,7 @@ export default class RoomClient
|
|||
if (this._produce)
|
||||
{
|
||||
if (this._room.canSend('audio'))
|
||||
this._setMicProducer();
|
||||
await this._setMicProducer();
|
||||
|
||||
// Add our webcam (unless the cookie says no).
|
||||
if (this._room.canSend('video'))
|
||||
|
|
@ -1285,7 +1324,7 @@ export default class RoomClient
|
|||
const devicesCookie = cookiesManager.getDevices();
|
||||
|
||||
if (!devicesCookie || devicesCookie.webcamEnabled)
|
||||
this.enableWebcam();
|
||||
await this.enableWebcam();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1462,6 +1501,14 @@ export default class RoomClient
|
|||
store.dispatch(stateActions.setProducerVolume(producer.id, volume));
|
||||
}
|
||||
});
|
||||
|
||||
this._audioContext = new AudioContext();
|
||||
|
||||
// We need to provoke user interaction to get permission from browser to start audio
|
||||
if (this._audioContext.state === 'suspended')
|
||||
{
|
||||
store.dispatch(stateActions.setAudioSuspended({ audioSuspended: true }));
|
||||
}
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
|
|
@ -1472,7 +1519,6 @@ export default class RoomClient
|
|||
if (producer)
|
||||
producer.close();
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
|
|
@ -63,6 +64,7 @@ class Room extends React.Component
|
|||
render()
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
room,
|
||||
amActiveSpeaker,
|
||||
onRoomLinkCopy
|
||||
|
|
@ -73,7 +75,31 @@ class Room extends React.Component
|
|||
democratic : Peers
|
||||
}[room.mode];
|
||||
|
||||
if (room.lockedOut)
|
||||
if (room.audioSuspended)
|
||||
{
|
||||
return (
|
||||
<Fragment>
|
||||
<Appear duration={300}>
|
||||
<div data-component='Room'>
|
||||
<div className='sound-suspended'>
|
||||
This webpage required sound and video to play, please click to allow.
|
||||
<div
|
||||
onClick={() =>
|
||||
{
|
||||
roomClient.notify('Joining.');
|
||||
roomClient.resumeAudio();
|
||||
}}
|
||||
className='button'
|
||||
>
|
||||
<span>Allow</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Appear>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
else if (room.lockedOut)
|
||||
{
|
||||
return (
|
||||
<Fragment>
|
||||
|
|
@ -186,6 +212,7 @@ class Room extends React.Component
|
|||
|
||||
Room.propTypes =
|
||||
{
|
||||
roomClient : PropTypes.object.isRequired,
|
||||
room : appPropTypes.Room.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
amActiveSpeaker : PropTypes.bool.isRequired,
|
||||
|
|
@ -228,9 +255,9 @@ const mapDispatchToProps = (dispatch) =>
|
|||
};
|
||||
};
|
||||
|
||||
const RoomContainer = connect(
|
||||
const RoomContainer = withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Room);
|
||||
)(Room));
|
||||
|
||||
export default RoomContainer;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ function run()
|
|||
// TODO: Debugging stuff.
|
||||
global.CLIENT = roomClient;
|
||||
|
||||
setInterval(() =>
|
||||
/* setInterval(() =>
|
||||
{
|
||||
if (!roomClient._room.peers[0])
|
||||
{
|
||||
|
|
@ -133,7 +133,7 @@ setInterval(() =>
|
|||
|
||||
global.CONSUMER = peer.consumers[peer.consumers.length - 1];
|
||||
}, 2000);
|
||||
|
||||
*/
|
||||
global.sendSdp = function()
|
||||
{
|
||||
logger.debug('---------- SEND_TRANSPORT LOCAL SDP OFFER:');
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ const initialState =
|
|||
state : 'new', // new/connecting/connected/disconnected/closed,
|
||||
locked : false,
|
||||
lockedOut : false,
|
||||
audioSuspended : false,
|
||||
activeSpeakerName : null,
|
||||
torrentSupport : false,
|
||||
showSettings : false,
|
||||
|
|
@ -52,6 +53,13 @@ const room = (state = initialState, action) =>
|
|||
return { ...state, lockedOut: true };
|
||||
}
|
||||
|
||||
case 'SET_AUDIO_SUSPENDED':
|
||||
{
|
||||
const { audioSuspended } = action.payload;
|
||||
|
||||
return { ...state, audioSuspended };
|
||||
}
|
||||
|
||||
case 'SET_ROOM_ACTIVE_SPEAKER':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,14 @@ export const setRoomLockedOut = () =>
|
|||
};
|
||||
};
|
||||
|
||||
export const setAudioSuspended = ({ audioSuspended }) =>
|
||||
{
|
||||
return {
|
||||
type : 'SET_AUDIO_SUSPENDED',
|
||||
payload : { audioSuspended }
|
||||
};
|
||||
};
|
||||
|
||||
export const setMe = ({ peerName, displayName, displayNameSet, device, loginEnabled }) =>
|
||||
{
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,34 @@
|
|||
padding: 2vmin;
|
||||
}
|
||||
|
||||
> .sound-suspended {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
width: 30vw;
|
||||
text-align: center;
|
||||
font-family: 'Roboto';
|
||||
font-size: 2.5em;
|
||||
box-shadow: 0px 5px 12px 2px rgba(17, 17, 17, 0.5);
|
||||
background-color: #fff;
|
||||
padding: 2vmin;
|
||||
|
||||
> .button {
|
||||
font-size: 1.5em;
|
||||
padding: 1.5vmin;
|
||||
margin: 0.8vmin;
|
||||
background-color: #38cd8b;
|
||||
border-radius: 1.8vmin;
|
||||
color: #fff;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
> .button:hover {
|
||||
background-color: #28bd7b;
|
||||
}
|
||||
}
|
||||
|
||||
> .room-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue