Browse Source

feat(RTC,JingleSessionPC): use the Promise based WebRTC APIs

It's 2018 after all...
dev1
Saúl Ibarra Corretgé 7 years ago
parent
commit
9fd0b674cd
2 changed files with 125 additions and 173 deletions
  1. 69
    82
      modules/RTC/TraceablePeerConnection.js
  2. 56
    91
      modules/xmpp/JingleSessionPC.js

+ 69
- 82
modules/RTC/TraceablePeerConnection.js View File

1686
     return localDescription;
1686
     return localDescription;
1687
 };
1687
 };
1688
 
1688
 
1689
-TraceablePeerConnection.prototype.setLocalDescription = function(
1690
-        description,
1691
-        successCallback,
1692
-        failureCallback) {
1689
+TraceablePeerConnection.prototype.setLocalDescription = function(description) {
1693
     let localSdp = description;
1690
     let localSdp = description;
1694
 
1691
 
1695
     this.trace('setLocalDescription::preTransform', dumpSDP(localSdp));
1692
     this.trace('setLocalDescription::preTransform', dumpSDP(localSdp));
1725
             dumpSDP(localSdp));
1722
             dumpSDP(localSdp));
1726
     }
1723
     }
1727
 
1724
 
1728
-    this.peerconnection.setLocalDescription(localSdp,
1729
-        () => {
1730
-            this.trace('setLocalDescriptionOnSuccess');
1731
-            const localUfrag = SDPUtil.getUfrag(localSdp.sdp);
1725
+    return new Promise((resolve, reject) => {
1726
+        this.peerconnection.setLocalDescription(localSdp)
1727
+            .then(() => {
1728
+                this.trace('setLocalDescriptionOnSuccess');
1729
+                const localUfrag = SDPUtil.getUfrag(localSdp.sdp);
1732
 
1730
 
1733
-            if (localUfrag !== this.localUfrag) {
1734
-                this.localUfrag = localUfrag;
1731
+                if (localUfrag !== this.localUfrag) {
1732
+                    this.localUfrag = localUfrag;
1733
+                    this.eventEmitter.emit(
1734
+                        RTCEvents.LOCAL_UFRAG_CHANGED, this, localUfrag);
1735
+                }
1736
+                resolve();
1737
+            })
1738
+            .catch(err => {
1739
+                this.trace('setLocalDescriptionOnFailure', err);
1735
                 this.eventEmitter.emit(
1740
                 this.eventEmitter.emit(
1736
-                    RTCEvents.LOCAL_UFRAG_CHANGED, this, localUfrag);
1737
-            }
1738
-            successCallback();
1739
-        },
1740
-        err => {
1741
-            this.trace('setLocalDescriptionOnFailure', err);
1742
-            this.eventEmitter.emit(
1743
-                RTCEvents.SET_LOCAL_DESCRIPTION_FAILED,
1744
-                err, this);
1745
-            failureCallback(err);
1746
-        }
1747
-    );
1741
+                    RTCEvents.SET_LOCAL_DESCRIPTION_FAILED,
1742
+                    err, this);
1743
+                reject(err);
1744
+            });
1745
+    });
1748
 };
1746
 };
1749
 
1747
 
