mirror of https://github.com/OpenVidu/openvidu.git
Merge branch 'openvidu_browser_refactor'
commit
bc65f454a2
|
@ -0,0 +1,4 @@
|
|||
npm run build
|
||||
npm pack
|
||||
cp openvidu-browser-2.14.0.tgz ../../openvidu-tutorials/openvidu-react-native
|
||||
cp openvidu-browser-2.14.0.tgz ../../openvidu-react-native-adapter/
|
|
@ -30,7 +30,6 @@ import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
|||
|
||||
import * as screenSharingAuto from '../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto';
|
||||
import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturing';
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
|
@ -748,115 +747,7 @@ export class OpenVidu {
|
|||
}
|
||||
|
||||
// CASE 4: deviceId or screen sharing
|
||||
if (typeof audioSource === 'string') {
|
||||
myConstraints.constraints!.audio = { deviceId: { exact: audioSource } };
|
||||
}
|
||||
if (typeof videoSource === 'string') {
|
||||
|
||||
if (!this.isScreenShare(videoSource)) {
|
||||
if (!myConstraints.constraints!.video) {
|
||||
myConstraints.constraints!.video = {};
|
||||
}
|
||||
(<MediaTrackConstraints>myConstraints.constraints!.video)['deviceId'] = { exact: videoSource };
|
||||
} else {
|
||||
|
||||
// Screen sharing
|
||||
|
||||
if (!this.checkScreenSharingCapabilities()) {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera, Safari (>=13.0) or Electron. Detected client: ' + platform.name);
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
} else {
|
||||
|
||||
if (platform.name === 'Electron') {
|
||||
const prefix = "screen:";
|
||||
const videoSourceString: string = videoSource;
|
||||
const electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length);
|
||||
(<any>myConstraints.constraints!.video) = {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: electronScreenId
|
||||
}
|
||||
};
|
||||
resolve(myConstraints);
|
||||
|
||||
} else {
|
||||
|
||||
if (!!this.advancedConfiguration.screenShareChromeExtension && !(platform.name!.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) {
|
||||
|
||||
// Custom screen sharing extension for Chrome (and Opera) and no support for MediaDevices.getDisplayMedia()
|
||||
|
||||
screenSharing.getScreenConstraints((error, screenConstraints) => {
|
||||
if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') {
|
||||
if (error === 'permission-denied' || error === 'PermissionDeniedError') {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
} else {
|
||||
const extensionId = this.advancedConfiguration.screenShareChromeExtension!.split('/').pop()!!.trim();
|
||||
screenSharing.getChromeExtensionStatus(extensionId, status => {
|
||||
if (status === 'installed-disabled') {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
}
|
||||
if (status === 'not-installed') {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, (<string>this.advancedConfiguration.screenShareChromeExtension));
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
myConstraints.constraints!.video = screenConstraints;
|
||||
resolve(myConstraints);
|
||||
}
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
|
||||
if (navigator.mediaDevices['getDisplayMedia']) {
|
||||
// getDisplayMedia support (Chrome >= 72, Firefox >= 66, Safari >= 13)
|
||||
resolve(myConstraints);
|
||||
} else {
|
||||
// Default screen sharing extension for Chrome/Opera, or is Firefox < 66
|
||||
const firefoxString = platform.name!.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined;
|
||||
|
||||
screenSharingAuto.getScreenId(firefoxString, (error, sourceId, screenConstraints) => {
|
||||
if (!!error) {
|
||||
if (error === 'not-installed') {
|
||||
const extensionUrl = !!this.advancedConfiguration.screenShareChromeExtension ? this.advancedConfiguration.screenShareChromeExtension :
|
||||
'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold';
|
||||
const err = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl);
|
||||
logger.error(err);
|
||||
reject(err);
|
||||
} else if (error === 'installed-disabled') {
|
||||
const err = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
|
||||
logger.error(err);
|
||||
reject(err);
|
||||
} else if (error === 'permission-denied') {
|
||||
const err = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
|
||||
logger.error(err);
|
||||
reject(err);
|
||||
} else {
|
||||
const err = new OpenViduError(OpenViduErrorName.GENERIC_ERROR, 'Unknown error when accessing screen share');
|
||||
logger.error(err);
|
||||
logger.error(error);
|
||||
reject(err);
|
||||
}
|
||||
} else {
|
||||
myConstraints.constraints!.video = screenConstraints.video;
|
||||
resolve(myConstraints);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.configureDeviceIdOrScreensharing(myConstraints, publisherProperties, resolve, reject);
|
||||
|
||||
resolve(myConstraints);
|
||||
});
|
||||
|
@ -984,6 +875,133 @@ export class OpenVidu {
|
|||
return mediaStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
protected configureDeviceIdOrScreensharing(myConstraints: CustomMediaStreamConstraints, publisherProperties: PublisherProperties, resolve, reject) {
|
||||
const audioSource = publisherProperties.audioSource;
|
||||
const videoSource = publisherProperties.videoSource;
|
||||
if (typeof audioSource === 'string') {
|
||||
myConstraints.constraints!.audio = { deviceId: { exact: audioSource } };
|
||||
}
|
||||
|
||||
if (typeof videoSource === 'string') {
|
||||
|
||||
if (!this.isScreenShare(videoSource)) {
|
||||
this.setVideoSource(myConstraints, videoSource);
|
||||
|
||||
} else {
|
||||
|
||||
// Screen sharing
|
||||
|
||||
if (!this.checkScreenSharingCapabilities()) {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera, Safari (>=13.0) or Electron. Detected client: ' + platform.name);
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
} else {
|
||||
|
||||
if (platform.name === 'Electron') {
|
||||
const prefix = "screen:";
|
||||
const videoSourceString: string = videoSource;
|
||||
const electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length);
|
||||
(<any>myConstraints.constraints!.video) = {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: electronScreenId
|
||||
}
|
||||
};
|
||||
resolve(myConstraints);
|
||||
|
||||
} else {
|
||||
|
||||
if (!!this.advancedConfiguration.screenShareChromeExtension && !(platform.name!.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) {
|
||||
|
||||
// Custom screen sharing extension for Chrome (and Opera) and no support for MediaDevices.getDisplayMedia()
|
||||
|
||||
screenSharing.getScreenConstraints((error, screenConstraints) => {
|
||||
if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') {
|
||||
if (error === 'permission-denied' || error === 'PermissionDeniedError') {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
} else {
|
||||
const extensionId = this.advancedConfiguration.screenShareChromeExtension!.split('/').pop()!!.trim();
|
||||
screenSharing.getChromeExtensionStatus(extensionId, status => {
|
||||
if (status === 'installed-disabled') {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
}
|
||||
if (status === 'not-installed') {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, (<string>this.advancedConfiguration.screenShareChromeExtension));
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
myConstraints.constraints!.video = screenConstraints;
|
||||
resolve(myConstraints);
|
||||
}
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
|
||||
if (navigator.mediaDevices['getDisplayMedia']) {
|
||||
// getDisplayMedia support (Chrome >= 72, Firefox >= 66, Safari >= 13)
|
||||
resolve(myConstraints);
|
||||
} else {
|
||||
// Default screen sharing extension for Chrome/Opera, or is Firefox < 66
|
||||
const firefoxString = platform.name!.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined;
|
||||
|
||||
screenSharingAuto.getScreenId(firefoxString, (error, sourceId, screenConstraints) => {
|
||||
if (!!error) {
|
||||
if (error === 'not-installed') {
|
||||
const extensionUrl = !!this.advancedConfiguration.screenShareChromeExtension ? this.advancedConfiguration.screenShareChromeExtension :
|
||||
'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold';
|
||||
const err = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl);
|
||||
logger.error(err);
|
||||
reject(err);
|
||||
} else if (error === 'installed-disabled') {
|
||||
const err = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
|
||||
logger.error(err);
|
||||
reject(err);
|
||||
} else if (error === 'permission-denied') {
|
||||
const err = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
|
||||
logger.error(err);
|
||||
reject(err);
|
||||
} else {
|
||||
const err = new OpenViduError(OpenViduErrorName.GENERIC_ERROR, 'Unknown error when accessing screen share');
|
||||
logger.error(err);
|
||||
logger.error(error);
|
||||
reject(err);
|
||||
}
|
||||
} else {
|
||||
myConstraints.constraints!.video = screenConstraints.video;
|
||||
resolve(myConstraints);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
protected setVideoSource(myConstraints: CustomMediaStreamConstraints, videoSource: string) {
|
||||
if (!myConstraints.constraints!.video) {
|
||||
myConstraints.constraints!.video = {};
|
||||
}
|
||||
(<MediaTrackConstraints>myConstraints.constraints!.video)['deviceId'] = { exact: videoSource };
|
||||
}
|
||||
|
||||
|
||||
/* Private methods */
|
||||
|
||||
private disconnectCallback(): void {
|
||||
|
|
|
@ -67,7 +67,7 @@ export class Publisher extends StreamManager {
|
|||
session: Session; // Initialized by Session.publish(Publisher)
|
||||
|
||||
private accessDenied = false;
|
||||
private properties: PublisherProperties;
|
||||
protected properties: PublisherProperties;
|
||||
private permissionDialogTimeout: NodeJS.Timer;
|
||||
|
||||
/**
|
||||
|
@ -385,19 +385,7 @@ export class Publisher extends StreamManager {
|
|||
mediaStream.getVideoTracks()[0].enabled = enabled;
|
||||
}
|
||||
|
||||
this.videoReference = document.createElement('video');
|
||||
|
||||
if (platform.name === 'Safari') {
|
||||
this.videoReference.setAttribute('playsinline', 'true');
|
||||
}
|
||||
|
||||
this.stream.setMediaStream(mediaStream);
|
||||
|
||||
if (!!this.firstVideoElement) {
|
||||
this.createVideoElement(this.firstVideoElement.targetElement, <VideoInsertMode>this.properties.insertMode);
|
||||
}
|
||||
|
||||
this.videoReference.srcObject = mediaStream;
|
||||
this.initializeVideoReference(mediaStream);
|
||||
|
||||
if (!this.stream.displayMyRemote()) {
|
||||
// When we are subscribed to our remote we don't still set the MediaStream object in the video elements to
|
||||
|
@ -443,7 +431,7 @@ export class Publisher extends StreamManager {
|
|||
// Rest of platforms
|
||||
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
|
||||
// Orientation must be checked for mobile devices (width and height are reversed)
|
||||
const { width, height } = mediaStream.getVideoTracks()[0].getSettings();
|
||||
const { width, height } = this.getVideoDimensions(mediaStream);
|
||||
|
||||
if ((platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') && (window.innerHeight > window.innerWidth)) {
|
||||
// Mobile portrait mode
|
||||
|
@ -666,6 +654,13 @@ export class Publisher extends StreamManager {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
getVideoDimensions(mediaStream: MediaStream): MediaTrackSettings {
|
||||
return mediaStream.getVideoTracks()[0].getSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
|
@ -675,6 +670,25 @@ export class Publisher extends StreamManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
initializeVideoReference(mediaStream: MediaStream) {
|
||||
this.videoReference = document.createElement('video');
|
||||
|
||||
if (platform.name === 'Safari') {
|
||||
this.videoReference.setAttribute('playsinline', 'true');
|
||||
}
|
||||
|
||||
this.stream.setMediaStream(mediaStream);
|
||||
|
||||
if (!!this.firstVideoElement) {
|
||||
this.createVideoElement(this.firstVideoElement.targetElement, <VideoInsertMode>this.properties.insertMode);
|
||||
}
|
||||
|
||||
this.videoReference.srcObject = mediaStream;
|
||||
}
|
||||
|
||||
|
||||
/* Private methods */
|
||||
|
||||
|
|
|
@ -1098,6 +1098,21 @@ export class Session extends EventDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
initializeParams(token: string) {
|
||||
const joinParams = {
|
||||
token: (!!token) ? token : '',
|
||||
session: this.sessionId,
|
||||
platform: !!platform.description ? platform.description : 'unknown',
|
||||
metadata: !!this.options.metadata ? this.options.metadata : '',
|
||||
secret: this.openvidu.getSecret(),
|
||||
recorder: this.openvidu.getRecorder()
|
||||
};
|
||||
return joinParams;
|
||||
}
|
||||
|
||||
|
||||
/* Private methods */
|
||||
|
||||
|
@ -1108,14 +1123,7 @@ export class Session extends EventDispatcher {
|
|||
reject(error);
|
||||
} else {
|
||||
|
||||
const joinParams = {
|
||||
token: (!!token) ? token : '',
|
||||
session: this.sessionId,
|
||||
platform: !!platform.description ? platform.description : 'unknown',
|
||||
metadata: !!this.options.metadata ? this.options.metadata : '',
|
||||
secret: this.openvidu.getSecret(),
|
||||
recorder: this.openvidu.getRecorder()
|
||||
};
|
||||
const joinParams = this.initializeParams(token);
|
||||
|
||||
this.openvidu.sendRequest('joinRoom', joinParams, (error, response) => {
|
||||
if (!!error) {
|
||||
|
@ -1193,7 +1201,7 @@ export class Session extends EventDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
private getConnection(connectionId: string, errorMessage: string): Promise<Connection> {
|
||||
protected getConnection(connectionId: string, errorMessage: string): Promise<Connection> {
|
||||
return new Promise<Connection>((resolve, reject) => {
|
||||
const connection = this.remoteConnections[connectionId];
|
||||
if (!!connection) {
|
||||
|
|
|
@ -133,8 +133,8 @@ export class Stream extends EventDispatcher {
|
|||
*/
|
||||
filter: Filter;
|
||||
|
||||
private webRtcPeer: WebRtcPeer;
|
||||
private mediaStream: MediaStream;
|
||||
protected webRtcPeer: WebRtcPeer;
|
||||
protected mediaStream: MediaStream;
|
||||
private webRtcStats: WebRtcStats;
|
||||
|
||||
private isSubscribeToRemote = false;
|
||||
|
@ -964,7 +964,10 @@ export class Stream extends EventDispatcher {
|
|||
});
|
||||
}
|
||||
|
||||
private remotePeerSuccessfullyEstablished(): void {
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
remotePeerSuccessfullyEstablished(): void {
|
||||
this.mediaStream = new MediaStream();
|
||||
let receiver: RTCRtpReceiver;
|
||||
for (receiver of this.webRtcPeer.pc.getReceivers()) {
|
||||
|
|
|
@ -297,7 +297,7 @@ export class StreamManager extends EventDispatcher {
|
|||
throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement);
|
||||
}
|
||||
|
||||
const video = document.createElement('video');
|
||||
const video = this.createVideo();
|
||||
this.initializeVideoProperties(video);
|
||||
|
||||
let insMode = !!insertMode ? insertMode : VideoInsertMode.APPEND;
|
||||
|
@ -414,8 +414,9 @@ export class StreamManager extends EventDispatcher {
|
|||
|
||||
this.videos.forEach(streamManagerVideo => {
|
||||
// Remove oncanplay event listener (only OpenVidu browser listener, not the user ones)
|
||||
streamManagerVideo.video.removeEventListener('canplay', this.canPlayListener);
|
||||
streamManagerVideo.canplayListenerAdded = false;
|
||||
if(!!streamManagerVideo.video && !!streamManagerVideo.video.removeEventListener){
|
||||
streamManagerVideo.video.removeEventListener('canplay', this.canPlayListener);
|
||||
} streamManagerVideo.canplayListenerAdded = false;
|
||||
if (!!streamManagerVideo.targetElement) {
|
||||
// Only remove from DOM videos created by OpenVidu Browser (those generated by passing a valid targetElement in OpenVidu.initPublisher
|
||||
// and Session.subscribe or those created by StreamManager.createVideoElement). All this videos triggered a videoElementCreated event
|
||||
|
@ -423,7 +424,7 @@ export class StreamManager extends EventDispatcher {
|
|||
this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent(streamManagerVideo.video, this, 'videoElementDestroyed')]);
|
||||
}
|
||||
// Remove srcObject from the video
|
||||
streamManagerVideo.video.srcObject = null;
|
||||
this.removeSrcObject(streamManagerVideo);
|
||||
// Remove from collection of videos every video managed by OpenVidu Browser
|
||||
this.videos.filter(v => !v.targetElement);
|
||||
});
|
||||
|
@ -480,9 +481,23 @@ export class StreamManager extends EventDispatcher {
|
|||
this.ee.emitEvent(type, eventArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
createVideo(): HTMLVideoElement {
|
||||
return document.createElement('video');
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
removeSrcObject(streamManagerVideo: StreamManagerVideo) {
|
||||
streamManagerVideo.video.srcObject = null;
|
||||
}
|
||||
|
||||
/* Private methods */
|
||||
|
||||
private pushNewStreamManagerVideo(streamManagerVideo: StreamManagerVideo) {
|
||||
protected pushNewStreamManagerVideo(streamManagerVideo: StreamManagerVideo) {
|
||||
this.videos.push(streamManagerVideo);
|
||||
this.addPlayEventToFirstVideo();
|
||||
if (this.stream.session.streamManagers.indexOf(this) === -1) {
|
||||
|
|
|
@ -2,16 +2,19 @@
|
|||
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);
|
||||
});
|
||||
if(typeof window !== 'undefined' && typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined'){
|
||||
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) {
|
||||
|
@ -148,7 +151,7 @@ function getScreenConstraints(callback, captureSourceIdWithAudio) {
|
|||
return;
|
||||
}
|
||||
|
||||
// this statement sets gets 'sourceId" and sets "chromeMediaSourceId"
|
||||
// this statement sets gets 'sourceId" and sets "chromeMediaSourceId"
|
||||
if (chromeMediaSource == 'desktop') {
|
||||
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
|
||||
}
|
||||
|
|
|
@ -49,11 +49,11 @@ export class WebRtcPeer {
|
|||
|
||||
private candidategatheringdone = false;
|
||||
|
||||
constructor(private configuration: WebRtcPeerConfiguration) {
|
||||
constructor(protected configuration: WebRtcPeerConfiguration) {
|
||||
this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice();
|
||||
|
||||
this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers });
|
||||
this.id = !!configuration.id ? configuration.id : uuid.v4();
|
||||
this.id = !!configuration.id ? configuration.id : this.generateUniqueId();
|
||||
|
||||
this.pc.onicecandidate = event => {
|
||||
if (!!event.candidate) {
|
||||
|
@ -71,7 +71,8 @@ export class WebRtcPeer {
|
|||
this.pc.onsignalingstatechange = () => {
|
||||
if (this.pc.signalingState === 'stable') {
|
||||
while (this.iceCandidateList.length > 0) {
|
||||
this.pc.addIceCandidate(<RTCIceCandidate>this.iceCandidateList.shift());
|
||||
let candidate = this.iceCandidateList.shift();
|
||||
this.pc.addIceCandidate(<RTCIceCandidate>candidate);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -206,25 +207,34 @@ export class WebRtcPeer {
|
|||
if (this.pc.signalingState === 'closed') {
|
||||
reject('RTCPeerConnection is closed');
|
||||
}
|
||||
if (platform['isIonicIos']) {
|
||||
// Ionic iOS platform
|
||||
if (needsTimeoutOnProcessAnswer) {
|
||||
// 400 ms have not elapsed yet since first remote stream triggered Stream#initWebRtcPeerReceive
|
||||
setTimeout(() => {
|
||||
logger.info('setRemoteDescription run after timeout for Ionic iOS device');
|
||||
this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(() => resolve()).catch(error => reject(error));
|
||||
}, 250);
|
||||
} else {
|
||||
// 400 ms have elapsed
|
||||
this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(() => resolve()).catch(error => reject(error));
|
||||
}
|
||||
} else {
|
||||
// Rest of platforms
|
||||
this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error));
|
||||
}
|
||||
|
||||
this.setRemoteDescription(answer, needsTimeoutOnProcessAnswer, resolve, reject);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
setRemoteDescription(answer: RTCSessionDescriptionInit, needsTimeoutOnProcessAnswer: boolean, resolve: (value?: string | PromiseLike<string> | undefined) => void, reject: (reason?: any) => void) {
|
||||
if (platform['isIonicIos']) {
|
||||
// Ionic iOS platform
|
||||
if (needsTimeoutOnProcessAnswer) {
|
||||
// 400 ms have not elapsed yet since first remote stream triggered Stream#initWebRtcPeerReceive
|
||||
setTimeout(() => {
|
||||
logger.info('setRemoteDescription run after timeout for Ionic iOS device');
|
||||
this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(() => resolve()).catch(error => reject(error));
|
||||
}, 250);
|
||||
} else {
|
||||
// 400 ms have elapsed
|
||||
this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(() => resolve()).catch(error => reject(error));
|
||||
}
|
||||
} else {
|
||||
// Rest of platforms
|
||||
this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function invoked when an ICE candidate is received
|
||||
*/
|
||||
|
@ -281,6 +291,13 @@ export class WebRtcPeer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
generateUniqueId(): string {
|
||||
return uuid.v4();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue