Removed screensharing extension. Added some small optimization fixes.
parent
0aa0aa08b0
commit
a3013bb716
|
|
@ -8,3 +8,4 @@ node_modules/
|
||||||
/server/public/
|
/server/public/
|
||||||
/server/certs/
|
/server/certs/
|
||||||
!/server/certs/mediasoup-demo.localhost.*
|
!/server/certs/mediasoup-demo.localhost.*
|
||||||
|
.vscode
|
||||||
17
CHANGELOG.md
17
CHANGELOG.md
|
|
@ -1,5 +1,22 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
### 2.1
|
||||||
|
* Updated to mediasoup v3
|
||||||
|
* Replace lib "passport-datporten" with "openid-client" (a general OIDC certified client)
|
||||||
|
- OpenID Connect discovery
|
||||||
|
- Auth code flow
|
||||||
|
* Add spdy http2 support.
|
||||||
|
- Notice it does not supports node 11.x
|
||||||
|
|
||||||
|
### 2.0
|
||||||
|
* Material UI
|
||||||
|
* Separate settings for lastN for desktop and mobile
|
||||||
|
|
||||||
|
### 1.2
|
||||||
|
* Add Lock Room feature
|
||||||
|
* Fix suspended Web Audio context / fixed delayed getUsermedia
|
||||||
|
* Added support for the new getdisplaymedia API in Chrome 72
|
||||||
|
|
||||||
### 1.1
|
### 1.1
|
||||||
* Moved Filesharing code out from React code to RoomClient
|
* Moved Filesharing code out from React code to RoomClient
|
||||||
* Major cleanup of CSS. Variables for most colors and sizes exposed in :root
|
* Major cleanup of CSS. Variables for most colors and sizes exposed in :root
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ Try it online at https://letsmeet.no. You can add /roomname to the URL for speci
|
||||||
* Chat
|
* Chat
|
||||||
* Screen sharing
|
* Screen sharing
|
||||||
* File sharing
|
* File sharing
|
||||||
* Different video layouts
|
|
||||||
|
|
||||||
There is also a SIP gateway that can be found [here](https://github.com/havfo/multiparty-meeting-sipgw). To try it, call: roomname@letsmeet.no.
|
There is also a SIP gateway that can be found [here](https://github.com/havfo/multiparty-meeting-sipgw). To try it, call: roomname@letsmeet.no.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "multiparty-meeting",
|
"name": "multiparty-meeting",
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "multiparty meeting service",
|
"description": "multiparty meeting service",
|
||||||
"author": "Håvar Aambø Fosstveit <h@fosstveit.net>",
|
"author": "Håvar Aambø Fosstveit <h@fosstveit.net>",
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@
|
||||||
<meta name='description' content='multiparty meeting - Simple web meetings'>
|
<meta name='description' content='multiparty meeting - Simple web meetings'>
|
||||||
<meta name='theme-color' content='#000000' />
|
<meta name='theme-color' content='#000000' />
|
||||||
|
|
||||||
<link rel='chrome-webstore-item' href='https://chrome.google.com/webstore/detail/fckajcjdaabdgnbdcmhhebdglogjfodi'>
|
<link rel='preconnect' href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
|
||||||
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
|
|
||||||
<link rel='shortcut icon' href='%PUBLIC_URL%/favicon.ico' />
|
<link rel='shortcut icon' href='%PUBLIC_URL%/favicon.ico' />
|
||||||
<link rel='manifest' href='%PUBLIC_URL%/manifest.json' />
|
<link rel='manifest' href='%PUBLIC_URL%/manifest.json' />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Allow crawling of all content
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
|
|
@ -748,53 +748,6 @@ export default class RoomClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
installExtension()
|
|
||||||
{
|
|
||||||
logger.debug('installExtension()');
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) =>
|
|
||||||
{
|
|
||||||
window.addEventListener('message', _onExtensionMessage, false);
|
|
||||||
// eslint-disable-next-line
|
|
||||||
chrome.webstore.install(null, _successfulInstall, _failedInstall);
|
|
||||||
function _onExtensionMessage({ data })
|
|
||||||
{
|
|
||||||
if (data.type === 'ScreenShareInjected')
|
|
||||||
{
|
|
||||||
logger.debug('installExtension() | installation succeeded');
|
|
||||||
|
|
||||||
return resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _failedInstall(reason)
|
|
||||||
{
|
|
||||||
window.removeEventListener('message', _onExtensionMessage);
|
|
||||||
|
|
||||||
return reject(
|
|
||||||
new Error('Failed to install extension: %s', reason));
|
|
||||||
}
|
|
||||||
|
|
||||||
function _successfulInstall()
|
|
||||||
{
|
|
||||||
logger.debug('installExtension() | installation accepted');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() =>
|
|
||||||
{
|
|
||||||
// This should be handled better
|
|
||||||
store.dispatch(stateActions.setScreenCapabilities(
|
|
||||||
{
|
|
||||||
canShareScreen : this._room.canSend('video'),
|
|
||||||
needExtension : false
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
.catch((error) =>
|
|
||||||
{
|
|
||||||
logger.error('installExtension() | failed: %o', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async changeAudioDevice(deviceId)
|
async changeAudioDevice(deviceId)
|
||||||
{
|
{
|
||||||
logger.debug('changeAudioDevice() [deviceId: %s]', deviceId);
|
logger.debug('changeAudioDevice() [deviceId: %s]', deviceId);
|
||||||
|
|
@ -1697,7 +1650,6 @@ export default class RoomClient
|
||||||
canSendWebcam : this._mediasoupDevice.canProduce('video'),
|
canSendWebcam : this._mediasoupDevice.canProduce('video'),
|
||||||
canShareScreen : this._mediasoupDevice.canProduce('video') &&
|
canShareScreen : this._mediasoupDevice.canProduce('video') &&
|
||||||
this._screenSharing.isScreenShareAvailable(),
|
this._screenSharing.isScreenShareAvailable(),
|
||||||
needExtension : this._screenSharing.needExtension(),
|
|
||||||
canShareFiles : this._torrentSupport
|
canShareFiles : this._torrentSupport
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -2021,8 +1973,7 @@ export default class RoomClient
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const available = this._screenSharing.isScreenShareAvailable() &&
|
const available = this._screenSharing.isScreenShareAvailable();
|
||||||
!this._screenSharing.needExtension();
|
|
||||||
|
|
||||||
if (!available)
|
if (!available)
|
||||||
throw new Error('screen sharing not available');
|
throw new Error('screen sharing not available');
|
||||||
|
|
|
||||||
|
|
@ -1,113 +1,4 @@
|
||||||
class ChromeScreenShare
|
class DisplayMediaScreenShare
|
||||||
{
|
|
||||||
constructor()
|
|
||||||
{
|
|
||||||
this._stream = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
start(options = { })
|
|
||||||
{
|
|
||||||
const state = this;
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) =>
|
|
||||||
{
|
|
||||||
window.addEventListener('message', _onExtensionMessage, false);
|
|
||||||
window.postMessage({ type: 'getStreamId' }, '*');
|
|
||||||
|
|
||||||
function _onExtensionMessage({ data })
|
|
||||||
{
|
|
||||||
if (data.type !== 'gotStreamId')
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const constraints = state._toConstraints(options, data.streamId);
|
|
||||||
|
|
||||||
navigator.mediaDevices.getUserMedia(constraints)
|
|
||||||
.then((stream) =>
|
|
||||||
{
|
|
||||||
window.removeEventListener('message', _onExtensionMessage);
|
|
||||||
|
|
||||||
state._stream = stream;
|
|
||||||
resolve(stream);
|
|
||||||
})
|
|
||||||
.catch((err) =>
|
|
||||||
{
|
|
||||||
window.removeEventListener('message', _onExtensionMessage);
|
|
||||||
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
stop()
|
|
||||||
{
|
|
||||||
if (this._stream instanceof MediaStream === false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._stream.getTracks().forEach((track) => track.stop());
|
|
||||||
this._stream = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
isScreenShareAvailable()
|
|
||||||
{
|
|
||||||
if ('__multipartyMeetingScreenShareExtensionAvailable__' in window)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
needExtension()
|
|
||||||
{
|
|
||||||
if ('__multipartyMeetingScreenShareExtensionAvailable__' in window)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_toConstraints(options, streamId)
|
|
||||||
{
|
|
||||||
const constraints = {
|
|
||||||
video : {
|
|
||||||
mandatory : {
|
|
||||||
chromeMediaSource : 'desktop',
|
|
||||||
chromeMediaSourceId : streamId
|
|
||||||
},
|
|
||||||
optional : [ {
|
|
||||||
googTemporalLayeredScreencast : true
|
|
||||||
} ]
|
|
||||||
},
|
|
||||||
audio : false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isFinite(options.width))
|
|
||||||
{
|
|
||||||
constraints.video.mandatory.maxWidth = options.width;
|
|
||||||
constraints.video.mandatory.minWidth = options.width;
|
|
||||||
}
|
|
||||||
if (isFinite(options.height))
|
|
||||||
{
|
|
||||||
constraints.video.mandatory.maxHeight = options.height;
|
|
||||||
constraints.video.mandatory.minHeight = options.height;
|
|
||||||
}
|
|
||||||
if (isFinite(options.frameRate))
|
|
||||||
{
|
|
||||||
constraints.video.mandatory.maxFrameRate = options.frameRate;
|
|
||||||
constraints.video.mandatory.minFrameRate = options.frameRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return constraints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Chrome72ScreenShare
|
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
|
@ -143,11 +34,6 @@ class Chrome72ScreenShare
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
needExtension()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_toConstraints()
|
_toConstraints()
|
||||||
{
|
{
|
||||||
const constraints = {
|
const constraints = {
|
||||||
|
|
@ -194,11 +80,6 @@ class FirefoxScreenShare
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
needExtension()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_toConstraints(options)
|
_toConstraints(options)
|
||||||
{
|
{
|
||||||
const constraints = {
|
const constraints = {
|
||||||
|
|
@ -238,119 +119,12 @@ class FirefoxScreenShare
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Firefox66ScreenShare
|
|
||||||
{
|
|
||||||
constructor()
|
|
||||||
{
|
|
||||||
this._stream = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
start(options = {})
|
|
||||||
{
|
|
||||||
const constraints = this._toConstraints(options);
|
|
||||||
|
|
||||||
return navigator.mediaDevices.getDisplayMedia(constraints)
|
|
||||||
.then((stream) =>
|
|
||||||
{
|
|
||||||
this._stream = stream;
|
|
||||||
|
|
||||||
return Promise.resolve(stream);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
stop()
|
|
||||||
{
|
|
||||||
if (this._stream instanceof MediaStream === false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._stream.getTracks().forEach((track) => track.stop());
|
|
||||||
this._stream = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
isScreenShareAvailable()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
needExtension()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_toConstraints()
|
|
||||||
{
|
|
||||||
const constraints = {
|
|
||||||
video : true
|
|
||||||
};
|
|
||||||
|
|
||||||
return constraints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EdgeScreenShare
|
|
||||||
{
|
|
||||||
constructor()
|
|
||||||
{
|
|
||||||
this._stream = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
start(options = {})
|
|
||||||
{
|
|
||||||
const constraints = this._toConstraints(options);
|
|
||||||
|
|
||||||
return navigator.getDisplayMedia(constraints)
|
|
||||||
.then((stream) =>
|
|
||||||
{
|
|
||||||
this._stream = stream;
|
|
||||||
|
|
||||||
return Promise.resolve(stream);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
stop()
|
|
||||||
{
|
|
||||||
if (this._stream instanceof MediaStream === false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._stream.getTracks().forEach((track) => track.stop());
|
|
||||||
this._stream = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
isScreenShareAvailable()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
needExtension()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_toConstraints()
|
|
||||||
{
|
|
||||||
const constraints = {
|
|
||||||
video : true
|
|
||||||
};
|
|
||||||
|
|
||||||
return constraints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DefaultScreenShare
|
class DefaultScreenShare
|
||||||
{
|
{
|
||||||
isScreenShareAvailable()
|
isScreenShareAvailable()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
needExtension()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ScreenShare
|
export default class ScreenShare
|
||||||
|
|
@ -364,18 +138,15 @@ export default class ScreenShare
|
||||||
if (device.version < 66.0)
|
if (device.version < 66.0)
|
||||||
return new FirefoxScreenShare();
|
return new FirefoxScreenShare();
|
||||||
else
|
else
|
||||||
return new Firefox66ScreenShare();
|
return new DisplayMediaScreenShare();
|
||||||
}
|
}
|
||||||
case 'chrome':
|
case 'chrome':
|
||||||
{
|
{
|
||||||
if (device.version < 72.0)
|
return new DisplayMediaScreenShare();
|
||||||
return new ChromeScreenShare();
|
|
||||||
else
|
|
||||||
return new Chrome72ScreenShare();
|
|
||||||
}
|
}
|
||||||
case 'msedge':
|
case 'msedge':
|
||||||
{
|
{
|
||||||
return new EdgeScreenShare();
|
return new DisplayMediaScreenShare();
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -69,21 +69,12 @@ export const setMediaCapabilities = ({
|
||||||
canSendMic,
|
canSendMic,
|
||||||
canSendWebcam,
|
canSendWebcam,
|
||||||
canShareScreen,
|
canShareScreen,
|
||||||
needExtension,
|
|
||||||
canShareFiles
|
canShareFiles
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
type : 'SET_MEDIA_CAPABILITIES',
|
type : 'SET_MEDIA_CAPABILITIES',
|
||||||
payload : { canSendMic, canSendWebcam, canShareScreen, needExtension, canShareFiles }
|
payload : { canSendMic, canSendWebcam, canShareScreen, canShareFiles }
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setScreenCapabilities = ({ canShareScreen, needExtension }) =>
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
type : 'SET_SCREEN_CAPABILITIES',
|
|
||||||
payload : { canShareScreen, needExtension }
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,12 +119,7 @@ const Sidebar = (props) =>
|
||||||
|
|
||||||
let screenTip;
|
let screenTip;
|
||||||
|
|
||||||
if (me.needExtension)
|
if (!me.canShareScreen)
|
||||||
{
|
|
||||||
screenState = 'need-extension';
|
|
||||||
screenTip = 'Install screen sharing extension';
|
|
||||||
}
|
|
||||||
else if (!me.canShareScreen)
|
|
||||||
{
|
{
|
||||||
screenState = 'unsupported';
|
screenState = 'unsupported';
|
||||||
screenTip = 'Screen sharing not supported';
|
screenTip = 'Screen sharing not supported';
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ const initialState =
|
||||||
canSendMic : false,
|
canSendMic : false,
|
||||||
canSendWebcam : false,
|
canSendWebcam : false,
|
||||||
canShareScreen : false,
|
canShareScreen : false,
|
||||||
needExtension : false,
|
|
||||||
canShareFiles : false,
|
canShareFiles : false,
|
||||||
audioDevices : null,
|
audioDevices : null,
|
||||||
webcamDevices : null,
|
webcamDevices : null,
|
||||||
|
|
@ -50,7 +49,6 @@ const me = (state = initialState, action) =>
|
||||||
canSendMic,
|
canSendMic,
|
||||||
canSendWebcam,
|
canSendWebcam,
|
||||||
canShareScreen,
|
canShareScreen,
|
||||||
needExtension,
|
|
||||||
canShareFiles
|
canShareFiles
|
||||||
} = action.payload;
|
} = action.payload;
|
||||||
|
|
||||||
|
|
@ -59,18 +57,10 @@ const me = (state = initialState, action) =>
|
||||||
canSendMic,
|
canSendMic,
|
||||||
canSendWebcam,
|
canSendWebcam,
|
||||||
canShareScreen,
|
canShareScreen,
|
||||||
needExtension,
|
|
||||||
canShareFiles
|
canShareFiles
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_SCREEN_CAPABILITIES':
|
|
||||||
{
|
|
||||||
const { canShareScreen, needExtension } = action.payload;
|
|
||||||
|
|
||||||
return { ...state, canShareScreen, needExtension };
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'SET_AUDIO_DEVICES':
|
case 'SET_AUDIO_DEVICES':
|
||||||
{
|
{
|
||||||
const { devices } = action.payload;
|
const { devices } = action.payload;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "multiparty-meeting-server",
|
"name": "multiparty-meeting-server",
|
||||||
"version": "3.0.0",
|
"version": "2.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "multiparty meeting server",
|
"description": "multiparty meeting server",
|
||||||
"author": "Håvar Aambø Fosstveit <h@fosstveit.net>",
|
"author": "Håvar Aambø Fosstveit <h@fosstveit.net>",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue