diff options
author | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2022-07-30 14:10:43 +0300 |
---|---|---|
committer | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2022-08-11 11:37:03 +0300 |
commit | 23825308e2c667085b2fc0cf723c9481102dbe83 (patch) | |
tree | 819d0eb656121eae1e6f20058e083b912c9f5840 | |
parent | 61d0fe08b5f011f47dd3306fd0b791efda88d1d0 (diff) |
Split local streams and sent streams
Until now the stream locally shown was the stream sent to the other
peers. Now there are separate streams for each case to be able to adjust
them independently to work around specific browser behaviours.
Nevertheless, the sent stream is a single stream shared by all sender
peers, not a stream specific for each peer, so it is still generated in
the local media class, just like the local stream.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
-rw-r--r-- | src/utils/webrtc/simplewebrtc/localmedia.js | 66 | ||||
-rw-r--r-- | src/utils/webrtc/simplewebrtc/peer.js | 24 |
2 files changed, 66 insertions, 24 deletions
diff --git a/src/utils/webrtc/simplewebrtc/localmedia.js b/src/utils/webrtc/simplewebrtc/localmedia.js index ab99bf681..47a9a4132 100644 --- a/src/utils/webrtc/simplewebrtc/localmedia.js +++ b/src/utils/webrtc/simplewebrtc/localmedia.js @@ -39,6 +39,7 @@ function LocalMedia(opts) { this._localMediaActive = false this.localStreams = [] + this.sentStreams = [] this.localScreens = [] if (!webrtcIndex.mediaDevicesManager.isSupported()) { @@ -78,6 +79,10 @@ function LocalMedia(opts) { this._trackToStream.addInputTrackSlot('audio') this._trackToStream.addInputTrackSlot('video') + this._trackToSentStream = new TrackToStream() + this._trackToSentStream.addInputTrackSlot('audio') + this._trackToSentStream.addInputTrackSlot('video') + this._handleStreamSetBound = this._handleStreamSet.bind(this) this._handleTrackReplacedBound = this._handleTrackReplaced.bind(this) this._handleTrackEnabledBound = this._handleTrackEnabled.bind(this) @@ -87,12 +92,14 @@ function LocalMedia(opts) { this._audioTrackEnabler.connectTrackSink('default', this._speakingMonitor) this._audioTrackEnabler.connectTrackSink('default', this._trackToStream, 'audio') + this._audioTrackEnabler.connectTrackSink('default', this._trackToSentStream, 'audio') this._videoTrackEnabler.connectTrackSink('default', this._videoTrackConstrainer) this._videoTrackConstrainer.connectTrackSink('default', this._virtualBackground) this._virtualBackground.connectTrackSink('default', this._trackToStream, 'video') + this._virtualBackground.connectTrackSink('default', this._trackToSentStream, 'video') } util.inherits(LocalMedia, WildEmitter) @@ -166,6 +173,7 @@ LocalMedia.prototype.start = function(mediaConstraints, cb, context) { this._mediaDevicesSource.start(retryNoVideoCallback).then(() => { self.localStreams.push(self._trackToStream.getStream()) + self.sentStreams.push(self._trackToSentStream.getStream()) self.emit('localStream', self._trackToStream.getStream()) @@ -173,6 +181,10 @@ LocalMedia.prototype.start = function(mediaConstraints, cb, context) { self._trackToStream.on('trackReplaced', self._handleTrackReplacedBound) self._trackToStream.on('trackEnabled', self._handleTrackEnabledBound) + self._trackToSentStream.on('streamSet', self._handleStreamSetBound) + self._trackToSentStream.on('trackReplaced', self._handleTrackReplacedBound) + self._trackToSentStream.on('trackEnabled', self._handleTrackEnabledBound) + self._localMediaActive = true if (cb) { @@ -190,6 +202,10 @@ LocalMedia.prototype.start = function(mediaConstraints, cb, context) { self._trackToStream.on('trackReplaced', self._handleTrackReplacedBound) self._trackToStream.on('trackEnabled', self._handleTrackEnabledBound) + self._trackToSentStream.on('streamSet', self._handleStreamSetBound) + self._trackToSentStream.on('trackReplaced', self._handleTrackReplacedBound) + self._trackToSentStream.on('trackEnabled', self._handleTrackEnabledBound) + self._localMediaActive = true if (cb) { @@ -204,7 +220,7 @@ LocalMedia.prototype._handleStreamSet = function(trackToStream, newStream, oldSt } if (newStream) { - this.localStreams.push(newStream) + trackToStream === this._trackToStream ? this.localStreams.push(newStream) : this.sentStreams.push(newStream) } // "streamSet" is always emitted along with "trackReplaced", so the @@ -212,16 +228,24 @@ LocalMedia.prototype._handleStreamSet = function(trackToStream, newStream, oldSt } LocalMedia.prototype._handleTrackReplaced = function(trackToStream, newTrack, oldTrack) { - // "localStreamChanged" is expected to be emitted also when the tracks of - // the stream change, even if the stream itself is the same. - this.emit('localStreamChanged', trackToStream.getStream()) - this.emit('localTrackReplaced', newTrack, oldTrack, trackToStream.getStream()) + if (trackToStream === this._trackToStream) { + // "localStreamChanged" is expected to be emitted also when the tracks + // of the stream change, even if the stream itself is the same. + this.emit('localStreamChanged', trackToStream.getStream()) + this.emit('localTrackReplaced', newTrack, oldTrack, trackToStream.getStream()) + } else { + this.emit('sentTrackReplaced', newTrack, oldTrack, trackToStream.getStream()) + } } LocalMedia.prototype._handleTrackEnabled = function(trackToStream, track) { // MediaStreamTrack does not emit an event when the enabled property // changes, so it needs to be explicitly notified. - this.emit('localTrackEnabledChanged', track, trackToStream.getStream()) + if (trackToStream === this._trackToStream) { + this.emit('localTrackEnabledChanged', track, trackToStream.getStream()) + } else { + this.emit('sentTrackEnabledChanged', track, trackToStream.getStream()) + } } LocalMedia.prototype.stop = function() { @@ -231,6 +255,10 @@ LocalMedia.prototype.stop = function() { this._trackToStream.off('trackReplaced', this._handleTrackReplacedBound) this._trackToStream.off('trackEnabled', this._handleTrackEnabledBound) + this._trackToSentStream.off('streamSet', this._handleStreamSetBound) + this._trackToSentStream.off('trackReplaced', this._handleTrackReplacedBound) + this._trackToSentStream.off('trackEnabled', this._handleTrackEnabledBound) + this.stopStream() this.stopScreenShare() @@ -239,12 +267,16 @@ LocalMedia.prototype.stop = function() { LocalMedia.prototype.stopStream = function() { const stream = this._trackToStream.getStream() + const sentStream = this._trackToSentStream.getStream() this._mediaDevicesSource.stop() if (stream) { this._removeStream(stream) } + if (sentStream) { + this._removeStream(sentStream) + } } LocalMedia.prototype.startScreenShare = function(mode, constraints, cb) { @@ -431,12 +463,22 @@ LocalMedia.prototype._removeStream = function(stream) { if (idx > -1) { this.localStreams.splice(idx, 1) this.emit('localStreamStopped', stream) - } else { - idx = this.localScreens.indexOf(stream) - if (idx > -1) { - this.localScreens.splice(idx, 1) - this.emit('localScreenStopped', stream) - } + + return + } + + idx = this.sentStreams.indexOf(stream) + if (idx > -1) { + this.sentStreams.splice(idx, 1) + this.emit('sentStreamStopped', stream) + + return + } + + idx = this.localScreens.indexOf(stream) + if (idx > -1) { + this.localScreens.splice(idx, 1) + this.emit('localScreenStopped', stream) } } diff --git a/src/utils/webrtc/simplewebrtc/peer.js b/src/utils/webrtc/simplewebrtc/peer.js index edf7885ea..df67298fd 100644 --- a/src/utils/webrtc/simplewebrtc/peer.js +++ b/src/utils/webrtc/simplewebrtc/peer.js @@ -70,7 +70,7 @@ function Peer(options) { if (sender.track) { // The stream is not known, but it is only used when the // track is added, so it can be ignored here. - self.handleLocalTrackEnabledChanged(sender.track, null) + self.handleSentTrackEnabledChanged(sender.track, null) } }) @@ -122,7 +122,7 @@ function Peer(options) { this.broadcaster = options.broadcaster } } else { - this.parent.localStreams.forEach(function(stream) { + this.parent.sentStreams.forEach(function(stream) { stream.getTracks().forEach(function(track) { if (track.kind !== 'video' || self.sendVideoIfAvailable) { self.pc.addTrack(track, stream) @@ -130,13 +130,13 @@ function Peer(options) { }) }) - this.handleLocalTrackReplacedBound = this.handleLocalTrackReplaced.bind(this) + this.handleSentTrackReplacedBound = this.handleSentTrackReplaced.bind(this) // TODO What would happen if the track is replaced while the peer is // still negotiating the offer and answer? - this.parent.on('localTrackReplaced', this.handleLocalTrackReplacedBound) + this.parent.on('sentTrackReplaced', this.handleSentTrackReplacedBound) - this.handleLocalTrackEnabledChangedBound = this.handleLocalTrackEnabledChanged.bind(this) - this.parent.on('localTrackEnabledChanged', this.handleLocalTrackEnabledChangedBound) + this.handleSentTrackEnabledChangedBound = this.handleSentTrackEnabledChanged.bind(this) + this.parent.on('sentTrackEnabledChanged', this.handleSentTrackEnabledChangedBound) } } @@ -675,13 +675,13 @@ Peer.prototype.end = function() { } this.pc.close() this.handleStreamRemoved() - this.parent.off('localTrackReplaced', this.handleLocalTrackReplacedBound) - this.parent.off('localTrackEnabledChanged', this.handleLocalTrackEnabledChangedBound) + this.parent.off('sentTrackReplaced', this.handleSentTrackReplacedBound) + this.parent.off('sentTrackEnabledChanged', this.handleSentTrackEnabledChangedBound) this.parent.emit('peerEnded', this) } -Peer.prototype.handleLocalTrackReplaced = function(newTrack, oldTrack, stream) { +Peer.prototype.handleSentTrackReplaced = function(newTrack, oldTrack, stream) { this._pendingReplaceTracksQueue.push({ newTrack, oldTrack, stream }) this._processPendingReplaceTracks() @@ -864,14 +864,14 @@ Peer.prototype._replaceTrack = async function(newTrack, oldTrack, stream) { return Promise.allSettled(replaceTrackPromises) } -Peer.prototype.handleLocalTrackEnabledChanged = function(track, stream) { +Peer.prototype.handleSentTrackEnabledChanged = function(track, stream) { const sender = this.pc.getSenders().find(sender => sender.track === track) const stoppedSender = this.pc.getSenders().find(sender => sender.trackDisabled === track) if (track.enabled && stoppedSender) { - this.handleLocalTrackReplacedBound(track, track, stream) + this.handleSentTrackReplacedBound(track, track, stream) } else if (!track.enabled && sender) { - this.handleLocalTrackReplacedBound(track, track, stream) + this.handleSentTrackReplacedBound(track, track, stream) } } |