openvidu-browser: IE master branch rollback

pull/375/head
pabloFuente 2019-06-03 17:16:18 +02:00
parent c6bc6c9d39
commit 2bad86e108
6 changed files with 67 additions and 302 deletions

View File

@ -36,9 +36,6 @@ import EventEmitter = require('wolfy87-eventemitter');
import RpcBuilder = require('../OpenViduInternal/KurentoUtils/kurento-jsonrpc');
import platform = require('platform');
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
@ -108,12 +105,6 @@ export class OpenVidu {
console.info("'OpenVidu' initialized");
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') {
// Listen to orientationchange only on mobile devices
(<any>window).addEventListener('orientationchange', () => {
@ -342,8 +333,7 @@ export class OpenVidu {
(browser !== 'Chrome') && (browser !== 'Chrome Mobile') &&
(browser !== 'Firefox') && (browser !== 'Firefox Mobile') &&
(browser !== 'Opera') && (browser !== 'Opera Mobile') &&
(browser !== 'Android Browser') && (browser !== 'Electron') &&
(browser !== 'IE' || platform.version !== undefined && parseInt(platform.version) < 11)
(browser !== 'Android Browser') && (browser !== 'Electron')
) {
return 0;
} else {
@ -449,8 +439,6 @@ export class OpenVidu {
return new Promise<MediaStream>((resolve, reject) => {
this.generateMediaConstraints(options)
.then(constraints => {
let userMediaFunc = () => {
navigator.mediaDevices.getUserMedia(constraints)
.then(mediaStream => {
resolve(mediaStream);
@ -465,15 +453,6 @@ export class OpenVidu {
}
reject(new OpenViduError(errorName, errorMessage));
});
}
if (platform['isInternetExplorer']) {
AdapterJS.webRTCReady(isUsingPlugin => {
userMediaFunc();
});
} else {
userMediaFunc();
}
})
.catch((error: OpenViduError) => {
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)]);
};
}
}

View File

@ -29,7 +29,6 @@ import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/Open
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
import platform = require('platform');
declare const AdapterJS: any;
/**
* 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);
if (!!this.firstVideoElement) {
let video = 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')
}
}
this.createVideoElement(this.firstVideoElement.targetElement, <VideoInsertMode>this.properties.insertMode);
}
if (platform['isInternetExplorer']) {
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
// avoid early 'streamPlaying' event
this.stream.updateMediaStreamInVideos();
@ -386,8 +361,8 @@ export class Publisher extends StreamManager {
videoDimensionsSet();
}
});
} else if (platform.name !== 'IE') {
// Rest of platforms except IE
} else {
// 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();
@ -630,7 +605,6 @@ export class Publisher extends StreamManager {
} else {
let userMediaFunc = () => {
navigator.mediaDevices.getUserMedia(constraintsAux)
.then(mediaStream => {
getMediaSuccess(mediaStream, definedAudioConstraint);
@ -638,15 +612,6 @@ export class Publisher extends StreamManager {
.catch(error => {
getMediaError(error);
});
}
if (platform['isInternetExplorer']) {
AdapterJS.webRTCReady(isUsingPlugin => {
userMediaFunc();
})
} else {
userMediaFunc();
}
}
} else {

View File

@ -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)
.then(connection => {
const stream = connection.stream;
if (platform['isInternetExplorer']) {
(<any>stream.getWebRtcPeer()).addIceCandidate(candidate, () => { }, error => {
console.error('Error adding candidate for ' + stream.streamId
+ ' 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 => {
console.error(openViduError);

View File

@ -34,7 +34,6 @@ import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/Open
import EventEmitter = require('wolfy87-eventemitter');
import hark = require('hark');
import platform = require('platform');
declare const AdapterJS: any;
/**
@ -799,7 +798,6 @@ export class Stream implements EventDispatcher {
});
};
const initWebRtcPeer = () => {
this.webRtcPeer = new WebRtcPeerRecvonly(options);
this.webRtcPeer.generateOffer()
.then(offer => {
@ -808,21 +806,12 @@ export class Stream implements EventDispatcher {
.catch(error => {
reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error)));
});
};
if (platform['isInternetExplorer']) {
AdapterJS.webRTCReady(isUsingPlugin => {
initWebRtcPeer();
});
} else {
initWebRtcPeer();
}
});
}
private remotePeerSuccessfullyEstablished(): void {
if (platform['isIonicIos'] || platform['isInternetExplorer']) {
// iOS Ionic or IExplorer. LIMITATION: must use deprecated WebRTC API
if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
const pc1: any = this.webRtcPeer.pc;
this.mediaStream = pc1.getRemoteStreams()[0];
} else {

View File

@ -25,7 +25,6 @@ import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
import EventEmitter = require('wolfy87-eventemitter');
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.
@ -121,7 +120,7 @@ export class StreamManager implements EventDispatcher {
this.element = targEl;
}
}
if (!platform['isInternetExplorer']) {
this.canPlayListener = () => {
if (this.stream.isLocal()) {
if (!this.stream.displayMyRemote()) {
@ -138,7 +137,6 @@ export class StreamManager implements EventDispatcher {
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent(this, 'streamPlaying', undefined)]);
};
}
}
/**
* See [[EventDispatcher.on]]
@ -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
for (const v of this.videos) {
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);
}
let video = document.createElement('video');
const video = document.createElement('video');
this.initializeVideoProperties(video);
let insMode = !!insertMode ? insertMode : VideoInsertMode.APPEND;
@ -331,10 +325,6 @@ export class StreamManager implements EventDispatcher {
break;
}
if (platform['isInternetExplorer'] && !!this.stream.getMediaStream()) {
video = this.customAttachMediaStreamIE(video, this.stream.getMediaStream());
}
const v: StreamManagerVideo = {
targetElement: targEl,
video,
@ -344,12 +334,8 @@ export class StreamManager implements EventDispatcher {
};
this.pushNewStreamManagerVideo(v);
let launchVideoCreatedEvent = !platform['isInternetExplorer'];
if (launchVideoCreatedEvent) {
// For IE the event is called in this.customAttachMediaStreamIE
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent(v.video, this, 'videoElementCreated')]);
}
this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement && launchVideoCreatedEvent;
this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement;
return video;
}
@ -372,7 +358,7 @@ export class StreamManager implements EventDispatcher {
video.setAttribute('playsinline', 'true');
}
if (!video.id && !platform['isInternetExplorer']) {
if (!video.id) {
video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId;
// DEPRECATED property: assign once the property id if the user provided a valid targetElement
if (!this.id && !!this.targetElement) {
@ -403,7 +389,7 @@ export class StreamManager implements EventDispatcher {
this.videos.forEach(streamManagerVideo => {
// 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;
if (!!streamManagerVideo.targetElement) {
// 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;
for (let i = 0; i < this.videos.length; i++) {
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);
disassociated = true;
console.info('Video element disassociated from ', this);
@ -440,14 +426,7 @@ export class StreamManager implements EventDispatcher {
*/
addPlayEventToFirstVideo() {
if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) {
if (platform['isInternetExplorer']) {
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;
}
}
@ -466,9 +445,6 @@ export class StreamManager implements EventDispatcher {
vParent!!.replaceChild(newVideo, streamManagerVideo.video);
streamManagerVideo.video = newVideo;
}
if (platform['isInternetExplorer']) {
this.customAttachMediaStreamIE(streamManagerVideo.video, mediaStream);
}
});
}
@ -499,30 +475,4 @@ export class StreamManager implements EventDispatcher {
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;
}
}

