Removed screensharing extension. Added some small optimization fixes.

master
Håvar Aambø Fosstveit 2019-06-04 12:58:12 +02:00
parent 0aa0aa08b0
commit a3013bb716
12 changed files with 31 additions and 314 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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>",

View File

@ -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' />

View File

@ -0,0 +1,3 @@
# Allow crawling of all content
User-agent: *
Disallow:

View File

@ -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');

View File

@ -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:
{ {

View File

@ -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 }
}; };
}; };

View File

@ -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';

View File

@ -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;

View File

@ -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>",