From edf5bf5fe94b6ab89ee77871b106415f9f6e577b Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Thu, 4 Jul 2019 16:28:14 +0200 Subject: [PATCH] openvidu-browser: rollback fix to Ionic iOS subscribers --- openvidu-browser/src/OpenVidu/Session.ts | 19 +++++++++++++++++++ openvidu-browser/src/OpenVidu/Stream.ts | 16 ++++++++++++++-- .../OpenViduInternal/WebRtcPeer/WebRtcPeer.ts | 18 ++++++++++++++---- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/openvidu-browser/src/OpenVidu/Session.ts b/openvidu-browser/src/OpenVidu/Session.ts index 032d24e3..1f7507a7 100644 --- a/openvidu-browser/src/OpenVidu/Session.ts +++ b/openvidu-browser/src/OpenVidu/Session.ts @@ -77,6 +77,14 @@ export class Session implements EventDispatcher { */ remoteStreamsCreated: ObjMap = {}; + /** + * @hidden + */ + isFirstIonicIosSubscriber = true; + /** + * @hidden + */ + countDownForIonicIosSubscribersActive = true; /** * @hidden */ @@ -665,6 +673,11 @@ export class Session implements EventDispatcher { streamEvent.callDefaultBehavior(); delete this.remoteStreamsCreated[stream.streamId]; + + if (Object.keys(this.remoteStreamsCreated).length === 0) { + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + } } delete this.remoteConnections[connection.connectionId]; this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent(false, this, 'connectionDestroyed', connection, msg.reason)]); @@ -734,6 +747,12 @@ export class Session implements EventDispatcher { // Deleting the remote stream const streamId: string = connection.stream.streamId; delete this.remoteStreamsCreated[streamId]; + + if (Object.keys(this.remoteStreamsCreated).length === 0) { + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); }) .catch(openViduError => { diff --git a/openvidu-browser/src/OpenVidu/Stream.ts b/openvidu-browser/src/OpenVidu/Stream.ts index de2b214f..dd3ee33f 100644 --- a/openvidu-browser/src/OpenVidu/Stream.ts +++ b/openvidu-browser/src/OpenVidu/Stream.ts @@ -718,7 +718,7 @@ export class Stream implements EventDispatcher { reject('Error on publishVideo: ' + JSON.stringify(error)); } } else { - this.webRtcPeer.processAnswer(response.sdpAnswer) + this.webRtcPeer.processAnswer(response.sdpAnswer, false) .then(() => { this.streamId = response.id; this.creationTime = response.createdAt; @@ -778,7 +778,19 @@ export class Stream implements EventDispatcher { if (error) { reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); } else { - this.webRtcPeer.processAnswer(response.sdpAnswer).then(() => { + // Ios Ionic. Limitation: some bug in iosrtc cordova plugin makes it necessary + // to add a timeout before calling PeerConnection#setRemoteDescription during + // some time (400 ms) from the moment first subscriber stream is received + if (this.session.isFirstIonicIosSubscriber) { + this.session.isFirstIonicIosSubscriber = false; + setTimeout(() => { + // After 400 ms Ionic iOS subscribers won't need to run + // PeerConnection#setRemoteDescription after 250 ms timeout anymore + this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + const needsTimeoutOnProcessAnswer = this.session.countDownForIonicIosSubscribersActive; + this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(() => { this.remotePeerSuccessfullyEstablished(); this.initWebRtcStats(); resolve(); diff --git a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts index f8f4b0fd..f23043a1 100644 --- a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts +++ b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts @@ -119,14 +119,14 @@ export class WebRtcPeer { const pc1: any = this.pc; for (const sender of pc1.getLocalStreams()) { if (!videoSourceIsMediaStreamTrack) { - (sender).stop(); + sender.stop(); } pc1.removeStream(sender); } // Stop receivers deprecated for (const receiver of pc1.getRemoteStreams()) { if (!!receiver.track) { - (receiver).stop(); + receiver.stop(); } } } else { @@ -234,7 +234,7 @@ export class WebRtcPeer { * Function invoked when a SDP answer is received. Final step in SDP negotiation, the peer * just needs to set the answer as its remote description */ - processAnswer(sdpAnswer: string): Promise { + processAnswer(sdpAnswer: string, needsTimeoutOnProcessAnswer: boolean): Promise { return new Promise((resolve, reject) => { const answer: RTCSessionDescriptionInit = { type: 'answer', @@ -246,7 +246,17 @@ export class WebRtcPeer { reject('RTCPeerConnection is closed'); } if (platform['isIonicIos']) { - this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(() => resolve()).catch(error => reject(error)); + // Ionic iOS platform + if (needsTimeoutOnProcessAnswer) { + // 400 ms have not elapsed yet since first remote stream triggered Stream#initWebRtcPeerReceive + setTimeout(() => { + console.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));