diff --git a/openvidu-browser/ts/OpenVidu/OpenVidu.ts b/openvidu-browser/ts/OpenVidu/OpenVidu.ts index de116f6d..54c188f5 100644 --- a/openvidu-browser/ts/OpenVidu/OpenVidu.ts +++ b/openvidu-browser/ts/OpenVidu/OpenVidu.ts @@ -19,6 +19,7 @@ import { OpenViduInternal } from '../OpenViduInternal/OpenViduInternal'; import { Session } from './Session'; import { Publisher } from './Publisher'; import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/OpenViduError'; +import { OutboundStreamOptions } from '../OpenViduInternal/index'; import * as adapter from 'webrtc-adapter'; import * as screenSharing from '../ScreenSharing/Screen-Capturing.js'; @@ -58,7 +59,6 @@ export class OpenVidu { initPublisher(parentId: string, cameraOptions?: any, callback?: Function): any { if (this.checkSystemRequirements()) { - this.openVidu.storedPublisherOptions = cameraOptions; let publisher: Publisher; if (cameraOptions != null) { @@ -66,6 +66,7 @@ export class OpenVidu { cameraOptions.video = cameraOptions.video != null ? cameraOptions.video : true; if (!cameraOptions.screen) { + // Webcam and/or microphone is being requested let cameraOptionsAux = { @@ -73,16 +74,19 @@ export class OpenVidu { sendVideo: cameraOptions.video != null ? cameraOptions.video : true, activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, - data: true, + dataChannel: true, mediaConstraints: this.openVidu.generateMediaConstraints(cameraOptions) }; cameraOptions = cameraOptionsAux; - publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, callback), parentId, false); + + publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, true, callback), parentId, false); console.info("'Publisher' initialized"); + return publisher; } else { - publisher = new Publisher(this.openVidu.initPublisherScreen(parentId, callback), parentId, true); + + publisher = new Publisher(this.openVidu.initPublisherScreen(parentId, true, callback), parentId, true); if (adapter.browserDetails.browser === 'firefox' && adapter.browserDetails.version >= 52) { screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { cameraOptions = { @@ -90,14 +94,17 @@ export class OpenVidu { sendVideo: cameraOptions.video, activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, - data: true, + dataChannel: true, mediaConstraints: { video: screenConstraints.video, audio: false } } + publisher.stream.configureScreenOptions(cameraOptions); console.info("'Publisher' initialized"); + + publisher.stream.ee.emitEvent('can-request-screen'); }); return publisher; } else if (adapter.browserDetails.browser === 'chrome') { @@ -145,14 +152,16 @@ export class OpenVidu { sendVideo: cameraOptions.video != null ? cameraOptions.video : true, activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, - data: true, + dataChannel: true, mediaConstraints: { video: screenConstraints.video, audio: false } } + publisher.stream.configureScreenOptions(cameraOptions); + publisher.stream.ee.emitEvent('can-request-screen'); }, (error) => { console.error('getScreenId error', error); return; @@ -169,14 +178,15 @@ export class OpenVidu { sendVideo: true, activeAudio: true, activeVideo: true, - data: true, + dataChannel: true, mediaConstraints: { audio: true, video: { width: { ideal: 1280 } } } } - publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, callback), parentId, false); + publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, true, callback), parentId, false); console.info("'Publisher' initialized"); + return publisher; } } else { @@ -184,6 +194,50 @@ export class OpenVidu { } } + reinitPublisher(publisher: Publisher): any { + if (publisher.stream.typeOfVideo !== 'SCREEN') { + publisher = new Publisher(this.openVidu.initPublisherTagged(publisher.stream.getParentId(), publisher.stream.outboundOptions, false), publisher.stream.getParentId(), false); + console.info("'Publisher' initialized"); + return publisher; + } else { + publisher = new Publisher(this.openVidu.initPublisherScreen(publisher.stream.getParentId(), false), publisher.stream.getParentId(), true); + if (adapter.browserDetails.browser === 'firefox' && adapter.browserDetails.version >= 52) { + screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { + + publisher.stream.outboundOptions.mediaConstraints.video = screenConstraints.video; + publisher.stream.configureScreenOptions(publisher.stream.outboundOptions); + console.info("'Publisher' initialized"); + + publisher.stream.ee.emitEvent('can-request-screen'); + }); + return publisher; + } else if (adapter.browserDetails.browser === 'chrome') { + screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { + if (error === 'not-installed') { + let error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, 'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk'); + console.error(error); + return; + } else if (error === 'permission-denied') { + let error = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error); + return; + } + publisher.stream.outboundOptions.mediaConstraints.video = screenConstraints.video; + publisher.stream.configureScreenOptions(publisher.stream.outboundOptions); + + publisher.stream.ee.emitEvent('can-request-screen'); + }, (error) => { + console.error('getScreenId error', error); + return; + }); + console.info("'Publisher' initialized"); + return publisher; + } else { + console.error('Screen sharing not supported on ' + adapter.browserDetails.browser); + } + } + } + checkSystemRequirements(): number { let browser = adapter.browserDetails.browser; let version = adapter.browserDetails.version; diff --git a/openvidu-browser/ts/OpenVidu/Publisher.ts b/openvidu-browser/ts/OpenVidu/Publisher.ts index 6331b905..3c237d7f 100644 --- a/openvidu-browser/ts/OpenVidu/Publisher.ts +++ b/openvidu-browser/ts/OpenVidu/Publisher.ts @@ -5,7 +5,7 @@ * * stream.hasAudio(); stream.hasVideo(); stream.hasData(); */ -import { Stream, StreamOptions } from '../OpenViduInternal/Stream'; +import { Stream } from '../OpenViduInternal/Stream'; import { Session } from './Session'; import EventEmitter = require('wolfy87-eventemitter'); diff --git a/openvidu-browser/ts/OpenVidu/Session.ts b/openvidu-browser/ts/OpenVidu/Session.ts index e146b850..85079894 100644 --- a/openvidu-browser/ts/OpenVidu/Session.ts +++ b/openvidu-browser/ts/OpenVidu/Session.ts @@ -11,7 +11,6 @@ import EventEmitter = require('wolfy87-eventemitter'); export class Session { sessionId: String; - //capabilities: Capabilities connection: Connection; private ee = new EventEmitter(); @@ -89,13 +88,14 @@ export class Session { this.streamPublish(publisher); } } else { // 'Session.unpublish(Publisher)' has been called - let mypublisher = this.openVidu.initPublisher(publisher.stream.getParentId(), this.openVidu.openVidu.storedPublisherOptions); - if (mypublisher.isScreenRequested && !mypublisher.stream.isScreenRequestedReady) { // Screen sharing Publisher and video stream not available yet - mypublisher.stream.addOnceEventListener('screen-ready', () => { - this.streamPublish(mypublisher); + publisher = this.openVidu.reinitPublisher(publisher); + + if (publisher.isScreenRequested && !publisher.stream.isScreenRequestedReady) { // Screen sharing Publisher and video stream not available yet + publisher.stream.addOnceEventListener('screen-ready', () => { + this.streamPublish(publisher); }); } else { // Video stream already available - this.streamPublish(mypublisher); + this.streamPublish(publisher); } } } diff --git a/openvidu-browser/ts/OpenVidu/Subscriber.ts b/openvidu-browser/ts/OpenVidu/Subscriber.ts index 0d219664..5b485f8b 100644 --- a/openvidu-browser/ts/OpenVidu/Subscriber.ts +++ b/openvidu-browser/ts/OpenVidu/Subscriber.ts @@ -1,4 +1,4 @@ -import { Stream, StreamOptions } from '../OpenViduInternal/Stream'; +import { Stream } from '../OpenViduInternal/Stream'; import EventEmitter = require('wolfy87-eventemitter'); diff --git a/openvidu-browser/ts/OpenViduInternal/Connection.ts b/openvidu-browser/ts/OpenViduInternal/Connection.ts index d82e6b59..faef6e01 100644 --- a/openvidu-browser/ts/OpenViduInternal/Connection.ts +++ b/openvidu-browser/ts/OpenViduInternal/Connection.ts @@ -1,4 +1,4 @@ -import { Stream, StreamOptions } from './Stream'; +import { Stream, StreamOptionsServer, InboundStreamOptions } from './Stream'; import { OpenViduInternal } from './OpenViduInternal'; import { SessionInternal } from './SessionInternal'; @@ -7,9 +7,7 @@ type ObjMap = { [s: string]: T; } export interface ConnectionOptions { id: string; metadata: string; - streams?: StreamOptions[]; - audioActive: boolean; - videoActive: boolean; + streams: StreamOptionsServer[]; } export class Connection { @@ -18,7 +16,7 @@ export class Connection { public data: string; public creationTime: number; private streams: ObjMap = {}; - private streamsOpts: StreamOptions; + private inboundStreamsOpts: InboundStreamOptions; constructor( private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, private options?: ConnectionOptions ) { @@ -27,10 +25,11 @@ export class Connection { if ( options ) { this.connectionId = options.id; - this.data = options.metadata; - - if ( options.streams ) { - this.initStreams(options); + if (options.metadata) { + this.data = options.metadata; + } + if (options.streams) { + this.initRemoteStreams(options); } } @@ -44,7 +43,11 @@ export class Connection { removeStream( key: string ) { delete this.streams[key]; delete this.room.getStreams()[key]; - delete this.streamsOpts; + delete this.inboundStreamsOpts; + } + + setOptions(options: ConnectionOptions) { + this.options = options; } getStreams() { @@ -75,28 +78,23 @@ export class Connection { }); } - initStreams(options) { - for ( let streamOptions of options.streams ) { + initRemoteStreams(options: ConnectionOptions) { + let opts: StreamOptionsServer; + for ( opts of options.streams ) { - let streamOpts = { - id: streamOptions.id, + let streamOptions: InboundStreamOptions = { + id: opts.id, connection: this, - sendAudio: streamOptions.sendAudio, - sendVideo: streamOptions.sendVideo, - recvAudio: ( streamOptions.audioActive == undefined ? true : streamOptions.audioActive ), - recvVideo: ( streamOptions.videoActive == undefined ? true : streamOptions.videoActive ), - typeOfVideo: streamOptions.typeOfVideo, - activeAudio: streamOptions.activeAudio, - activeVideo: streamOptions.activeVideo, - data: streamOptions.data, - mediaConstraints: streamOptions.mediaConstraints + recvAudio: ( opts.audioActive == null ? true : opts.audioActive ), + recvVideo: ( opts.videoActive == null ? true : opts.videoActive ), + typeOfVideo: opts.typeOfVideo, } - let stream = new Stream(this.openVidu, false, this.room, streamOpts ); + let stream = new Stream(this.openVidu, false, this.room, streamOptions); - this.addStream( stream ); - this.streamsOpts = streamOpts; + this.addStream(stream); + this.inboundStreamsOpts = streamOptions; } - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + "] is now configured for receiving Streams with options: ", this.streamsOpts ); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + "] is now configured for receiving Streams with options: ", this.inboundStreamsOpts ); } } \ No newline at end of file diff --git a/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts b/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts index 6ed39cc2..2a8b1c26 100644 --- a/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts +++ b/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts @@ -1,4 +1,4 @@ -export enum OpenViduErrorName { +export const enum OpenViduErrorName { CAMERA_ACCESS_DENIED = 'CAMERA_ACCESS_DENIED', MICROPHONE_ACCESS_DENIED = 'MICROPHONE_ACCESS_DENIED', SCREEN_CAPTURE_DENIED = 'SCREEN_CAPTURE_DENIED', diff --git a/openvidu-browser/ts/OpenViduInternal/OpenViduInternal.ts b/openvidu-browser/ts/OpenViduInternal/OpenViduInternal.ts index 7b06e8cf..8d00db94 100644 --- a/openvidu-browser/ts/OpenViduInternal/OpenViduInternal.ts +++ b/openvidu-browser/ts/OpenViduInternal/OpenViduInternal.ts @@ -16,7 +16,7 @@ */ import { SessionInternal, SessionOptions } from './SessionInternal'; import { OpenViduError, OpenViduErrorName } from './OpenViduError'; -import { Stream } from './Stream'; +import { Stream, OutboundStreamOptions } from './Stream'; import * as RpcBuilder from '../KurentoUtils/kurento-jsonrpc'; export type Callback = (error?: any, openVidu?: T) => void; @@ -28,15 +28,10 @@ export class OpenViduInternal { private jsonRpcClient: any; private rpcParams: any; private callback: Callback; - private camera: Stream; + private localStream: Stream; private remoteStreams: Stream[] = []; - private secret: string; - constructor() { }; - - storedPublisherOptions: any; - /* NEW METHODS */ initSession(sessionId) { console.info("'Session' initialized with 'sessionId' [" + sessionId + "]"); @@ -44,36 +39,56 @@ export class OpenViduInternal { return this.session; } - initPublisherTagged(parentId: string, cameraOptions: any, callback?: Function): Stream { + initPublisherTagged(parentId: string, cameraOptions: OutboundStreamOptions, newStream: boolean, callback?: Function): Stream { - this.getCamera(cameraOptions); + if (newStream) { + if (cameraOptions == null) { + cameraOptions = { + connection: this.session.getLocalParticipant(), + sendAudio: true, + sendVideo: true, + activeAudio: true, + activeVideo: true, + dataChannel: true, + mediaConstraints: { + audio: true, + video: { width: { ideal: 1280 } } + } + } + } else { + cameraOptions.connection = this.session.getLocalParticipant(); + } + this.localStream = new Stream(this, true, this.session, cameraOptions); + } - this.camera.requestCameraAccess((error, camera) => { + this.localStream.requestCameraAccess((error, localStream) => { if (error) { - // Neither camera or microphone device is allowed/able to capture media + // Neither localStream or microphone device is allowed/able to capture media console.error(error); if (callback) { callback(error); } - this.camera.ee.emitEvent('access-denied-by-publisher'); + this.localStream.ee.emitEvent('access-denied-by-publisher'); } else { - this.camera.setVideoElement(this.cameraReady(camera!, parentId)); + this.localStream.setVideoElement(this.cameraReady(localStream!, parentId)); if (callback) { callback(undefined); } } }); - return this.camera; + return this.localStream; } - initPublisherScreen(parentId: string, callback?): Stream { - if (!this.camera) { - this.camera = new Stream(this, true, this.session, 'screen-options'); + initPublisherScreen(parentId: string, newStream: boolean, callback?): Stream { + + if (newStream) { + this.localStream = new Stream(this, true, this.session, 'screen-options'); } - this.camera.addOnceEventListener('can-request-screen', () => { - this.camera.requestCameraAccess((error, camera) => { + + this.localStream.addOnceEventListener('can-request-screen', () => { + this.localStream.requestCameraAccess((error, localStream) => { if (error) { - this.camera.ee.emitEvent('access-denied-by-publisher'); + this.localStream.ee.emitEvent('access-denied-by-publisher'); let errorName: OpenViduErrorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED; let errorMessage = 'You must allow access to one window of your desktop'; let e = new OpenViduError(errorName, errorMessage); @@ -83,20 +98,26 @@ export class OpenViduInternal { } } else { - this.camera.setVideoElement(this.cameraReady(camera!, parentId)); - if (this.camera.getSendAudio()) { + this.localStream.setVideoElement(this.cameraReady(localStream!, parentId)); + if (this.localStream.getSendAudio()) { // If the user wants to send audio with the screen capturing navigator.mediaDevices.getUserMedia({ audio: true, video: false }) .then(userStream => { - this.camera.getMediaStream().addTrack(userStream.getAudioTracks()[0]); - this.camera.isScreenRequestedReady = true; - this.camera.ee.emitEvent('screen-ready'); + this.localStream.getMediaStream().addTrack(userStream.getAudioTracks()[0]); + + // Mute audio if 'activeAudio' property is false + if (userStream.getAudioTracks()[0] != null) { + userStream.getAudioTracks()[0].enabled = this.localStream.outboundOptions.activeAudio; + } + + this.localStream.isScreenRequestedReady = true; + this.localStream.ee.emitEvent('screen-ready'); if (callback) { callback(undefined); } }) .catch(error => { - this.camera.ee.emitEvent('access-denied-by-publisher'); + this.localStream.ee.emitEvent('access-denied-by-publisher'); console.error("Error accessing the microphone", error); if (callback) { let errorName: OpenViduErrorName = OpenViduErrorName.MICROPHONE_ACCESS_DENIED; @@ -105,8 +126,8 @@ export class OpenViduInternal { } }); } else { - this.camera.isScreenRequestedReady = true; - this.camera.ee.emitEvent('screen-ready'); + this.localStream.isScreenRequestedReady = true; + this.localStream.ee.emitEvent('screen-ready'); if (callback) { callback(undefined); } @@ -114,18 +135,18 @@ export class OpenViduInternal { } }); }); - return this.camera; + return this.localStream; } - cameraReady(camera: Stream, parentId: string) { - this.camera = camera; - let videoElement = this.camera.playOnlyVideo(parentId, null); - this.camera.emitStreamReadyEvent(); + cameraReady(localStream: Stream, parentId: string): HTMLVideoElement { + this.localStream = localStream; + let videoElement = this.localStream.playOnlyVideo(parentId, null); + this.localStream.emitStreamReadyEvent(); return videoElement; } getLocalStream() { - return this.camera; + return this.localStream; } getRemoteStreams() { @@ -327,29 +348,6 @@ export class OpenViduInternal { } } - getCamera(options?) { - - if (this.camera) { - return this.camera; - } - - options = options || { - sendAudio: true, - sendVideo: true, - activeAudio: true, - activeVideo: true, - data: true, - mediaConstraints: { - audio: true, - video: { width: { ideal: 1280 } } - } - } - options.connection = this.session.getLocalParticipant(); - - this.camera = new Stream(this, true, this.session, options); - return this.camera; - }; - //CHAT sendMessage(message) { this.sendRequest('sendMessage', { @@ -361,26 +359,6 @@ export class OpenViduInternal { }); }; - - - toggleLocalVideoTrack(activate: boolean) { - this.getCamera().getWebRtcPeer().videoEnabled = activate; - } - - toggleLocalAudioTrack(activate: boolean) { - this.getCamera().getWebRtcPeer().audioEnabled = activate; - } - - publishLocalVideoAudio() { - this.toggleLocalVideoTrack(true); - this.toggleLocalAudioTrack(true); - } - - unpublishLocalVideoAudio() { - this.toggleLocalVideoTrack(false); - this.toggleLocalAudioTrack(false); - } - generateMediaConstraints(cameraOptions: any) { let mediaConstraints = { audio: cameraOptions.audio, diff --git a/openvidu-browser/ts/OpenViduInternal/SessionInternal.ts b/openvidu-browser/ts/OpenViduInternal/SessionInternal.ts index db99285f..2737ffd8 100644 --- a/openvidu-browser/ts/OpenViduInternal/SessionInternal.ts +++ b/openvidu-browser/ts/OpenViduInternal/SessionInternal.ts @@ -1,9 +1,10 @@ -import { Stream } from './Stream'; +import { Stream, StreamOptionsServer } from './Stream'; import { OpenViduInternal } from './OpenViduInternal'; import { Connection, ConnectionOptions } from './Connection'; -import EventEmitter = require('wolfy87-eventemitter'); import { Publisher } from '../OpenVidu/Publisher'; +import EventEmitter = require('wolfy87-eventemitter'); + const SECRET_PARAM = '?secret='; export interface SessionOptions { @@ -119,7 +120,7 @@ export class SessionInternal { this.connected = true; - let exParticipants = response.value; + let exParticipants: ConnectionOptions[] = response.value; // IMPORTANT: Update connectionId with value send by server this.localParticipant.connectionId = response.id; @@ -256,19 +257,19 @@ export class SessionInternal { }); } - onParticipantPublished(options) { + onParticipantPublished(response: ConnectionOptions) { // Get the existing Connection created on 'onParticipantJoined' for // existing participants or create a new one for new participants - let connection = this.participants[options.id]; - if (connection) { + let connection: Connection = this.participants[response.id]; + if (connection != null) { // Update existing Connection - options.metadata = connection.data; - connection.options = options; - connection.initStreams(options); + response.metadata = connection.data; + connection.setOptions(response); + connection.initRemoteStreams(response); } else { // Create new Connection - connection = new Connection(this.openVidu, false, this, options); + connection = new Connection(this.openVidu, false, this, response); } let pid = connection.connectionId; @@ -320,6 +321,7 @@ export class SessionInternal { stream.dispose(); this.openVidu.getRemoteStreams().splice(index, 1); delete this.streams[stream.streamId]; + connection.removeStream(stream.streamId); } } else { @@ -329,9 +331,9 @@ export class SessionInternal { } } - onParticipantJoined(msg) { + onParticipantJoined(response: ConnectionOptions) { - let connection = new Connection(this.openVidu, false, this, msg); + let connection = new Connection(this.openVidu, false, this, response); connection.creationTime = new Date().getTime(); let pid = connection.connectionId; @@ -574,6 +576,8 @@ export class SessionInternal { stream.isReadyToPublish = false; stream.isScreenRequestedReady = false; + delete stream.connection.getStreams()[stream.streamId]; + publisher.ee.emitEvent('streamDestroyed', [{ stream: publisher.stream, preventDefault: () => { this.ee.removeEvent('stream-destroyed-default'); } diff --git a/openvidu-browser/ts/OpenViduInternal/Stream.ts b/openvidu-browser/ts/OpenViduInternal/Stream.ts index 969e582b..e219f8e6 100644 --- a/openvidu-browser/ts/OpenViduInternal/Stream.ts +++ b/openvidu-browser/ts/OpenViduInternal/Stream.ts @@ -32,17 +32,29 @@ function hide(id: string) { document.getElementById(jq(id))!.style.display = 'none'; } -export interface StreamOptions { +export interface StreamOptionsServer { + id: string; + audioActive: boolean; + videoActive: boolean; + typeOfVideo: string; +} + +export interface InboundStreamOptions { id: string; connection: Connection; - recvVideo: boolean; recvAudio: boolean; - sendVideo: boolean; - sendAudio: boolean; + recvVideo: boolean; + typeOfVideo: string; +} + +export interface OutboundStreamOptions { activeAudio: boolean; activeVideo: boolean; - data: boolean; + connection: Connection; + dataChannel: boolean; mediaConstraints: any; + sendAudio: boolean; + sendVideo: boolean; } export class Stream { @@ -58,19 +70,13 @@ export class Stream { private wp: any; private video: HTMLVideoElement; private speechEvent: any; - private recvVideo: boolean; - private recvAudio: boolean; - private sendVideo: boolean; - private sendAudio: boolean; - private mediaConstraints: any; private showMyRemote = false; private localMirrored = false; private chanId = 0; - private dataChannel: boolean; private dataChannelOpened = false; - private activeAudio = true; - private activeVideo = true; + inboundOptions: InboundStreamOptions; + outboundOptions: OutboundStreamOptions; private parentId: string; public isReadyToPublish: boolean = false; @@ -83,9 +89,17 @@ export class Stream { constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: any) { if (options !== 'screen-options') { - this.configureOptions(options); + if ('id' in options) { + this.inboundOptions = options; + } else { + this.outboundOptions = options; + } + this.streamId = (options.id != null) ? options.id : ((options.sendVideo) ? "CAMERA" : "MICRO"); + this.typeOfVideo = (options.typeOfVideo != null) ? options.typeOfVideo : ''; + this.connection = options.connection; } else { this.isScreenRequested = true; + this.typeOfVideo = 'SCREEN'; this.connection = this.room.getLocalParticipant(); } this.addEventListener('mediastream-updated', () => { @@ -131,19 +145,19 @@ export class Stream { } getRecvVideo() { - return this.recvVideo; + return this.inboundOptions.recvVideo; } getRecvAudio() { - return this.recvAudio; + return this.inboundOptions.recvAudio; } getSendVideo() { - return this.sendVideo; + return this.outboundOptions.sendVideo; } getSendAudio() { - return this.sendAudio; + return this.outboundOptions.sendAudio; } @@ -174,7 +188,7 @@ export class Stream { isDataChannelEnabled() { - return this.dataChannel; + return this.outboundOptions.dataChannel; } @@ -318,7 +332,7 @@ export class Stream { this.connection.addStream(this); - let constraints = this.mediaConstraints; + let constraints = this.outboundOptions.mediaConstraints; /*let constraints2 = { audio: true, @@ -334,14 +348,14 @@ export class Stream { this.userMediaHasVideo((hasVideo) => { if (!hasVideo) { - if (this.sendVideo) { + if (this.outboundOptions.sendVideo) { callback(new OpenViduError(OpenViduErrorName.NO_VIDEO_DEVICE, 'You have requested camera access but there is no video input device available. Trying to connect with an audio input device only'), this); } - if (!this.sendAudio) { + if (!this.outboundOptions.sendAudio) { callback(new OpenViduError(OpenViduErrorName.NO_INPUT_DEVICE, 'You must init Publisher object with audio or video streams enabled'), undefined); } else { constraints.video = false; - this.sendVideo = false; + this.outboundOptions.sendVideo = false; this.requestCameraAccesAux(constraints, callback); } } else { @@ -351,6 +365,7 @@ export class Stream { } private requestCameraAccesAux(constraints, callback) { + console.log(constraints); navigator.mediaDevices.getUserMedia(constraints) .then(userStream => { this.cameraAccessSuccess(userStream, callback); @@ -361,7 +376,7 @@ export class Stream { let errorName: OpenViduErrorName; let errorMessage = error.toString();; if (!this.isScreenRequested) { - errorName = this.sendVideo ? OpenViduErrorName.CAMERA_ACCESS_DENIED : OpenViduErrorName.MICROPHONE_ACCESS_DENIED; + errorName = this.outboundOptions.sendVideo ? OpenViduErrorName.CAMERA_ACCESS_DENIED : OpenViduErrorName.MICROPHONE_ACCESS_DENIED; } else { errorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED; // This code is only reachable for Firefox } @@ -375,10 +390,10 @@ export class Stream { this.ee.emitEvent('access-allowed-by-publisher'); if (userStream.getAudioTracks()[0] != null) { - userStream.getAudioTracks()[0].enabled = this.activeAudio; + userStream.getAudioTracks()[0].enabled = this.outboundOptions.activeAudio; } if (userStream.getVideoTracks()[0] != null) { - userStream.getVideoTracks()[0].enabled = this.activeVideo; + userStream.getVideoTracks()[0].enabled = this.outboundOptions.activeVideo; } this.mediaStream = userStream; @@ -416,9 +431,9 @@ export class Stream { this.openVidu.sendRequest("publishVideo", { sdpOffer: sdpOfferParam, doLoopback: this.displayMyRemote() || false, - audioActive: this.sendAudio, - videoActive: this.sendVideo, - typeOfVideo: ((this.sendVideo) ? ((this.isScreenRequested) ? 'SCREEN' :'CAMERA') : '') + audioActive: this.outboundOptions.sendAudio, + videoActive: this.outboundOptions.sendVideo, + typeOfVideo: ((this.outboundOptions.sendVideo) ? ((this.isScreenRequested) ? 'SCREEN' :'CAMERA') : '') }, (error, response) => { if (error) { console.error("Error on publishVideo: " + JSON.stringify(error)); @@ -452,8 +467,8 @@ export class Stream { if (this.local) { let userMediaConstraints = { - audio: this.sendAudio, - video: this.sendVideo + audio: this.outboundOptions.sendAudio, + video: this.outboundOptions.sendVideo } let options: any = { @@ -462,7 +477,7 @@ export class Stream { onicecandidate: this.connection.sendIceCandidate.bind(this.connection), } - if (this.dataChannel) { + if (this.outboundOptions.dataChannel) { options.dataChannelConfig = { id: this.getChannelName(), onopen: this.onDataChannelOpen, @@ -490,8 +505,8 @@ export class Stream { this.ee.emitEvent('stream-created-by-publisher'); } else { let offerConstraints = { - audio: this.recvAudio, - video: this.recvVideo + audio: this.inboundOptions.recvAudio, + video: this.inboundOptions.recvVideo }; console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); @@ -656,43 +671,8 @@ export class Stream { console.info((this.local ? "Local " : "Remote ") + "'Stream' with id [" + this.streamId + "]' has been succesfully disposed"); } - private configureOptions(options) { - 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.hasAudio = ((this.recvAudio || this.sendAudio) != undefined) ? (this.recvAudio || this.sendAudio) : false; - this.hasVideo = ((this.recvVideo || this.sendVideo) != undefined) ? (this.recvVideo || this.sendVideo) : false; - this.typeOfVideo = options.typeOfVideo; - - if (options.id) { - this.streamId = options.id; - } else { - this.streamId = this.sendVideo ? "WEBCAM" : "MICRO"; - } - } - - configureScreenOptions(options) { - if (options.id) { - this.streamId = options.id; - } else { - this.streamId = "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'); + configureScreenOptions(options: OutboundStreamOptions) { + this.outboundOptions = options; + this.streamId = "SCREEN"; } }