multiparty-meeting/app/src/ScreenShare.js

243 lines
3.7 KiB
JavaScript

import isElectron from 'is-electron';
let electron = null;
if (isElectron())
electron = window.require('electron');
class ElectronScreenShare
{
constructor()
{
this._stream = null;
}
start()
{
return Promise.resolve()
.then(() =>
{
return electron.desktopCapturer.getSources({ types: [ 'window', 'screen' ] });
})
.then((sources) =>
{
for (const source of sources)
{
// Currently only getting whole screen
if (source.name === 'Entire Screen')
{
return navigator.mediaDevices.getUserMedia({
audio : false,
video :
{
mandatory :
{
chromeMediaSource : 'desktop',
chromeMediaSourceId : source.id
}
}
});
}
}
})
.then((stream) =>
{
this._stream = stream;
return stream;
});
}
stop()
{
if (this._stream instanceof MediaStream === false)
{
return;
}
this._stream.getTracks().forEach((track) => track.stop());
this._stream = null;
}
isScreenShareAvailable()
{
return true;
}
}
class DisplayMediaScreenShare
{
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;
}
_toConstraints(options)
{
const constraints = {
video : {}
};
if (isFinite(options.width))
{
constraints.video.width = options.width;
}
if (isFinite(options.height))
{
constraints.video.height = options.height;
}
if (isFinite(options.frameRate))
{
constraints.video.frameRate = options.frameRate;
}
return constraints;
}
}
class FirefoxScreenShare
{
constructor()
{
this._stream = null;
}
start(options = {})
{
const constraints = this._toConstraints(options);
return navigator.mediaDevices.getUserMedia(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;
}
_toConstraints(options)
{
const constraints = {
video : {
mediaSource : 'window'
},
audio : false
};
if ('mediaSource' in options)
{
constraints.video.mediaSource = options.mediaSource;
}
if (isFinite(options.width))
{
constraints.video.width = {
min : options.width,
max : options.width
};
}
if (isFinite(options.height))
{
constraints.video.height = {
min : options.height,
max : options.height
};
}
if (isFinite(options.frameRate))
{
constraints.video.frameRate = {
min : options.frameRate,
max : options.frameRate
};
}
return constraints;
}
}
class DefaultScreenShare
{
isScreenShareAvailable()
{
return false;
}
}
export default class ScreenShare
{
static create(device)
{
if (isElectron())
return new ElectronScreenShare();
else
{
switch (device.flag)
{
case 'firefox':
{
if (device.version < 66.0)
return new FirefoxScreenShare();
else
return new DisplayMediaScreenShare();
}
case 'chrome':
{
return new DisplayMediaScreenShare();
}
case 'msedge':
{
return new DisplayMediaScreenShare();
}
default:
{
return new DefaultScreenShare();
}
}
}
}
}