mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: IE master branch rollback
parent
c6bc6c9d39
commit
2bad86e108
|
@ -36,9 +36,6 @@ import EventEmitter = require('wolfy87-eventemitter');
|
||||||
import RpcBuilder = require('../OpenViduInternal/KurentoUtils/kurento-jsonrpc');
|
import RpcBuilder = require('../OpenViduInternal/KurentoUtils/kurento-jsonrpc');
|
||||||
import platform = require('platform');
|
import platform = require('platform');
|
||||||
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua!!.indexOf('Safari') === -1;
|
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua!!.indexOf('Safari') === -1;
|
||||||
platform['isInternetExplorer'] = platform.name === 'IE' && platform.version !== undefined && parseInt(platform.version) >= 11;
|
|
||||||
platform['isReactNative'] = navigator.product === 'ReactNative';
|
|
||||||
declare const AdapterJS: any;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
|
@ -108,12 +105,6 @@ export class OpenVidu {
|
||||||
console.info("'OpenVidu' initialized");
|
console.info("'OpenVidu' initialized");
|
||||||
console.info("openvidu-browser version: " + this.libraryVersion);
|
console.info("openvidu-browser version: " + this.libraryVersion);
|
||||||
|
|
||||||
if (platform['isInternetExplorer']) {
|
|
||||||
console.info("Detected IE Explorer " + platform.version);
|
|
||||||
this.importIEAdapterJS();
|
|
||||||
this.setGlobalIEFunctions();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') {
|
if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') {
|
||||||
// Listen to orientationchange only on mobile devices
|
// Listen to orientationchange only on mobile devices
|
||||||
(<any>window).addEventListener('orientationchange', () => {
|
(<any>window).addEventListener('orientationchange', () => {
|
||||||
|
@ -342,8 +333,7 @@ export class OpenVidu {
|
||||||
(browser !== 'Chrome') && (browser !== 'Chrome Mobile') &&
|
(browser !== 'Chrome') && (browser !== 'Chrome Mobile') &&
|
||||||
(browser !== 'Firefox') && (browser !== 'Firefox Mobile') &&
|
(browser !== 'Firefox') && (browser !== 'Firefox Mobile') &&
|
||||||
(browser !== 'Opera') && (browser !== 'Opera Mobile') &&
|
(browser !== 'Opera') && (browser !== 'Opera Mobile') &&
|
||||||
(browser !== 'Android Browser') && (browser !== 'Electron') &&
|
(browser !== 'Android Browser') && (browser !== 'Electron')
|
||||||
(browser !== 'IE' || platform.version !== undefined && parseInt(platform.version) < 11)
|
|
||||||
) {
|
) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -449,31 +439,20 @@ export class OpenVidu {
|
||||||
return new Promise<MediaStream>((resolve, reject) => {
|
return new Promise<MediaStream>((resolve, reject) => {
|
||||||
this.generateMediaConstraints(options)
|
this.generateMediaConstraints(options)
|
||||||
.then(constraints => {
|
.then(constraints => {
|
||||||
|
navigator.mediaDevices.getUserMedia(constraints)
|
||||||
let userMediaFunc = () => {
|
.then(mediaStream => {
|
||||||
navigator.mediaDevices.getUserMedia(constraints)
|
resolve(mediaStream);
|
||||||
.then(mediaStream => {
|
})
|
||||||
resolve(mediaStream);
|
.catch(error => {
|
||||||
})
|
let errorName: OpenViduErrorName;
|
||||||
.catch(error => {
|
const errorMessage = error.toString();
|
||||||
let errorName: OpenViduErrorName;
|
if (!(options.videoSource === 'screen')) {
|
||||||
const errorMessage = error.toString();
|
errorName = OpenViduErrorName.DEVICE_ACCESS_DENIED;
|
||||||
if (!(options.videoSource === 'screen')) {
|
} else {
|
||||||
errorName = OpenViduErrorName.DEVICE_ACCESS_DENIED;
|
errorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED;
|
||||||
} else {
|
}
|
||||||
errorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED;
|
reject(new OpenViduError(errorName, errorMessage));
|
||||||
}
|
|
||||||
reject(new OpenViduError(errorName, errorMessage));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platform['isInternetExplorer']) {
|
|
||||||
AdapterJS.webRTCReady(isUsingPlugin => {
|
|
||||||
userMediaFunc();
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
userMediaFunc();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch((error: OpenViduError) => {
|
.catch((error: OpenViduError) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
|
@ -791,59 +770,4 @@ export class OpenVidu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private importIEAdapterJS(): void {
|
|
||||||
const moduleSpecifier = 'https://cdn.temasys.io/adapterjs/0.15.x/adapter.min.js';
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.src = moduleSpecifier;
|
|
||||||
var ref = document.querySelector('script');
|
|
||||||
|
|
||||||
if (ref && ref.parentNode) {
|
|
||||||
ref.parentNode.insertBefore(script, ref);
|
|
||||||
console.info("IE AdapterJS imported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setGlobalIEFunctions(): void {
|
|
||||||
// FIX: the IE plugin seems to require the handler functions to be globally accessible. Store the functions with unique streamId
|
|
||||||
|
|
||||||
// Global handler for onloadedmetadata
|
|
||||||
(<any>window).IEOnLoadedMetadata = (simVideo: HTMLVideoElement, str: Stream) => {
|
|
||||||
const videoDimensionsSet = () => {
|
|
||||||
str.videoDimensions = {
|
|
||||||
width: simVideo.videoWidth,
|
|
||||||
height: simVideo.videoHeight
|
|
||||||
};
|
|
||||||
str.isLocalStreamReadyToPublish = true;
|
|
||||||
str.ee.emitEvent('stream-ready-to-publish', []);
|
|
||||||
};
|
|
||||||
let interval;
|
|
||||||
if (simVideo.videoWidth === 0) {
|
|
||||||
interval = setInterval(() => {
|
|
||||||
if (simVideo.videoWidth !== 0) {
|
|
||||||
clearInterval(interval);
|
|
||||||
videoDimensionsSet();
|
|
||||||
}
|
|
||||||
}, 40);
|
|
||||||
} else {
|
|
||||||
videoDimensionsSet();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Global handler for oncanplay
|
|
||||||
(<any>window).IEOnCanPlay = (strManager: StreamManager) => {
|
|
||||||
if (strManager.stream.isLocal()) {
|
|
||||||
if (!strManager.stream.displayMyRemote()) {
|
|
||||||
console.info("Your local 'Stream' with id [" + strManager.stream.streamId + '] video is now playing');
|
|
||||||
strManager.ee.emitEvent('videoPlaying', [new VideoElementEvent(strManager.videos[0].video, strManager, 'videoPlaying')]);
|
|
||||||
} else {
|
|
||||||
console.info("Your own remote 'Stream' with id [" + strManager.stream.streamId + '] video is now playing');
|
|
||||||
strManager.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent(strManager.videos[0].video, strManager, 'remoteVideoPlaying')]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.info("Remote 'Stream' with id [" + strManager.stream.streamId + '] video is now playing');
|
|
||||||
strManager.ee.emitEvent('videoPlaying', [new VideoElementEvent(strManager.videos[0].video, strManager, 'videoPlaying')]);
|
|
||||||
}
|
|
||||||
strManager.ee.emitEvent('streamPlaying', [new StreamManagerEvent(strManager, 'streamPlaying', undefined)]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -29,7 +29,6 @@ import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/Open
|
||||||
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
||||||
|
|
||||||
import platform = require('platform');
|
import platform = require('platform');
|
||||||
declare const AdapterJS: any;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Packs local media streams. Participants can publish it to a session. Initialized with [[OpenVidu.initPublisher]] method
|
* Packs local media streams. Participants can publish it to a session. Initialized with [[OpenVidu.initPublisher]] method
|
||||||
|
@ -317,36 +316,12 @@ export class Publisher extends StreamManager {
|
||||||
this.stream.setMediaStream(mediaStream);
|
this.stream.setMediaStream(mediaStream);
|
||||||
|
|
||||||
if (!!this.firstVideoElement) {
|
if (!!this.firstVideoElement) {
|
||||||
let video = this.createVideoElement(this.firstVideoElement.targetElement, <VideoInsertMode>this.properties.insertMode);
|
this.createVideoElement(this.firstVideoElement.targetElement, <VideoInsertMode>this.properties.insertMode);
|
||||||
if (platform['isInternetExplorer']) {
|
|
||||||
this.videoReference = video;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (platform['isInternetExplorer']) {
|
|
||||||
// IE cannot have a video reference not inserted into DOM
|
|
||||||
// Pick up the first video element of videos array
|
|
||||||
this.videoReference = this.videos[0].video;
|
|
||||||
if (!this.videoReference) {
|
|
||||||
console.warn('IE requires the video element to be defined when initializing a Publisher. ' +
|
|
||||||
'Be sure to initialize the publisher passing a pre-existing targetElement')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform['isInternetExplorer']) {
|
this.videoReference.srcObject = mediaStream;
|
||||||
AdapterJS.webRTCReady(isUsingPlugin => {
|
|
||||||
this.videoReference = this.customAttachMediaStreamIE(this.videoReference, mediaStream);
|
|
||||||
if (this.stream.isSendVideo()) {
|
|
||||||
if (!this.stream.isSendScreen()) {
|
|
||||||
this.videoReference.addEventListener('loadedmetadata', (<any>window).IEOnLoadedMetadata(this.videoReference, this.stream));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.videoReference.srcObject = mediaStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.stream.displayMyRemote() && (platform.name !== 'IE')) {
|
if (!this.stream.displayMyRemote()) {
|
||||||
// When we are subscribed to our remote we don't still set the MediaStream object in the video elements to
|
// When we are subscribed to our remote we don't still set the MediaStream object in the video elements to
|
||||||
// avoid early 'streamPlaying' event
|
// avoid early 'streamPlaying' event
|
||||||
this.stream.updateMediaStreamInVideos();
|
this.stream.updateMediaStreamInVideos();
|
||||||
|
@ -386,8 +361,8 @@ export class Publisher extends StreamManager {
|
||||||
videoDimensionsSet();
|
videoDimensionsSet();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (platform.name !== 'IE') {
|
} else {
|
||||||
// Rest of platforms except IE
|
// Rest of platforms
|
||||||
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
|
// 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)
|
// Orientation must be checked for mobile devices (width and height are reversed)
|
||||||
const { width, height } = mediaStream.getVideoTracks()[0].getSettings();
|
const { width, height } = mediaStream.getVideoTracks()[0].getSettings();
|
||||||
|
@ -630,23 +605,13 @@ export class Publisher extends StreamManager {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
let userMediaFunc = () => {
|
navigator.mediaDevices.getUserMedia(constraintsAux)
|
||||||
navigator.mediaDevices.getUserMedia(constraintsAux)
|
.then(mediaStream => {
|
||||||
.then(mediaStream => {
|
getMediaSuccess(mediaStream, definedAudioConstraint);
|
||||||
getMediaSuccess(mediaStream, definedAudioConstraint);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
getMediaError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platform['isInternetExplorer']) {
|
|
||||||
AdapterJS.webRTCReady(isUsingPlugin => {
|
|
||||||
userMediaFunc();
|
|
||||||
})
|
})
|
||||||
} else {
|
.catch(error => {
|
||||||
userMediaFunc();
|
getMediaError(error);
|
||||||
}
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -882,17 +882,10 @@ export class Session implements EventDispatcher {
|
||||||
this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate)
|
this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate)
|
||||||
.then(connection => {
|
.then(connection => {
|
||||||
const stream = connection.stream;
|
const stream = connection.stream;
|
||||||
if (platform['isInternetExplorer']) {
|
stream.getWebRtcPeer().addIceCandidate(candidate).catch(error => {
|
||||||
(<any>stream.getWebRtcPeer()).addIceCandidate(candidate, () => { }, error => {
|
console.error('Error adding candidate for ' + stream.streamId
|
||||||
console.error('Error adding candidate for ' + stream.streamId
|
+ ' stream of endpoint ' + msg.endpointName + ': ' + error);
|
||||||
+ ' stream of endpoint ' + msg.endpointName + ': ' + error);
|
});
|
||||||
});
|
|
||||||
} else {
|
|
||||||
stream.getWebRtcPeer().addIceCandidate(candidate).catch(error => {
|
|
||||||
console.error('Error adding candidate for ' + stream.streamId
|
|
||||||
+ ' stream of endpoint ' + msg.endpointName + ': ' + error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch(openViduError => {
|
.catch(openViduError => {
|
||||||
console.error(openViduError);
|
console.error(openViduError);
|
||||||
|
|
|
@ -34,7 +34,6 @@ import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/Open
|
||||||
import EventEmitter = require('wolfy87-eventemitter');
|
import EventEmitter = require('wolfy87-eventemitter');
|
||||||
import hark = require('hark');
|
import hark = require('hark');
|
||||||
import platform = require('platform');
|
import platform = require('platform');
|
||||||
declare const AdapterJS: any;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -799,30 +798,20 @@ export class Stream implements EventDispatcher {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const initWebRtcPeer = () => {
|
this.webRtcPeer = new WebRtcPeerRecvonly(options);
|
||||||
this.webRtcPeer = new WebRtcPeerRecvonly(options);
|
this.webRtcPeer.generateOffer()
|
||||||
this.webRtcPeer.generateOffer()
|
.then(offer => {
|
||||||
.then(offer => {
|
successCallback(offer);
|
||||||
successCallback(offer);
|
})
|
||||||
})
|
.catch(error => {
|
||||||
.catch(error => {
|
reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error)));
|
||||||
reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error)));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (platform['isInternetExplorer']) {
|
|
||||||
AdapterJS.webRTCReady(isUsingPlugin => {
|
|
||||||
initWebRtcPeer();
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
initWebRtcPeer();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private remotePeerSuccessfullyEstablished(): void {
|
private remotePeerSuccessfullyEstablished(): void {
|
||||||
if (platform['isIonicIos'] || platform['isInternetExplorer']) {
|
if (platform['isIonicIos']) {
|
||||||
// iOS Ionic or IExplorer. LIMITATION: must use deprecated WebRTC API
|
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
|
||||||
const pc1: any = this.webRtcPeer.pc;
|
const pc1: any = this.webRtcPeer.pc;
|
||||||
this.mediaStream = pc1.getRemoteStreams()[0];
|
this.mediaStream = pc1.getRemoteStreams()[0];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
||||||
|
|
||||||
import EventEmitter = require('wolfy87-eventemitter');
|
import EventEmitter = require('wolfy87-eventemitter');
|
||||||
import platform = require('platform');
|
import platform = require('platform');
|
||||||
declare const attachMediaStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface in charge of displaying the media streams in the HTML DOM. This wraps any [[Publisher]] and [[Subscriber]] object.
|
* Interface in charge of displaying the media streams in the HTML DOM. This wraps any [[Publisher]] and [[Subscriber]] object.
|
||||||
|
@ -121,23 +120,22 @@ export class StreamManager implements EventDispatcher {
|
||||||
this.element = targEl;
|
this.element = targEl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!platform['isInternetExplorer']) {
|
|
||||||
this.canPlayListener = () => {
|
this.canPlayListener = () => {
|
||||||
if (this.stream.isLocal()) {
|
if (this.stream.isLocal()) {
|
||||||
if (!this.stream.displayMyRemote()) {
|
if (!this.stream.displayMyRemote()) {
|
||||||
console.info("Your local 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
console.info("Your local 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
|
||||||
} else {
|
|
||||||
console.info("Your own remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
|
||||||
this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.info("Remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
|
||||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||||
|
} else {
|
||||||
|
console.info("Your own remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||||
|
this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]);
|
||||||
}
|
}
|
||||||
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent(this, 'streamPlaying', undefined)]);
|
} else {
|
||||||
};
|
console.info("Remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||||
}
|
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||||
|
}
|
||||||
|
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent(this, 'streamPlaying', undefined)]);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,10 +243,6 @@ export class StreamManager implements EventDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform['isInternetExplorer'] && !!this.stream.getMediaStream()) {
|
|
||||||
video = this.customAttachMediaStreamIE(video, this.stream.getMediaStream());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the video element is already part of this StreamManager do nothing
|
// If the video element is already part of this StreamManager do nothing
|
||||||
for (const v of this.videos) {
|
for (const v of this.videos) {
|
||||||
if (v.video === video) {
|
if (v.video === video) {
|
||||||
|
@ -305,7 +299,7 @@ export class StreamManager implements EventDispatcher {
|
||||||
throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement);
|
throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
let video = document.createElement('video');
|
const video = document.createElement('video');
|
||||||
this.initializeVideoProperties(video);
|
this.initializeVideoProperties(video);
|
||||||
|
|
||||||
let insMode = !!insertMode ? insertMode : VideoInsertMode.APPEND;
|
let insMode = !!insertMode ? insertMode : VideoInsertMode.APPEND;
|
||||||
|
@ -331,10 +325,6 @@ export class StreamManager implements EventDispatcher {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform['isInternetExplorer'] && !!this.stream.getMediaStream()) {
|
|
||||||
video = this.customAttachMediaStreamIE(video, this.stream.getMediaStream());
|
|
||||||
}
|
|
||||||
|
|
||||||
const v: StreamManagerVideo = {
|
const v: StreamManagerVideo = {
|
||||||
targetElement: targEl,
|
targetElement: targEl,
|
||||||
video,
|
video,
|
||||||
|
@ -344,12 +334,8 @@ export class StreamManager implements EventDispatcher {
|
||||||
};
|
};
|
||||||
this.pushNewStreamManagerVideo(v);
|
this.pushNewStreamManagerVideo(v);
|
||||||
|
|
||||||
let launchVideoCreatedEvent = !platform['isInternetExplorer'];
|
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent(v.video, this, 'videoElementCreated')]);
|
||||||
if (launchVideoCreatedEvent) {
|
this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement;
|
||||||
// For IE the event is called in this.customAttachMediaStreamIE
|
|
||||||
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent(v.video, this, 'videoElementCreated')]);
|
|
||||||
}
|
|
||||||
this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement && launchVideoCreatedEvent;
|
|
||||||
|
|
||||||
return video;
|
return video;
|
||||||
}
|
}
|
||||||
|
@ -372,7 +358,7 @@ export class StreamManager implements EventDispatcher {
|
||||||
video.setAttribute('playsinline', 'true');
|
video.setAttribute('playsinline', 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!video.id && !platform['isInternetExplorer']) {
|
if (!video.id) {
|
||||||
video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId;
|
video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId;
|
||||||
// DEPRECATED property: assign once the property id if the user provided a valid targetElement
|
// DEPRECATED property: assign once the property id if the user provided a valid targetElement
|
||||||
if (!this.id && !!this.targetElement) {
|
if (!this.id && !!this.targetElement) {
|
||||||
|
@ -403,7 +389,7 @@ export class StreamManager implements EventDispatcher {
|
||||||
|
|
||||||
this.videos.forEach(streamManagerVideo => {
|
this.videos.forEach(streamManagerVideo => {
|
||||||
// Remove oncanplay event listener (only OpenVidu browser listener, not the user ones)
|
// Remove oncanplay event listener (only OpenVidu browser listener, not the user ones)
|
||||||
streamManagerVideo.video.removeEventListener('canplay', platform['isInternetExplorer'] ? (<any>window).IEOnCanPlay : this.canPlayListener);
|
streamManagerVideo.video.removeEventListener('canplay', this.canPlayListener);
|
||||||
streamManagerVideo.canplayListenerAdded = false;
|
streamManagerVideo.canplayListenerAdded = false;
|
||||||
if (!!streamManagerVideo.targetElement) {
|
if (!!streamManagerVideo.targetElement) {
|
||||||
// Only remove from DOM videos created by OpenVidu Browser (those generated by passing a valid targetElement in OpenVidu.initPublisher
|
// Only remove from DOM videos created by OpenVidu Browser (those generated by passing a valid targetElement in OpenVidu.initPublisher
|
||||||
|
@ -425,7 +411,7 @@ export class StreamManager implements EventDispatcher {
|
||||||
let disassociated = false;
|
let disassociated = false;
|
||||||
for (let i = 0; i < this.videos.length; i++) {
|
for (let i = 0; i < this.videos.length; i++) {
|
||||||
if (this.videos[i].video === video) {
|
if (this.videos[i].video === video) {
|
||||||
this.videos[i].video.removeEventListener('canplay', platform['isInternetExplorer'] ? (<any>window).IEOnCanPlay : this.canPlayListener);
|
this.videos[i].video.removeEventListener('canplay', this.canPlayListener);
|
||||||
this.videos.splice(i, 1);
|
this.videos.splice(i, 1);
|
||||||
disassociated = true;
|
disassociated = true;
|
||||||
console.info('Video element disassociated from ', this);
|
console.info('Video element disassociated from ', this);
|
||||||
|
@ -440,14 +426,7 @@ export class StreamManager implements EventDispatcher {
|
||||||
*/
|
*/
|
||||||
addPlayEventToFirstVideo() {
|
addPlayEventToFirstVideo() {
|
||||||
if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) {
|
if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) {
|
||||||
if (platform['isInternetExplorer']) {
|
this.videos[0].video.addEventListener('canplay', this.canPlayListener);
|
||||||
if (!(this.videos[0].video instanceof HTMLVideoElement)) {
|
|
||||||
// Add canplay event listener only after plugin has inserted custom video element (not a DOM HTMLVideoElement)
|
|
||||||
(<any>this.videos[0].video).addEventListener('canplay', (<any>window).IEOnCanPlay(this));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.videos[0].video.addEventListener('canplay', this.canPlayListener);
|
|
||||||
}
|
|
||||||
this.videos[0].canplayListenerAdded = true;
|
this.videos[0].canplayListenerAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,9 +445,6 @@ export class StreamManager implements EventDispatcher {
|
||||||
vParent!!.replaceChild(newVideo, streamManagerVideo.video);
|
vParent!!.replaceChild(newVideo, streamManagerVideo.video);
|
||||||
streamManagerVideo.video = newVideo;
|
streamManagerVideo.video = newVideo;
|
||||||
}
|
}
|
||||||
if (platform['isInternetExplorer']) {
|
|
||||||
this.customAttachMediaStreamIE(streamManagerVideo.video, mediaStream);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,30 +475,4 @@ export class StreamManager implements EventDispatcher {
|
||||||
video.style.webkitTransform = 'unset';
|
video.style.webkitTransform = 'unset';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected customAttachMediaStreamIE(video: HTMLVideoElement, mediaStream: MediaStream): HTMLVideoElement {
|
|
||||||
var simVideo = attachMediaStream(video, mediaStream);
|
|
||||||
|
|
||||||
if (!simVideo) {
|
|
||||||
console.error('The video element used by IE to insert its custom media element is not properly added to DOM (must be inserted and visible)');
|
|
||||||
console.error(video);
|
|
||||||
return simVideo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace HTMLVideoElemet (if exists) with new HTMLObjectElement returned by IE plugin
|
|
||||||
for (let i = 0; i < this.videos.length; i++) {
|
|
||||||
if (this.videos[i].video === video) {
|
|
||||||
this.videos[i].video = simVideo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always launch videoElementCreated event after IE plugin has inserted simulated video into DOM
|
|
||||||
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent(simVideo, this, 'videoElementCreated')]);
|
|
||||||
|
|
||||||
// Add streamPlaying event to newly inserted video if necessary
|
|
||||||
this.addPlayEventToFirstVideo();
|
|
||||||
|
|
||||||
return simVideo;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -65,20 +65,7 @@ export class WebRtcPeer {
|
||||||
this.pc.onsignalingstatechange = () => {
|
this.pc.onsignalingstatechange = () => {
|
||||||
if (this.pc.signalingState === 'stable') {
|
if (this.pc.signalingState === 'stable') {
|
||||||
while (this.iceCandidateList.length > 0) {
|
while (this.iceCandidateList.length > 0) {
|
||||||
if (platform['isInternetExplorer']) {
|
this.pc.addIceCandidate(<RTCIceCandidate>this.iceCandidateList.shift());
|
||||||
const iceCandidate = this.iceCandidateList.shift();
|
|
||||||
if (!!iceCandidate) {
|
|
||||||
const iceCandidateAuxIE = {
|
|
||||||
candidate: iceCandidate.candidate,
|
|
||||||
sdpMid: iceCandidate.sdpMid,
|
|
||||||
sdpMLineIndex: iceCandidate.sdpMLineIndex
|
|
||||||
};
|
|
||||||
const finalIECandidate = new RTCIceCandidate(iceCandidateAuxIE);
|
|
||||||
(<any>this.pc).addIceCandidate(finalIECandidate, () => { }, () => { });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.pc.addIceCandidate(<RTCIceCandidate>this.iceCandidateList.shift());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -99,8 +86,8 @@ export class WebRtcPeer {
|
||||||
reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue');
|
reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue');
|
||||||
}
|
}
|
||||||
if (!!this.configuration.mediaStream) {
|
if (!!this.configuration.mediaStream) {
|
||||||
if (platform['isIonicIos'] || platform['isInternetExplorer']) {
|
if (platform['isIonicIos']) {
|
||||||
// iOS Ionic and IExplorer. LIMITATION: must use deprecated WebRTC API
|
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
|
||||||
const pc2: any = this.pc;
|
const pc2: any = this.pc;
|
||||||
pc2.addStream(this.configuration.mediaStream);
|
pc2.addStream(this.configuration.mediaStream);
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,8 +113,8 @@ export class WebRtcPeer {
|
||||||
this.remoteCandidatesQueue = [];
|
this.remoteCandidatesQueue = [];
|
||||||
this.localCandidatesQueue = [];
|
this.localCandidatesQueue = [];
|
||||||
|
|
||||||
if (platform['isIonicIos'] || platform['isInternetExplorer']) {
|
if (platform['isIonicIos']) {
|
||||||
// iOS Ionic or IExplorer. LIMITATION: must use deprecated WebRTC API
|
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
|
||||||
// Stop senders deprecated
|
// Stop senders deprecated
|
||||||
const pc1: any = this.pc;
|
const pc1: any = this.pc;
|
||||||
for (const sender of pc1.getLocalStreams()) {
|
for (const sender of pc1.getLocalStreams()) {
|
||||||
|
@ -222,34 +209,6 @@ export class WebRtcPeer {
|
||||||
})
|
})
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
|
|
||||||
} else if (platform['isInternetExplorer']) {
|
|
||||||
|
|
||||||
// IE Explorer cannot use Promise base API
|
|
||||||
let setLocalDescriptionOnSuccess = () => {
|
|
||||||
const localDescription = this.pc.localDescription;
|
|
||||||
if (!!localDescription) {
|
|
||||||
console.debug('Local description set', localDescription.sdp);
|
|
||||||
resolve(localDescription.sdp);
|
|
||||||
} else {
|
|
||||||
reject('Local description is not defined');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let setLocalDescriptionOnError = error => {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
let createOfferOnSuccess = offer => {
|
|
||||||
console.debug('Created SDP offer');
|
|
||||||
(<any>this.pc).setLocalDescription(offer, setLocalDescriptionOnSuccess, setLocalDescriptionOnError);
|
|
||||||
};
|
|
||||||
let createOfferOnError = error => {
|
|
||||||
reject(error);
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIX: for IExplorer WebRTC peer connections must be negotiated to receive video and audio
|
|
||||||
constraints.offerToReceiveAudio = true;
|
|
||||||
constraints.offerToReceiveVideo = true;
|
|
||||||
(<any>this.pc).createOffer(createOfferOnSuccess, createOfferOnError, constraints);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Rest of platforms
|
// Rest of platforms
|
||||||
|
@ -292,13 +251,8 @@ export class WebRtcPeer {
|
||||||
this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error));
|
this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error));
|
||||||
}, 250);
|
}, 250);
|
||||||
} else {
|
} else {
|
||||||
if (platform['isInternetExplorer']) {
|
// Rest of platforms
|
||||||
// IE Explorer cannot use Promise base API
|
this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error));
|
||||||
(<any>this.pc).setRemoteDescription(answer, resolve(), error => reject(error));
|
|
||||||
} else {
|
|
||||||
// Rest of platforms
|
|
||||||
this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -316,17 +270,7 @@ export class WebRtcPeer {
|
||||||
break;
|
break;
|
||||||
case 'stable':
|
case 'stable':
|
||||||
if (!!this.pc.remoteDescription) {
|
if (!!this.pc.remoteDescription) {
|
||||||
if (platform['isInternetExplorer']) {
|
this.pc.addIceCandidate(iceCandidate).then(() => resolve()).catch(error => reject(error));
|
||||||
const iceCandidateAuxIE = {
|
|
||||||
candidate: iceCandidate.candidate,
|
|
||||||
sdpMid: iceCandidate.sdpMid,
|
|
||||||
sdpMLineIndex: iceCandidate.sdpMLineIndex
|
|
||||||
};
|
|
||||||
const finalIECandidate = new RTCIceCandidate(iceCandidateAuxIE);
|
|
||||||
(<any>this.pc).addIceCandidate(finalIECandidate, () => resolve(), error => reject(error));
|
|
||||||
} else {
|
|
||||||
this.pc.addIceCandidate(iceCandidate).then(() => resolve()).catch(error => reject(error));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.iceCandidateList.push(iceCandidate);
|
this.iceCandidateList.push(iceCandidate);
|
||||||
resolve();
|
resolve();
|
||||||
|
|
Loading…
Reference in New Issue