diff --git a/openvidu-browser/src/OpenVidu/OpenVidu.ts b/openvidu-browser/src/OpenVidu/OpenVidu.ts index de5124ee..daa83e1e 100644 --- a/openvidu-browser/src/OpenVidu/OpenVidu.ts +++ b/openvidu-browser/src/OpenVidu/OpenVidu.ts @@ -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 (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,31 +439,20 @@ export class OpenVidu { return new Promise((resolve, reject) => { this.generateMediaConstraints(options) .then(constraints => { - - let userMediaFunc = () => { - navigator.mediaDevices.getUserMedia(constraints) - .then(mediaStream => { - resolve(mediaStream); - }) - .catch(error => { - let errorName: OpenViduErrorName; - const errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduErrorName.DEVICE_ACCESS_DENIED; - } else { - errorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError(errorName, errorMessage)); - }); - } - - if (platform['isInternetExplorer']) { - AdapterJS.webRTCReady(isUsingPlugin => { - userMediaFunc(); + navigator.mediaDevices.getUserMedia(constraints) + .then(mediaStream => { + resolve(mediaStream); + }) + .catch(error => { + let errorName: OpenViduErrorName; + const errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduErrorName.DEVICE_ACCESS_DENIED; + } else { + errorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError(errorName, errorMessage)); }); - } 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 - (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 - (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)]); - }; - } - } \ No newline at end of file diff --git a/openvidu-browser/src/OpenVidu/Publisher.ts b/openvidu-browser/src/OpenVidu/Publisher.ts index 1818d76b..ab89d153 100644 --- a/openvidu-browser/src/OpenVidu/Publisher.ts +++ b/openvidu-browser/src/OpenVidu/Publisher.ts @@ -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, 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, 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', (window).IEOnLoadedMetadata(this.videoReference, this.stream)); - } - } - }); - } else { - this.videoReference.srcObject = mediaStream; - } + 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,23 +605,13 @@ export class Publisher extends StreamManager { } else { - let userMediaFunc = () => { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(mediaStream => { - getMediaSuccess(mediaStream, definedAudioConstraint); - }) - .catch(error => { - getMediaError(error); - }); - } - - if (platform['isInternetExplorer']) { - AdapterJS.webRTCReady(isUsingPlugin => { - userMediaFunc(); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(mediaStream => { + getMediaSuccess(mediaStream, definedAudioConstraint); }) - } else { - userMediaFunc(); - } + .catch(error => { + getMediaError(error); + }); } } else { diff --git a/openvidu-browser/src/OpenVidu/Session.ts b/openvidu-browser/src/OpenVidu/Session.ts index 71475ce9..a719044e 100644 --- a/openvidu-browser/src/OpenVidu/Session.ts +++ b/openvidu-browser/src/OpenVidu/Session.ts @@ -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']) { - (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); - }); - } + 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); diff --git a/openvidu-browser/src/OpenVidu/Stream.ts b/openvidu-browser/src/OpenVidu/Stream.ts index 98624dd0..b58a7411 100644 --- a/openvidu-browser/src/OpenVidu/Stream.ts +++ b/openvidu-browser/src/OpenVidu/Stream.ts @@ -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,30 +798,20 @@ export class Stream implements EventDispatcher { }); }; - const initWebRtcPeer = () => { - this.webRtcPeer = new WebRtcPeerRecvonly(options); - this.webRtcPeer.generateOffer() - .then(offer => { - successCallback(offer); - }) - .catch(error => { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }; - - if (platform['isInternetExplorer']) { - AdapterJS.webRTCReady(isUsingPlugin => { - initWebRtcPeer(); + this.webRtcPeer = new WebRtcPeerRecvonly(options); + this.webRtcPeer.generateOffer() + .then(offer => { + successCallback(offer); + }) + .catch(error => { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); }); - } 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 { diff --git a/openvidu-browser/src/OpenVidu/StreamManager.ts b/openvidu-browser/src/OpenVidu/StreamManager.ts index 7c560410..c3e296ff 100644 --- a/openvidu-browser/src/OpenVidu/StreamManager.ts +++ b/openvidu-browser/src/OpenVidu/StreamManager.ts @@ -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,23 +120,22 @@ export class StreamManager implements EventDispatcher { this.element = targEl; } } - if (!platform['isInternetExplorer']) { - this.canPlayListener = () => { - if (this.stream.isLocal()) { - if (!this.stream.displayMyRemote()) { - 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.canPlayListener = () => { + if (this.stream.isLocal()) { + if (!this.stream.displayMyRemote()) { + 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')]); } - 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 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.ee.emitEvent('videoElementCreated', [new VideoElementEvent(v.video, this, 'videoElementCreated')]); + 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'] ? (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'] ? (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) - (this.videos[0].video).addEventListener('canplay', (window).IEOnCanPlay(this)); - } - } else { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - } + 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; - } - } \ No newline at end of file diff --git a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts index d003b72d..dd80468c 100644 --- a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts +++ b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts @@ -65,20 +65,7 @@ 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); - (this.pc).addIceCandidate(finalIECandidate, () => { }, () => { }); - } - } else { - this.pc.addIceCandidate(this.iceCandidateList.shift()); - } + this.pc.addIceCandidate(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'); } 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'); - (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; - (this.pc).createOffer(createOfferOnSuccess, createOfferOnError, constraints); - } else { // Rest of platforms @@ -292,13 +251,8 @@ export class WebRtcPeer { this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error)); }, 250); } else { - if (platform['isInternetExplorer']) { - // IE Explorer cannot use Promise base API - (this.pc).setRemoteDescription(answer, resolve(), error => reject(error)); - } else { - // Rest of platforms - this.pc.setRemoteDescription(answer).then(() => resolve()).catch(error => reject(error)); - } + // 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); - (this.pc).addIceCandidate(finalIECandidate, () => resolve(), error => reject(error)); - } else { - this.pc.addIceCandidate(iceCandidate).then(() => resolve()).catch(error => reject(error)); - } + this.pc.addIceCandidate(iceCandidate).then(() => resolve()).catch(error => reject(error)); } else { this.iceCandidateList.push(iceCandidate); resolve();