1750
 /**
1748
 /**
1810
         });
1808
         });
1811
     };
1809
     };
1812
 
1810
 
1813
-TraceablePeerConnection.prototype.setRemoteDescription = function(
1814
-        description,
1815
-        successCallback,
1816
-        failureCallback) {
1811
+TraceablePeerConnection.prototype.setRemoteDescription = function(description) {
1817
     this.trace('setRemoteDescription::preTransform', dumpSDP(description));
1812
     this.trace('setRemoteDescription::preTransform', dumpSDP(description));
1818
 
1813
 
1819
     // TODO the focus should squeze or explode the remote simulcast
1814
     // TODO the focus should squeze or explode the remote simulcast
1876
         description = this._injectH264IfNotPresent(description);
1871
         description = this._injectH264IfNotPresent(description);
1877
     }
1872
     }
1878
 
1873
 
1879
-    this.peerconnection.setRemoteDescription(
1880
-        description,
1881
-        () => {
1882
-            this.trace('setRemoteDescriptionOnSuccess');
1883
-            const remoteUfrag = SDPUtil.getUfrag(description.sdp);
1874
+    return new Promise((resolve, reject) => {
1875
+        this.peerconnection.setRemoteDescription(description)
1876
+            .then(() => {
1877
+                this.trace('setRemoteDescriptionOnSuccess');
1878
+                const remoteUfrag = SDPUtil.getUfrag(description.sdp);
1884
 
1879
 
1885
-            if (remoteUfrag !== this.remoteUfrag) {
1886
-                this.remoteUfrag = remoteUfrag;
1880
+                if (remoteUfrag !== this.remoteUfrag) {
1881
+                    this.remoteUfrag = remoteUfrag;
1882
+                    this.eventEmitter.emit(
1883
+                        RTCEvents.REMOTE_UFRAG_CHANGED, this, remoteUfrag);
1884
+                }
1885
+                resolve();
1886
+            })
1887
+            .catch(err => {
1888
+                this.trace('setRemoteDescriptionOnFailure', err);
1887
                 this.eventEmitter.emit(
1889
                 this.eventEmitter.emit(
1888
-                    RTCEvents.REMOTE_UFRAG_CHANGED, this, remoteUfrag);
1889
-            }
1890
-            successCallback();
1891
-        },
1892
-        err => {
1893
-            this.trace('setRemoteDescriptionOnFailure', err);
1894
-            this.eventEmitter.emit(
1895
-                RTCEvents.SET_REMOTE_DESCRIPTION_FAILED,
1896
-                err,
1897
-                this);
1898
-            failureCallback(err);
1899
-        });
1890
+                    RTCEvents.SET_REMOTE_DESCRIPTION_FAILED,
1891
+                    err,
1892
+                    this);
1893
+                reject(err);
1894
+            });
1895
+    });
1900
 };
1896
 };
1901
 
1897
 
1902
 /**
1898
 /**
2104
     }
2100
     }
2105
 };
2101
 };
2106
 
2102
 
2107
-TraceablePeerConnection.prototype.createAnswer = function(
2108
-        successCallback,
2109
-        failureCallback,
2110
-        constraints) {
2103
+TraceablePeerConnection.prototype.createAnswer = function(constraints) {
2111
     if (browser.supportsRtpSender() && this.isSimulcastOn()) {
2104
     if (browser.supportsRtpSender() && this.isSimulcastOn()) {
2112
         const videoSender
2105
         const videoSender
2113
             = this.peerconnection.getSenders().find(sender =>
2106
             = this.peerconnection.getSenders().find(sender =>
2130
 
2123
 
2131
         videoSender.setParameters(simParams);
2124
         videoSender.setParameters(simParams);
2132
     }
2125
     }
2133
-    this._createOfferOrAnswer(
2134
-        false /* answer */, successCallback, failureCallback, constraints);
2135
-};
2136
 
2126
 
2137
-TraceablePeerConnection.prototype.createOffer = function(
2138
-        successCallback,
2139
-        failureCallback,
2140
-        constraints) {
2141
-    this._createOfferOrAnswer(
2142
-        true /* offer */, successCallback, failureCallback, constraints);
2127
+    return this._createOfferOrAnswer(false /* answer */, constraints);
2143
 };
2128
 };
2144
 
2129
 
2145
-/* eslint-disable max-params */
2130
+TraceablePeerConnection.prototype.createOffer = function(constraints) {
2131
+    return this._createOfferOrAnswer(true /* offer */, constraints);
2132
+};
2146
 
2133
 