View File

@ -65,22 +65,9 @@ export class WebRtcPeer {
this.pc.onsignalingstatechange = () => {
if (this.pc.signalingState === 'stable') {
while (this.iceCandidateList.length > 0) {
if (platform['isInternetExplorer']) {
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());
}
}
}
};
this.start();
@ -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');
}
if (!!this.configuration.mediaStream) {
if (platform['isIonicIos'] || platform['isInternetExplorer']) {
// iOS Ionic and IExplorer. LIMITATION: must use deprecated WebRTC API
if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
const pc2: any = this.pc;
pc2.addStream(this.configuration.mediaStream);
} else {
@ -126,8 +113,8 @@ export class WebRtcPeer {
this.remoteCandidatesQueue = [];
this.localCandidatesQueue = [];
if (platform['isIonicIos'] || platform['isInternetExplorer']) {
// iOS Ionic or IExplorer. LIMITATION: must use deprecated WebRTC API
if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
// Stop senders deprecated
const pc1: any = this.pc;
for (const sender of pc1.getLocalStreams()) {
@ -222,34 +209,6 @@ export class WebRtcPeer {
})
.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 {
// Rest of platforms
@ -291,15 +250,10 @@ export class WebRtcPeer {
console.info('setRemoteDescription run after timout for iOS device');
this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error));
}, 250);
} else {
if (platform['isInternetExplorer']) {
// IE Explorer cannot use Promise base API
(<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;
case 'stable':
if (!!this.pc.remoteDescription) {
if (platform['isInternetExplorer']) {
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 {
this.iceCandidateList.push(iceCandidate);
resolve();