mirror of https://github.com/OpenVidu/openvidu.git
Screen share first version: auto Chrome extension
parent
7fd3911e3f
commit
9497ba7ea2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -20,6 +20,8 @@ import { Session } from './Session';
|
|||
import { Publisher } from './Publisher';
|
||||
|
||||
import * as adapter from 'webrtc-adapter';
|
||||
import * as screenSharing from '../ScreenSharing/Screen-Capturing.js';
|
||||
import * as screenSharingAuto from '../ScreenSharing/Screen-Capturing-Auto.js';
|
||||
|
||||
if (window) {
|
||||
window["adapter"] = adapter;
|
||||
|
@ -55,16 +57,112 @@ export class OpenVidu {
|
|||
|
||||
initPublisher(parentId: string, cameraOptions?: any, callback?: Function): any {
|
||||
if (this.checkSystemRequirements()) {
|
||||
let publisher: Publisher;
|
||||
if (cameraOptions != null) {
|
||||
let cameraOptionsAux = {
|
||||
sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true,
|
||||
sendVideo: cameraOptions.video != null ? cameraOptions.video : true,
|
||||
activeAudio: cameraOptions.activeAudio != null ? cameraOptions.activeAudio : true,
|
||||
activeVideo: cameraOptions.activeVideo != null ? cameraOptions.activeVideo : true,
|
||||
data: true,
|
||||
mediaConstraints: this.openVidu.generateMediaConstraints(cameraOptions)
|
||||
};
|
||||
cameraOptions = cameraOptionsAux;
|
||||
if (!cameraOptions.screen) {
|
||||
// Webcam and/or microphone is being requested
|
||||
|
||||
let cameraOptionsAux = {
|
||||
sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true,
|
||||
sendVideo: cameraOptions.video != null ? cameraOptions.video : true,
|
||||
activeAudio: cameraOptions.activeAudio != null ? cameraOptions.activeAudio : true,
|
||||
activeVideo: cameraOptions.activeVideo != null ? cameraOptions.activeVideo : true,
|
||||
data: true,
|
||||
mediaConstraints: this.openVidu.generateMediaConstraints(cameraOptions)
|
||||
};
|
||||
cameraOptions = cameraOptionsAux;
|
||||
publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, callback), parentId, false);
|
||||
console.info("'Publisher' initialized");
|
||||
return publisher;
|
||||
|
||||
} else {
|
||||
if (adapter.browserDetails.browser === 'firefox' && adapter.browserDetails.version >= 52) {
|
||||
publisher = new Publisher(this.openVidu.initPublisherScreen(parentId), parentId, true);
|
||||
screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => {
|
||||
cameraOptions = {
|
||||
sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true,
|
||||
sendVideo: cameraOptions.video != null ? cameraOptions.video : true,
|
||||
activeAudio: cameraOptions.activeAudio != null ? cameraOptions.activeAudio : true,
|
||||
activeVideo: cameraOptions.activeVideo != null ? cameraOptions.activeVideo : true,
|
||||
data: true,
|
||||
mediaConstraints: {
|
||||
video: screenConstraints.video,
|
||||
audio: false
|
||||
}
|
||||
}
|
||||
publisher.stream.configureScreenOptions(cameraOptions);
|
||||
console.info("'Publisher' initialized");
|
||||
});
|
||||
return publisher;
|
||||
} else if (adapter.browserDetails.browser === 'chrome') {
|
||||
// Screen is being requested
|
||||
|
||||
/*screenSharing.isChromeExtensionAvailable((availability) => {
|
||||
switch (availability) {
|
||||
case 'available':
|
||||
console.warn('EXTENSION AVAILABLE!!!');
|
||||
screenSharing.getScreenConstraints((error, screenConstraints) => {
|
||||
if (!error) {
|
||||
console.warn(screenConstraints);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'unavailable':
|
||||
console.warn('EXTENSION NOT AVAILABLE!!!');
|
||||
break;
|
||||
case 'isFirefox':
|
||||
console.warn('IT IS FIREFOX!!!');
|
||||
screenSharing.getScreenConstraints((error, screenConstraints) => {
|
||||
if (!error) {
|
||||
console.warn(screenConstraints);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});*/
|
||||
screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => {
|
||||
|
||||
if (error === 'not-installed') {
|
||||
console.error('Error capturing the screen: an extension is needed');
|
||||
if (confirm('You need an extension to share your screen!\n\n' +
|
||||
'This is the URL where you can install it:\n' +
|
||||
'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk\n\n' +
|
||||
'Click OK to install it (Pop-Up can be blocked) and then reload this page')) {
|
||||
window.open(
|
||||
'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk',
|
||||
'_blank'
|
||||
);
|
||||
}
|
||||
return;
|
||||
} else if (error === 'permission-denied') {
|
||||
console.error('Error capturing the screen: Permission Denied');
|
||||
return;
|
||||
}
|
||||
|
||||
cameraOptions = {
|
||||
sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true,
|
||||
sendVideo: cameraOptions.video != null ? cameraOptions.video : true,
|
||||
activeAudio: cameraOptions.activeAudio != null ? cameraOptions.activeAudio : true,
|
||||
activeVideo: cameraOptions.activeVideo != null ? cameraOptions.activeVideo : true,
|
||||
data: true,
|
||||
mediaConstraints: {
|
||||
video: screenConstraints.video,
|
||||
audio: false
|
||||
}
|
||||
}
|
||||
publisher.stream.configureScreenOptions(cameraOptions);
|
||||
|
||||
}, (error) => {
|
||||
console.error('getScreenId error', error);
|
||||
return;
|
||||
});
|
||||
publisher = new Publisher(this.openVidu.initPublisherScreen(parentId), parentId, true);
|
||||
console.info("'Publisher' initialized");
|
||||
return publisher;
|
||||
} else {
|
||||
console.error('Screen sharing not supported on ' + adapter.browserDetails.browser);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cameraOptions = {
|
||||
sendAudio: true,
|
||||
|
@ -77,12 +175,10 @@ export class OpenVidu {
|
|||
video: { width: { ideal: 1280 } }
|
||||
}
|
||||
}
|
||||
publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, callback), parentId, false);
|
||||
console.info("'Publisher' initialized");
|
||||
return publisher;
|
||||
}
|
||||
var publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, callback), parentId);
|
||||
|
||||
console.info("'Publisher' initialized");
|
||||
return publisher;
|
||||
|
||||
} else {
|
||||
alert("Browser not supported");
|
||||
}
|
||||
|
@ -113,10 +209,10 @@ export class OpenVidu {
|
|||
}
|
||||
|
||||
enableProdMode() {
|
||||
console.log = function() {};
|
||||
console.debug = function() {};
|
||||
console.info = function() {};
|
||||
console.warn = function() {};
|
||||
console.log = function () { };
|
||||
console.debug = function () { };
|
||||
console.info = function () { };
|
||||
console.warn = function () { };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,9 +19,11 @@ export class Publisher {
|
|||
id: string;
|
||||
stream: Stream;
|
||||
session: Session; //Initialized by Session.publish(Publisher)
|
||||
isScreenRequested: boolean = false;
|
||||
|
||||
constructor(stream: Stream, parentId: string) {
|
||||
constructor(stream: Stream, parentId: string, isScreenRequested: boolean) {
|
||||
this.stream = stream;
|
||||
this.isScreenRequested = isScreenRequested;
|
||||
|
||||
this.stream.addEventListener('camera-access-changed', (event) => {
|
||||
this.accessAllowed = event.accessAllowed;
|
||||
|
@ -86,9 +88,9 @@ export class Publisher {
|
|||
video.paused == false &&
|
||||
video.ended == false &&
|
||||
video.readyState == 4) {
|
||||
this.ee.emitEvent('videoPlaying', [{
|
||||
element: this.stream.getVideoElement()
|
||||
}]);
|
||||
this.ee.emitEvent('videoPlaying', [{
|
||||
element: this.stream.getVideoElement()
|
||||
}]);
|
||||
} else {
|
||||
this.stream.addOnceEventListener('video-is-playing', (element) => {
|
||||
this.ee.emitEvent('videoPlaying', [{
|
||||
|
@ -104,9 +106,9 @@ export class Publisher {
|
|||
video.paused == false &&
|
||||
video.ended == false &&
|
||||
video.readyState == 4) {
|
||||
this.ee.emitEvent('remoteVideoPlaying', [{
|
||||
element: this.stream.getVideoElement()
|
||||
}]);
|
||||
this.ee.emitEvent('remoteVideoPlaying', [{
|
||||
element: this.stream.getVideoElement()
|
||||
}]);
|
||||
} else {
|
||||
this.stream.addOnceEventListener('remote-video-is-playing', (element) => {
|
||||
this.ee.emitEvent('remoteVideoPlaying', [{
|
||||
|
|
|
@ -76,8 +76,15 @@ export class Session {
|
|||
}
|
||||
|
||||
publish(publisher: Publisher) {
|
||||
publisher.session = this;
|
||||
publisher.stream.publish();
|
||||
if (publisher.isScreenRequested && !publisher.stream.isScreenRequestedReady) {
|
||||
publisher.stream.addOnceEventListener('screen-ready', () => {
|
||||
publisher.session = this;
|
||||
publisher.stream.publish();
|
||||
});
|
||||
} else {
|
||||
publisher.session = this;
|
||||
publisher.stream.publish();
|
||||
}
|
||||
}
|
||||
|
||||
unpublish(publisher: Publisher) {
|
||||
|
@ -121,64 +128,4 @@ export class Session {
|
|||
subscriber.stream.removeVideo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Shortcut event API */
|
||||
|
||||
onStreamCreated(callback) {
|
||||
this.session.addEventListener("streamCreated", streamEvent => {
|
||||
callback(streamEvent.stream);
|
||||
});
|
||||
}
|
||||
|
||||
onStreamDestroyed(callback) {
|
||||
this.session.addEventListener("streamDestroyed", streamEvent => {
|
||||
callback(streamEvent.stream);
|
||||
});
|
||||
}
|
||||
|
||||
onParticipantJoined(callback) {
|
||||
this.session.addEventListener("participant-joined", participantEvent => {
|
||||
callback(participantEvent.connection);
|
||||
});
|
||||
}
|
||||
|
||||
onParticipantLeft(callback) {
|
||||
this.session.addEventListener("participant-left", participantEvent => {
|
||||
callback(participantEvent.connection);
|
||||
});
|
||||
}
|
||||
|
||||
onParticipantPublished(callback) {
|
||||
this.session.addEventListener("participant-published", participantEvent => {
|
||||
callback(participantEvent.connection);
|
||||
});
|
||||
}
|
||||
|
||||
onParticipantEvicted(callback) {
|
||||
this.session.addEventListener("participant-evicted", participantEvent => {
|
||||
callback(participantEvent.connection);
|
||||
});
|
||||
}
|
||||
|
||||
onRoomClosed(callback) {
|
||||
this.session.addEventListener("room-closed", roomEvent => {
|
||||
callback(roomEvent.room);
|
||||
});
|
||||
}
|
||||
|
||||
onLostConnection(callback) {
|
||||
this.session.addEventListener("lost-connection", roomEvent => {
|
||||
callback(roomEvent.room);
|
||||
});
|
||||
}
|
||||
|
||||
onMediaError(callback) {
|
||||
this.session.addEventListener("error-media", errorEvent => {
|
||||
callback(errorEvent.error)
|
||||
});
|
||||
}
|
||||
|
||||
/* Shortcut event API */
|
||||
}
|
||||
|
|
|
@ -42,32 +42,65 @@ export class OpenViduInternal {
|
|||
return this.session;
|
||||
}
|
||||
|
||||
initPublisherTagged(parentId: string, cameraOptions: any, callback?) {
|
||||
initPublisherTagged(parentId: string, cameraOptions: any, callback?: Function): Stream {
|
||||
|
||||
this.getCamera(cameraOptions);
|
||||
|
||||
if (callback == null) {
|
||||
this.camera.requestCameraAccess((error, camera) => {
|
||||
if (error) {
|
||||
console.error("Error accessing the camera", error);
|
||||
}
|
||||
else {
|
||||
this.camera.setVideoElement(this.cameraReady(camera!, parentId));
|
||||
}
|
||||
});
|
||||
return this.camera;
|
||||
} else {
|
||||
this.camera.requestCameraAccess((error, camera) => {
|
||||
if (error) {
|
||||
this.camera.requestCameraAccess((error, camera) => {
|
||||
if (error) {
|
||||
console.error("Error accessing the camera", error);
|
||||
if (callback) {
|
||||
callback(error);
|
||||
}
|
||||
else {
|
||||
this.camera.setVideoElement(this.cameraReady(camera!, parentId));
|
||||
} else {
|
||||
this.camera.setVideoElement(this.cameraReady(camera!, parentId));
|
||||
if (callback) {
|
||||
callback(undefined);
|
||||
}
|
||||
}
|
||||
});
|
||||
return this.camera;
|
||||
}
|
||||
|
||||
initPublisherScreen(parentId: string, callback?): Stream {
|
||||
this.camera = new Stream(this, true, this.session, 'screen-options');
|
||||
this.camera.addOnceEventListener('can-request-screen', () => {
|
||||
this.camera.requestCameraAccess((error, camera) => {
|
||||
if (error) {
|
||||
console.error("Error capturing the screen", error);
|
||||
if (callback) {
|
||||
callback(error);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.camera.setVideoElement(this.cameraReady(camera!, parentId));
|
||||
if (this.camera.getSendAudio()) {
|
||||
// If the user wants to send audio with the screen capturing
|
||||
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
|
||||
.then(userStream => {
|
||||
this.camera.getWrStream().addTrack(userStream.getAudioTracks()[0]);
|
||||
this.camera.isScreenRequestedReady = true;
|
||||
this.camera.ee.emitEvent('screen-ready');
|
||||
if (callback) {
|
||||
callback(undefined);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
this.camera.ee.emitEvent('access-denied-by-publisher');
|
||||
console.error("Access denied", error);
|
||||
if (callback) callback(error, this);
|
||||
});
|
||||
} else {
|
||||
this.camera.isScreenRequestedReady = true;
|
||||
this.camera.ee.emitEvent('screen-ready');
|
||||
if (callback) {
|
||||
callback(undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return this.camera;
|
||||
}
|
||||
});
|
||||
return this.camera;
|
||||
}
|
||||
|
||||
cameraReady(camera: Stream, parentId: string) {
|
||||
|
|
|
@ -53,7 +53,7 @@ export class Stream {
|
|||
|
||||
public connection: Connection;
|
||||
|
||||
private ee = new EventEmitter();
|
||||
ee = new EventEmitter();
|
||||
private wrStream: MediaStream;
|
||||
private wp: any;
|
||||
private id: string;
|
||||
|
@ -81,25 +81,14 @@ export class Stream {
|
|||
public isVideoELementCreated: boolean = false;
|
||||
public accessIsAllowed: boolean = false;
|
||||
public accessIsDenied: boolean = false;
|
||||
public isScreenRequestedReady: boolean = false;
|
||||
|
||||
constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: StreamOptions) {
|
||||
|
||||
if (options.id) {
|
||||
this.id = options.id;
|
||||
constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: any) {
|
||||
if (options !== 'screen-options') {
|
||||
this.configureOptions(options);
|
||||
} else {
|
||||
this.id = "webcam";
|
||||
this.connection = this.room.getLocalParticipant();
|
||||
}
|
||||
|
||||
this.connection = options.connection;
|
||||
this.recvVideo = options.recvVideo || false;
|
||||
this.recvAudio = options.recvAudio || false;
|
||||
this.sendVideo = options.sendVideo;
|
||||
this.sendAudio = options.sendAudio;
|
||||
this.activeAudio = options.activeAudio;
|
||||
this.activeVideo = options.activeVideo;
|
||||
this.dataChannel = options.data || false;
|
||||
this.mediaConstraints = options.mediaConstraints;
|
||||
|
||||
this.addEventListener('src-added', (srcEvent) => {
|
||||
this.videoSrcObject = srcEvent.srcObject;
|
||||
if (this.video) this.video.srcObject = srcEvent.srcObject;
|
||||
|
@ -159,6 +148,14 @@ export class Stream {
|
|||
return this.recvAudio;
|
||||
}
|
||||
|
||||
getSendVideo() {
|
||||
return this.sendVideo;
|
||||
}
|
||||
|
||||
getSendAudio() {
|
||||
return this.sendAudio;
|
||||
}
|
||||
|
||||
|
||||
subscribeToMyRemote() {
|
||||
this.showMyRemote = true;
|
||||
|
@ -397,7 +394,7 @@ export class Stream {
|
|||
});
|
||||
}
|
||||
|
||||
private cameraAccessSuccess(userStream, callback) {
|
||||
private cameraAccessSuccess(userStream: MediaStream, callback: Function) {
|
||||
this.accessIsAllowed = true;
|
||||
this.accessIsDenied = false;
|
||||
this.ee.emitEvent('access-allowed-by-publisher');
|
||||
|
@ -679,4 +676,39 @@ export class Stream {
|
|||
|
||||
console.info((this.local ? "Local " : "Remote ") + "'Stream' with id [" + this.getId() + "]' has been succesfully disposed");
|
||||
}
|
||||
|
||||
private configureOptions(options) {
|
||||
if (options.id) {
|
||||
this.id = options.id;
|
||||
} else {
|
||||
this.id = "webcam";
|
||||
}
|
||||
this.connection = options.connection;
|
||||
this.recvVideo = options.recvVideo || false;
|
||||
this.recvAudio = options.recvAudio || false;
|
||||
this.sendVideo = options.sendVideo;
|
||||
this.sendAudio = options.sendAudio;
|
||||
this.activeAudio = options.activeAudio;
|
||||
this.activeVideo = options.activeVideo;
|
||||
this.dataChannel = options.data || false;
|
||||
this.mediaConstraints = options.mediaConstraints;
|
||||
}
|
||||
|
||||
configureScreenOptions(options) {
|
||||
if (options.id) {
|
||||
this.id = options.id;
|
||||
} else {
|
||||
this.id = "screen";
|
||||
}
|
||||
this.recvVideo = options.recvVideo || false;
|
||||
this.recvAudio = options.recvAudio || false;
|
||||
this.sendVideo = options.sendVideo;
|
||||
this.sendAudio = options.sendAudio;
|
||||
this.activeAudio = options.activeAudio;
|
||||
this.activeVideo = options.activeVideo;
|
||||
this.dataChannel = options.data || false;
|
||||
this.mediaConstraints = options.mediaConstraints;
|
||||
|
||||
this.ee.emitEvent('can-request-screen');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
// Last time updated at Feb 16, 2017, 08:32:23
|
||||
|
||||
// Latest file can be found here: https://cdn.webrtc-experiment.com/getScreenId.js
|
||||
|
||||
// Muaz Khan - www.MuazKhan.com
|
||||
// MIT License - www.WebRTC-Experiment.com/licence
|
||||
// Documentation - https://github.com/muaz-khan/getScreenId.
|
||||
|
||||
// ______________
|
||||
// getScreenId.js
|
||||
|
||||
/*
|
||||
getScreenId(function (error, sourceId, screen_constraints) {
|
||||
// error == null || 'permission-denied' || 'not-installed' || 'installed-disabled' || 'not-chrome'
|
||||
// sourceId == null || 'string' || 'firefox'
|
||||
|
||||
if(sourceId == 'firefox') {
|
||||
navigator.mozGetUserMedia(screen_constraints, onSuccess, onFailure);
|
||||
}
|
||||
else navigator.webkitGetUserMedia(screen_constraints, onSuccess, onFailure);
|
||||
});
|
||||
*/
|
||||
|
||||
window.getScreenId = function (callback) {
|
||||
// for Firefox:
|
||||
// sourceId == 'firefox'
|
||||
// screen_constraints = {...}
|
||||
if (!!navigator.mozGetUserMedia) {
|
||||
callback(null, 'firefox', {
|
||||
video: {
|
||||
mozMediaSource: 'window',
|
||||
mediaSource: 'window'
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('message', onIFrameCallback);
|
||||
|
||||
function onIFrameCallback(event) {
|
||||
if (!event.data) return;
|
||||
|
||||
if (event.data.chromeMediaSourceId) {
|
||||
if (event.data.chromeMediaSourceId === 'PermissionDeniedError') {
|
||||
callback('permission-denied');
|
||||
} else callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId));
|
||||
}
|
||||
|
||||
if (event.data.chromeExtensionStatus) {
|
||||
callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus));
|
||||
}
|
||||
|
||||
// this event listener is no more needed
|
||||
window.removeEventListener('message', onIFrameCallback);
|
||||
}
|
||||
|
||||
setTimeout(postGetSourceIdMessage, 100);
|
||||
};
|
||||
|
||||
function getScreenConstraints(error, sourceId) {
|
||||
var screen_constraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: error ? 'screen' : 'desktop',
|
||||
maxWidth: window.screen.width > 1920 ? window.screen.width : 1920,
|
||||
maxHeight: window.screen.height > 1080 ? window.screen.height : 1080
|
||||
},
|
||||
optional: []
|
||||
}
|
||||
};
|
||||
|
||||
if (sourceId) {
|
||||
screen_constraints.video.mandatory.chromeMediaSourceId = sourceId;
|
||||
}
|
||||
|
||||
return screen_constraints;
|
||||
}
|
||||
|
||||
function postGetSourceIdMessage() {
|
||||
if (!iframe) {
|
||||
loadIFrame(postGetSourceIdMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!iframe.isLoaded) {
|
||||
setTimeout(postGetSourceIdMessage, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
iframe.contentWindow.postMessage({
|
||||
captureSourceId: true
|
||||
}, '*');
|
||||
}
|
||||
|
||||
var iframe;
|
||||
|
||||
// this function is used in RTCMultiConnection v3
|
||||
window.getScreenConstraints = function (callback) {
|
||||
loadIFrame(function () {
|
||||
getScreenId(function (error, sourceId, screen_constraints) {
|
||||
callback(error, screen_constraints.video);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function loadIFrame(loadCallback) {
|
||||
if (iframe) {
|
||||
loadCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.onload = function () {
|
||||
iframe.isLoaded = true;
|
||||
|
||||
loadCallback();
|
||||
};
|
||||
iframe.src = 'https://www.webrtc-experiment.com/getSourceId/'; // https://wwww.yourdomain.com/getScreenId.html
|
||||
iframe.style.display = 'none';
|
||||
(document.body || document.documentElement).appendChild(iframe);
|
||||
}
|
||||
|
||||
window.getChromeExtensionStatus = function (callback) {
|
||||
// for Firefox:
|
||||
if (!!navigator.mozGetUserMedia) {
|
||||
callback('installed-enabled');
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('message', onIFrameCallback);
|
||||
|
||||
function onIFrameCallback(event) {
|
||||
if (!event.data) return;
|
||||
|
||||
if (event.data.chromeExtensionStatus) {
|
||||
callback(event.data.chromeExtensionStatus);
|
||||
}
|
||||
|
||||
// this event listener is no more needed
|
||||
window.removeEventListener('message', onIFrameCallback);
|
||||
}
|
||||
|
||||
setTimeout(postGetChromeExtensionStatusMessage, 100);
|
||||
};
|
||||
|
||||
function postGetChromeExtensionStatusMessage() {
|
||||
if (!iframe) {
|
||||
loadIFrame(postGetChromeExtensionStatusMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!iframe.isLoaded) {
|
||||
setTimeout(postGetChromeExtensionStatusMessage, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
iframe.contentWindow.postMessage({
|
||||
getChromeExtensionStatus: true
|
||||
}, '*');
|
||||
}
|
||||
|
||||
exports.getScreenId = getScreenId;
|
||||
exports.getChromeExtensionStatus = getChromeExtensionStatus;
|
|
@ -0,0 +1,127 @@
|
|||
// global variables
|
||||
var chromeMediaSource = 'screen';
|
||||
var sourceId;
|
||||
var screenCallback;
|
||||
var isFirefox = typeof window.InstallTrigger !== 'undefined';
|
||||
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
|
||||
var isChrome = !!window.chrome && !isOpera;
|
||||
|
||||
window.addEventListener('message', function (event) {
|
||||
if (event.origin != window.location.origin) {
|
||||
return;
|
||||
}
|
||||
onMessageCallback(event.data);
|
||||
});
|
||||
|
||||
// and the function that handles received messages
|
||||
function onMessageCallback(data) {
|
||||
// "cancel" button is clicked
|
||||
if (data == 'PermissionDeniedError') {
|
||||
chromeMediaSource = 'PermissionDeniedError';
|
||||
if (screenCallback)
|
||||
return screenCallback('PermissionDeniedError');
|
||||
else
|
||||
throw new Error('PermissionDeniedError');
|
||||
}
|
||||
// extension notified his presence
|
||||
if (data == 'rtcmulticonnection-extension-loaded') {
|
||||
chromeMediaSource = 'desktop';
|
||||
}
|
||||
// extension shared temp sourceId
|
||||
if (data.sourceId && screenCallback) {
|
||||
screenCallback(sourceId = data.sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
// this method can be used to check if chrome extension is installed & enabled.
|
||||
function isChromeExtensionAvailable(callback) {
|
||||
if (isFirefox)
|
||||
return callback(false);
|
||||
if (chromeMediaSource == 'desktop')
|
||||
return callback('isFirefox');
|
||||
// ask extension if it is available
|
||||
window.postMessage('are-you-there', '*');
|
||||
setTimeout(function () {
|
||||
if (chromeMediaSource == 'screen') {
|
||||
callback('unavailable');
|
||||
}
|
||||
else
|
||||
callback('available');
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// this function can be used to get "source-id" from the extension
|
||||
function getSourceId(callback) {
|
||||
if (!callback)
|
||||
throw '"callback" parameter is mandatory.';
|
||||
if (sourceId)
|
||||
return callback(sourceId);
|
||||
screenCallback = callback;
|
||||
window.postMessage('get-sourceId', '*');
|
||||
}
|
||||
|
||||
function getChromeExtensionStatus(extensionid, callback) {
|
||||
if (isFirefox)
|
||||
return callback('not-chrome');
|
||||
if (arguments.length != 2) {
|
||||
callback = extensionid;
|
||||
extensionid = 'ajhifddimkapgcifgcodmmfdlknahffk'; // default extension-id
|
||||
}
|
||||
var image = document.createElement('img');
|
||||
image.src = 'chrome-extension://' + extensionid + '/icon.png';
|
||||
image.onload = function () {
|
||||
chromeMediaSource = 'screen';
|
||||
window.postMessage('are-you-there', '*');
|
||||
setTimeout(function () {
|
||||
if (chromeMediaSource == 'screen') {
|
||||
callback(extensionid == extensionid ? 'installed-enabled' : 'installed-disabled');
|
||||
}
|
||||
else
|
||||
callback('installed-enabled');
|
||||
}, 2000);
|
||||
};
|
||||
image.onerror = function () {
|
||||
callback('not-installed');
|
||||
};
|
||||
}
|
||||
|
||||
// this function explains how to use above methods/objects
|
||||
function getScreenConstraints(callback) {
|
||||
var firefoxScreenConstraints = {
|
||||
mozMediaSource: 'window',
|
||||
mediaSource: 'window'
|
||||
};
|
||||
if (isFirefox)
|
||||
return callback(null, firefoxScreenConstraints);
|
||||
// this statement defines getUserMedia constraints
|
||||
// that will be used to capture content of screen
|
||||
var screen_constraints = {
|
||||
mandatory: {
|
||||
chromeMediaSource: chromeMediaSource,
|
||||
maxWidth: screen.width > 1920 ? screen.width : 1920,
|
||||
maxHeight: screen.height > 1080 ? screen.height : 1080
|
||||
},
|
||||
optional: []
|
||||
};
|
||||
// this statement verifies chrome extension availability
|
||||
// if installed and available then it will invoke extension API
|
||||
// otherwise it will fallback to command-line based screen capturing API
|
||||
if (chromeMediaSource == 'desktop' && !sourceId) {
|
||||
getSourceId(function () {
|
||||
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
|
||||
callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints);
|
||||
});
|
||||
return;
|
||||
}
|
||||
// this statement sets gets 'sourceId" and sets "chromeMediaSourceId"
|
||||
if (chromeMediaSource == 'desktop') {
|
||||
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
|
||||
}
|
||||
// now invoking native getUserMedia API
|
||||
callback(null, screen_constraints);
|
||||
}
|
||||
|
||||
exports.getScreenConstraints = getScreenConstraints;
|
||||
exports.isChromeExtensionAvailable = isChromeExtensionAvailable;
|
||||
exports.getChromeExtensionStatus = getChromeExtensionStatus;
|
||||
exports.getSourceId = getSourceId;
|
|
@ -187,7 +187,8 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
video: this.sendVideo,
|
||||
activeAudio: this.activeAudio,
|
||||
activeVideo: this.activeVideo,
|
||||
quality: 'MEDIUM'
|
||||
quality: 'MEDIUM',
|
||||
screen: this.optionsVideo === 'screen' ? true : false
|
||||
});
|
||||
|
||||
this.publisher.on('videoElementCreated', (event) => {
|
||||
|
|
Loading…
Reference in New Issue