Ver código fonte

fix: Use RTCRtpSender.replaceTrack() for applying presenter effect on FF

dev1
Jaya Allamsetty 5 anos atrás
pai
commit
d5d8e0a1e4

+ 26
- 0
JitsiConference.js Ver arquivo

@@ -989,6 +989,32 @@ JitsiConference.prototype.replaceTrack = function(oldTrack, newTrack) {
989 989
         }, error => Promise.reject(new Error(error)));
990 990
 };
991 991
 
992
+/**
993
+ * Replaces the track at the lower level by going through the Jingle session
994
+ * and WebRTC peer connection. The track is replaced without the need for an
995
+ * offer/answer cycle.
996
+ * @param {JitsiLocalTrack} localTrack - the local track whose media stream has
997
+ * been updated.
998
+ */
999
+JitsiConference.prototype.replaceTrackWithoutOfferAnswer = function(localTrack) {
1000
+    const replaceTrackPromises = [];
1001
+
1002
+    if (this.jvbJingleSession) {
1003
+        replaceTrackPromises.push(
1004
+            this.jvbJingleSession.replaceTrackWithoutOfferAnswer(localTrack));
1005
+    } else {
1006
+        logger.info('replaceTrackWithoutOfferAnswer - no JVB JingleSession');
1007
+    }
1008
+    if (this.p2pJingleSession) {
1009
+        replaceTrackPromises.push(
1010
+            this.p2pJingleSession.replaceTrackWithoutOfferAnswer(localTrack));
1011
+    } else {
1012
+        logger.info('_doReplaceTrack - no P2P JingleSession');
1013
+    }
1014
+
1015
+    return Promise.all(replaceTrackPromises);
1016
+};
1017
+
992 1018
 /**
993 1019
  * Replaces the tracks at the lower level by going through the Jingle session
994 1020
  * and WebRTC peer connection. The method will resolve immediately if there is

+ 16
- 1
modules/RTC/JitsiLocalTrack.js Ver arquivo

@@ -338,7 +338,6 @@ export default class JitsiLocalTrack extends JitsiTrack {
338 338
         if (this._streamEffect) {
339 339
             this._streamEffect.stopEffect();
340 340
             this._setStream(this._originalStream);
341
-            this._originalStream = undefined;
342 341
         }
343 342
     }
344 343
 
@@ -392,6 +391,22 @@ export default class JitsiLocalTrack extends JitsiTrack {
392 391
 
393 392
         this._setEffectInProgress = true;
394 393
 
394
+        // For firefox/safari, replace the stream without doing a offer answer with the remote peer.
395
+        if (browser.supportsRtpSender()) {
396
+            this._switchStreamEffect(effect);
397
+
398
+            return conference.replaceTrackWithoutOfferAnswer(this)
399
+                .then(() => {
400
+                    this._setEffectInProgress = false;
401
+                })
402
+                .catch(error => {
403
+                    this._setEffectInProgress = false;
404
+                    this._switchStreamEffect();
405
+                    logger.error('Failed to switch to the new stream!', error);
406
+                    throw error;
407
+                });
408
+        }
409
+
395 410
         // TODO: Create new JingleSessionPC method for replacing a stream in JitsiLocalTrack without offer answer.
396 411
         return conference.removeTrack(this)
397 412
             .then(() => {

+ 38
- 0
modules/RTC/TraceablePeerConnection.js Ver arquivo

@@ -5,6 +5,7 @@ import transform from 'sdp-transform';
5 5
 
6 6
 import * as GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
7 7
 import JitsiRemoteTrack from './JitsiRemoteTrack';
8
+import * as JitsiTrackEvents from '../../JitsiTrackEvents';
8 9
 import * as MediaType from '../../service/RTC/MediaType';
9 10
 import LocalSdpMunger from './LocalSdpMunger';
10 11
 import RTC from './RTC';
@@ -1546,6 +1547,16 @@ TraceablePeerConnection.prototype.removeTrack = function(localTrack) {
1546 1547
     }
1547 1548
 };
1548 1549
 
1550
+/**
1551
+ * Returns the sender corresponding to the given media type.
1552
+ * @param {MEDIA_TYPE} mediaType - The media type 'audio' or 'video' to be used for the search.
1553
+ * @returns {RTPSender|undefined} - The found sender or undefined if no sender
1554
+ * was found.
1555
+ */
1556
+TraceablePeerConnection.prototype.findSenderByKind = function(mediaType) {
1557
+    return this.peerconnection.getSenders().find(s => s.track && s.track.kind === mediaType);
1558
+};
1559
+
1549 1560
 /**
1550 1561
  * Returns the sender corresponding to the given MediaStream.
1551 1562
  *
@@ -1633,6 +1644,33 @@ TraceablePeerConnection.prototype.replaceTrack = function(oldTrack, newTrack) {
1633 1644
     return Promise.resolve(true);
1634 1645
 };
1635 1646
 
1647
+/**
1648
+ * Replaces the existing media stream from the underlying peerconnection with the new
1649
+ * mediastream that has been added to the JitsiLocalTrack. Renegotiation with the remote
1650
+ * peer is not needed in this case.
1651
+ * @param {JitsiLocalTrack} localTrack - the localtrack whose mediastream has been updated.
1652
+ * @return {Promise} - Promise resolved with undefined if the track is replaced,
1653
+ * or rejected with <tt>InvalidModificationError<tt> if the track cannot be replaced.
1654
+ */
1655
+TraceablePeerConnection.prototype.replaceTrackWithoutOfferAnswer = function(localTrack) {
1656
+    const newTrack = localTrack.stream.getTracks()[0];
1657
+    const sender = this.findSenderByKind(newTrack.kind);
1658
+
1659
+    if (!sender) {
1660
+        return Promise.reject(new Error(`Could not find RTCRtpSender for ${newTrack.kind}`));
1661
+    }
1662
+
1663
+    return sender.replaceTrack(newTrack)
1664
+        .then(() => {
1665
+            this._addedStreams = this._addedStreams.filter(s => s !== localTrack._originalStream);
1666
+            this._addedStreams.push(localTrack.stream);
1667
+            localTrack.emit(JitsiTrackEvents.TRACK_MUTE_CHANGED, localTrack);
1668
+        })
1669
+        .catch(err => {
1670
+            logger.error(`replaceTrackWithoutOfferAnswer - replaceTrack failed for ${newTrack.kind}`, err);
1671
+        });
1672
+};
1673
+
1636 1674
 /**
1637 1675
  * Removes local track as part of the mute operation.
1638 1676
  * @param {JitsiLocalTrack} localTrack the local track to be remove as part of

+ 13
- 0
modules/xmpp/JingleSessionPC.js Ver arquivo

@@ -1665,6 +1665,19 @@ export default class JingleSessionPC extends JingleSession {
1665 1665
             });
1666 1666
     }
1667 1667
 
1668
+    /**
1669
+     * Replaces the existing mediaStream on the underlying peerconnection with the newly
1670
+     * added stream on the same JitsiLocalTrack wihtout the need to perform a offer/answer
1671
+     * cycle.
1672
+     * @param {JitsiLocalTrack} track - the current track in use whose media stream has been
1673
+     * updated.
1674
+     * @returns {Promise} which resolves once the replacement is complete or reject with an
1675
+     * error {string}.
1676
+     */
1677
+    replaceTrackWithoutOfferAnswer(track) {
1678
+        return this.peerconnection.replaceTrackWithoutOfferAnswer(track);
1679
+    }
1680
+
1668 1681
     /**
1669 1682
      * Replaces <tt>oldTrack</tt> with <tt>newTrack</tt> and performs a single
1670 1683
      * offer/answer cycle after both operations are done. Either

Carregando…
Cancelar
Salvar