2147
 TraceablePeerConnection.prototype._createOfferOrAnswer = function(
2134
 TraceablePeerConnection.prototype._createOfferOrAnswer = function(
2148
         isOffer,
2135
         isOffer,
2149
-        successCallback,
2150
-        failureCallback,
2151
         constraints) {
2136
         constraints) {
2152
     const logName = isOffer ? 'Offer' : 'Answer';
2137
     const logName = isOffer ? 'Offer' : 'Answer';
2153
 
2138
 
2154
     this.trace(`create${logName}`, JSON.stringify(constraints, null, ' '));
2139
     this.trace(`create${logName}`, JSON.stringify(constraints, null, ' '));
2155
 
2140
 
2156
-    const _successCallback = resultSdp => {
2141
+    const handleSuccess = (resultSdp, resolveFn, rejectFn) => {
2157
         try {
2142
         try {
2158
             this.trace(
2143
             this.trace(
2159
                 `create${logName}OnSuccess::preTransform`, dumpSDP(resultSdp));
2144
                 `create${logName}OnSuccess::preTransform`, dumpSDP(resultSdp));
2206
 
2191
 
2207
             // Add simulcast streams if simulcast is enabled
2192
             // Add simulcast streams if simulcast is enabled
2208
             if (this.isSimulcastOn()) {
2193
             if (this.isSimulcastOn()) {
2209
-
2210
                 // eslint-disable-next-line no-param-reassign
2194
                 // eslint-disable-next-line no-param-reassign
2211
                 resultSdp = this.simulcast.mungeLocalDescription(resultSdp);
2195
                 resultSdp = this.simulcast.mungeLocalDescription(resultSdp);
2212
                 this.trace(
2196
                 this.trace(
2249
             logger.debug('Got local SSRCs MAP: ', ssrcMap);
2233
             logger.debug('Got local SSRCs MAP: ', ssrcMap);
2250
             this._processLocalSSRCsMap(ssrcMap);
2234
             this._processLocalSSRCsMap(ssrcMap);
2251
 
2235
 
2252
-            successCallback(resultSdp);
2236
+            resolveFn(resultSdp);
2253
         } catch (e) {
2237
         } catch (e) {
2254
             this.trace(`create${logName}OnError`, e);
2238
             this.trace(`create${logName}OnError`, e);
2255
             this.trace(`create${logName}OnError`, dumpSDP(resultSdp));
2239
             this.trace(`create${logName}OnError`, dumpSDP(resultSdp));
2256
             logger.error(`create${logName}OnError`, e, dumpSDP(resultSdp));
2240
             logger.error(`create${logName}OnError`, e, dumpSDP(resultSdp));
2257
-            failureCallback(e);
2241
+
2242
+            rejectFn(e);
2258
         }
2243
         }
2259
     };
2244
     };
2260
 
2245
 
2261
-    const _errorCallback = err => {
2246
+    const handleFailure = (err, rejectFn) => {
2262
         this.trace(`create${logName}OnFailure`, err);
2247
         this.trace(`create${logName}OnFailure`, err);
2263
         const eventType
2248
         const eventType
2264
             = isOffer
2249
             = isOffer
2266
                 : RTCEvents.CREATE_ANSWER_FAILED;
2251
                 : RTCEvents.CREATE_ANSWER_FAILED;
2267
 
2252
 
2268
         this.eventEmitter.emit(eventType, err, this);
2253
         this.eventEmitter.emit(eventType, err, this);
2269
-        failureCallback(err);
2254
+
2255
+        rejectFn(err);
2270
     };
2256
     };
2271
 
2257
 
2272
-    if (isOffer) {
2273
-        this.peerconnection.createOffer(
2274
-            _successCallback, _errorCallback, constraints);
2275
-    } else {
2276
-        this.peerconnection.createAnswer(
2277
-            _successCallback, _errorCallback, constraints);
2278
-    }
2279
-};
2258
+    return new Promise((resolve, reject) => {
2259
+        let oaPromise;
2280
 
2260
 
2281
-/* eslint-enable max-params */
2261
+        if (isOffer) {
2262
+            oaPromise = this.peerconnection.createOffer(constraints);
2263
+        } else {
2264
+            oaPromise = this.peerconnection.createAnswer(constraints);
2265
+        }
2266
+
2267
+        oaPromise
2268
+            .then(sdp => handleSuccess(sdp, resolve, reject))
2269
+            .catch(error => handleFailure(error, reject));
2270
+    });
2271
+};
2282
 
2272
 
2283
 /**
2273
 /**
2284
  * Extract primary SSRC from given {@link TrackSSRCInfo} object.
2274
  * Extract primary SSRC from given {@link TrackSSRCInfo} object.
2344
     }
2334
     }
2345
 };
2335
 };
2346
 
2336
 
2347
-TraceablePeerConnection.prototype.addIceCandidate = function(
2348
-        candidate,
2349
-        successCallback,
2350
-        failureCallback) {
2337
+TraceablePeerConnection.prototype.addIceCandidate = function(candidate) {
2351
     this.trace('addIceCandidate', JSON.stringify({
2338
     this.trace('addIceCandidate', JSON.stringify({
2352
         candidate: candidate.candidate,
2339
         candidate: candidate.candidate,
2353
         sdpMid: candidate.sdpMid,
2340
         sdpMid: candidate.sdpMid,
2354
         sdpMLineIndex: candidate.sdpMLineIndex,
2341
         sdpMLineIndex: candidate.sdpMLineIndex,
2355
         usernameFragment: candidate.usernameFragment
2342
         usernameFragment: candidate.usernameFragment
2356
     }, null, ' '));
2343
     }, null, ' '));
2357
-    this.peerconnection.addIceCandidate(
2358
-        candidate, successCallback, failureCallback);
2344
+
2345
+    return this.peerconnection.addIceCandidate(candidate);
2359
 };
2346
 };
2360
 
2347
 
2361
 /**
2348
 /**

+ 56
- 91
modules/xmpp/JingleSessionPC.js View File

679
         // and XMPP preserves order).
679
         // and XMPP preserves order).
680
         const workFunction = finishedCallback => {
680
         const workFunction = finishedCallback => {
681
             for (const iceCandidate of iceCandidates) {
681
             for (const iceCandidate of iceCandidates) {
682
-                this.peerconnection.addIceCandidate(
683
-                    iceCandidate,
684
-                    () => {
685
-                        logger.debug('addIceCandidate ok!');
686
-                    },
687
-                    error => {
682
+                this.peerconnection.addIceCandidate(iceCandidate)
683
+                    .then(() => logger.debug('addIceCandidate ok!'))
684
+                    .catch(error => {
688
                         logger.error('addIceCandidate failed!', error);
685
                         logger.error('addIceCandidate failed!', error);
689
                     });
686
                     });
690
             }
687
             }
799
             for (const localTrack of localTracks) {
796
             for (const localTrack of localTracks) {
800
                 this.peerconnection.addTrack(localTrack);
797
                 this.peerconnection.addTrack(localTrack);
801
             }
798
             }
802
-            this.peerconnection.createOffer(
803
-                offerSdp => {
804
-                    this.peerconnection.setLocalDescription(
805
-                        offerSdp,
806
-                        () => {
799
+            this.peerconnection.createOffer(this.mediaConstraints)
800
+                .then(offerSdp => {
801
+                    this.peerconnection.setLocalDescription(offerSdp)
802
+                        .then(() => {
807
                             // NOTE that the offer is obtained from
803
                             // NOTE that the offer is obtained from
808
                             // the localDescription getter as it needs to go
804
                             // the localDescription getter as it needs to go
809
                             // though the transformation chain.
805
                             // though the transformation chain.
810
                             this.sendSessionInitiate(
806
                             this.sendSessionInitiate(
811
                                 this.peerconnection.localDescription.sdp);
807
                                 this.peerconnection.localDescription.sdp);
812
                             finishedCallback();
808
                             finishedCallback();
813
-                        },
814
-                        error => {
809
+                        })
810
+                        .catch(error => {
815
                             logger.error(
811
                             logger.error(
816
                                 'Failed to set local SDP', error, offerSdp);
812
                                 'Failed to set local SDP', error, offerSdp);
817
                             finishedCallback(error);
813
                             finishedCallback(error);
818
                         });
814
                         });
819
-                },
820
-                error => {
815
+                })
816
+                .catch(error => {
821
                     logger.error(
817
                     logger.error(
822
                         'Failed to create an offer',
818
                         'Failed to create an offer',
823
                         error,
819
                         error,
824
                         this.mediaConstraints);
820
                         this.mediaConstraints);
825
                     finishedCallback(error);
821
                     finishedCallback(error);
826
-                },
827
-                this.mediaConstraints);
822
+                });
828
         };
823
         };
829
 
824
 
830
         this.modificationQueue.push(
825
         this.modificationQueue.push(
1514
      *  rejects with an error {string}
1509
      *  rejects with an error {string}
1515
      */
1510
      */
1516
     _renegotiate(optionalRemoteSdp) {
1511
     _renegotiate(optionalRemoteSdp) {
1512
+        if (this.peerconnection.signalingState === 'closed') {
1513
+            return Promise.reject('Attempted to renegotiate in state closed');
1514
+        }
1515
+
1517
         const remoteSdp
1516
         const remoteSdp
1518
             = optionalRemoteSdp || this.peerconnection.remoteDescription.sdp;
1517
             = optionalRemoteSdp || this.peerconnection.remoteDescription.sdp;
1519
 
1518
 
1528
             sdp: remoteSdp
1527
             sdp: remoteSdp
1529
         });
1528
         });
1530
 
1529
 
1531
-        return new Promise((resolve, reject) => {
1532
-            if (this.peerconnection.signalingState === 'closed') {
1533
-                reject('Attempted to renegotiate in state closed');
1530
+        if (this.isInitiator) {
1531
+            return this._initiatorRenegotiate(remoteDescription);
1532
+        }
1534
 
1533
 
1535
-                return;
1536
-            }
1537
-            if (this.isInitiator) {
1538
-                this._initiatorRenegotiate(remoteDescription, resolve, reject);
1539
-            } else {
1540
-                this._responderRenegotiate(remoteDescription, resolve, reject);
1541
-            }
1542
-        });
1534
+        return this._responderRenegotiate(remoteDescription);
1543
     }
1535
     }
1544
 
1536
 
1545
     /**
1537
     /**
1546
      * Renegotiate cycle implementation for the responder case.
1538
      * Renegotiate cycle implementation for the responder case.
1547
      * @param {object} remoteDescription the SDP object as defined by the WebRTC
1539
      * @param {object} remoteDescription the SDP object as defined by the WebRTC
1548
      * which will be used as remote description in the cycle.
1540
      * which will be used as remote description in the cycle.
1549
-     * @param {function} resolve the success callback
1550
-     * @param {function} reject the failure callback
1551
      * @private
1541
      * @private
1552
      */
1542
      */
1553
-    _responderRenegotiate(remoteDescription, resolve, reject) {
1554
-        // FIXME use WebRTC promise API to simplify things
1543
+    _responderRenegotiate(remoteDescription) {
1555
         logger.debug('Renegotiate: setting remote description');
1544
         logger.debug('Renegotiate: setting remote description');
1556
-        this.peerconnection.setRemoteDescription(
1557
-            remoteDescription,
1558
-            () => {
1545
+
1546
+        return this.peerconnection.setRemoteDescription(remoteDescription)
1547
+            .then(() => {
1559
                 logger.debug('Renegotiate: creating answer');
1548
                 logger.debug('Renegotiate: creating answer');
1560
-                this.peerconnection.createAnswer(
1561
-                    answer => {
1549
+
1550
+                return this.peerconnection.createAnswer(this.mediaConstraints)
1551
+                    .then(answer => {
1562
                         logger.debug('Renegotiate: setting local description');
1552
                         logger.debug('Renegotiate: setting local description');
1563
-                        this.peerconnection.setLocalDescription(
1564
-                            answer,
1565
-                            () => {
1566
-                                resolve();
1567
-                            },
1568
-                            error => {
1569
-                                reject(
1570
-                                    `setLocalDescription failed: ${error}`);
1571
-                            }
1572
-                        );
1573
-                    },
1574
-                    error => reject(`createAnswer failed: ${error}`),
1575
-                    this.mediaConstraints
1576
-                );
1577
-            },
1578
-            error => reject(`setRemoteDescription failed: ${error}`)
1579
-        );
1553
+
1554
+                        return this.peerconnection.setLocalDescription(answer);
1555
+                    });
1556
+            });
1580
     }
1557
     }
1581
 
1558
 
1582
     /**
1559
     /**
1583
      * Renegotiate cycle implementation for the initiator's case.
1560
      * Renegotiate cycle implementation for the initiator's case.
1584
      * @param {object} remoteDescription the SDP object as defined by the WebRTC
1561
      * @param {object} remoteDescription the SDP object as defined by the WebRTC
1585
      * which will be used as remote description in the cycle.
1562
      * which will be used as remote description in the cycle.
1586
-     * @param {function} resolve the success callback
1587
-     * @param {function} reject the failure callback
1588
      * @private
1563
      * @private
1589
      */
1564
      */
1590
-    _initiatorRenegotiate(remoteDescription, resolve, reject) {
1591
-        // FIXME use WebRTC promise API to simplify things
1565
+    _initiatorRenegotiate(remoteDescription) {
1592
         if (this.peerconnection.signalingState === 'have-local-offer') {
1566
         if (this.peerconnection.signalingState === 'have-local-offer') {
1593
-
1594
             // Skip createOffer and setLocalDescription or FF will fail
1567
             // Skip createOffer and setLocalDescription or FF will fail
1595
             logger.debug(
1568
             logger.debug(
1596
                 'Renegotiate: setting remote description');
1569
                 'Renegotiate: setting remote description');
1597
-            this.peerconnection.setRemoteDescription(
1598
-                remoteDescription,
1599
-                () => {
1570
+
1571
+            /* eslint-disable arrow-body-style */
1572
+
1573
+            return this.peerconnection.setRemoteDescription(remoteDescription)
1574
+                .then(() => {
1600
                     // In case when the answer is being set for the first time,
1575
                     // In case when the answer is being set for the first time,
1601
                     // full sRD/sLD cycle is required to have the local
1576
                     // full sRD/sLD cycle is required to have the local
1602
                     // description updated and SSRCs synchronized correctly.
1577
                     // description updated and SSRCs synchronized correctly.
1605
                     // The reason for that is that renegotiate can not be called
1580
                     // The reason for that is that renegotiate can not be called
1606
                     // when adding tracks and they will not be reflected in
1581
                     // when adding tracks and they will not be reflected in
1607
                     // the local SDP.
1582
                     // the local SDP.
1608
-                    this._initiatorRenegotiate(
1609
-                        remoteDescription, resolve, reject);
1610
-                },
1611
-                error => reject(`setRemoteDescription failed: ${error}`)
1612
-            );
1613
-        } else {
1614
-            logger.debug('Renegotiate: creating offer');
1615
-            this.peerconnection.createOffer(
1616
-                offer => {
1617
-                    logger.debug('Renegotiate: setting local description');
1618
-                    this.peerconnection.setLocalDescription(offer,
1619
-                        () => {
1620
-                            logger.debug(
1621
-                                'Renegotiate: setting remote description');
1622
-                            this.peerconnection.setRemoteDescription(
1623
-                                remoteDescription,
1624
-                                () => {
1625
-                                    resolve();
1626
-                                },
1627
-                                error => reject(
1628
-                                    `setRemoteDescription failed: ${error}`)
1629
-                            );
1630
-                        },
1631
-                        error => {
1632
-                            reject('setLocalDescription failed: ', error);
1633
-                        });
1634
-                },
1635
-                error => reject(`createOffer failed: ${error}`),
1636
-                this.mediaConstraints);
1583
+                    return this._initiatorRenegotiate(remoteDescription);
1584
+                });
1585
+            /* eslint-enable arrow-body-style */
1637
         }
1586
         }
1587
+
1588
+        logger.debug('Renegotiate: creating offer');
1589
+
1590
+        return this.peerconnection.createOffer(this.mediaConstraints)
1591
+            .then(offer => {
1592
+                logger.debug('Renegotiate: setting local description');
1593
+
1594
+                return this.peerconnection.setLocalDescription(offer)
1595
+                    .then(() => {
1596
+                        logger.debug(
1597
+                            'Renegotiate: setting remote description');
1598
+
1599
+                        // eslint-disable-next-line max-len
1600
+                        return this.peerconnection.setRemoteDescription(remoteDescription);
1601
+                    });
1602
+            });
1638
     }
1603
     }
1639
 
1604
 
1640
     /**
1605
     /**

Loading…
Cancel
Save