Handle track changes when call was started without audio or video

When the call was started without audio nor video (either explicitly or
because there was an error when getting the media) the media device
changes were not listened to, so further device changes were ignored and
"localTrackReplaced" events were not emitted.

Moreover, "localTrackReplaced" events were handled by Peer objects to
replace or add tracks as needed, but if a call is started without media
some Peer objects will be missing (the ownPeer object if the HPB is
used, Peer objects for any other participant that is not sending media
when the HPB is not used). Therefore now a forced reconnection is
triggered when needed to establish the missing sender connections.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
Daniel Calviño Sánchez 2021-05-20 02:39:41 +02:00
Родитель a55563fa75
Коммит 086e474060
2 изменённых файлов: 45 добавлений и 4 удалений

Просмотреть файл

@ -144,6 +144,10 @@ LocalMedia.prototype.start = function(mediaConstraints, cb, context) {
webrtcIndex.mediaDevicesManager.disableDeviceEvents()
}
// The handlers for "change:audioInputId" and "change:videoInputId" events
// expect the initial "getUserMedia" call to have been completed before
// being used, so they must be set when the promise is resolved or rejected.
webrtcIndex.mediaDevicesManager.getUserMedia(constraints).then(function(stream) {
// Although the promise should be resolved only if all the constraints
// are met Edge resolves it if both audio and video are requested but
@ -197,6 +201,9 @@ LocalMedia.prototype.start = function(mediaConstraints, cb, context) {
self.emit('localStreamRequestFailed', constraints)
webrtcIndex.mediaDevicesManager.on('change:audioInputId', self._handleAudioInputIdChangedBound)
webrtcIndex.mediaDevicesManager.on('change:videoInputId', self._handleVideoInputIdChangedBound)
if (cb) {
return cb(err, null)
}
@ -484,10 +491,8 @@ LocalMedia.prototype.stop = function(stream) {
this.stopStream(stream)
this.stopScreenShare(stream)
if (!this.localStreams.length) {
webrtcIndex.mediaDevicesManager.off('change:audioInputId', this._handleAudioInputIdChangedBound)
webrtcIndex.mediaDevicesManager.off('change:videoInputId', this._handleVideoInputIdChangedBound)
}
webrtcIndex.mediaDevicesManager.off('change:audioInputId', this._handleAudioInputIdChangedBound)
webrtcIndex.mediaDevicesManager.off('change:videoInputId', this._handleVideoInputIdChangedBound)
}
LocalMedia.prototype.stopStream = function(stream) {

Просмотреть файл

@ -49,6 +49,7 @@ let callParticipantCollection = null
let localCallParticipantModel = null
let showedTURNWarning = false
let sendCurrentStateWithRepetitionTimeout = null
let startedWithMedia
function arrayDiff(a, b) {
return a.filter(function(i) {
@ -552,6 +553,8 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
})
webrtc.startMedia = function(token) {
startedWithMedia = undefined
webrtc.joinCall(token)
}
@ -872,6 +875,8 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
// reconnection is forced to start sending it.
signaling.setSendVideoIfAvailable(true)
startedWithMedia = true
let flags = signaling.getCurrentCallFlags()
flags |= PARTICIPANT.CALL_FLAG.WITH_VIDEO
@ -937,9 +942,38 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
}
})
webrtc.on('localTrackReplaced', function(newTrack /*, oldTrack, stream */) {
// Device disabled, nothing to do here.
if (!newTrack) {
return
}
// If the call was started with media the connections will be already
// established. If it has not started yet the connections will be
// established once started.
if (startedWithMedia || startedWithMedia === undefined) {
return
}
// If the call was originally started without media the participant
// needs to reconnect to establish the sender connections.
startedWithMedia = true
let flags = signaling.getCurrentCallFlags()
if (newTrack.kind === 'audio') {
flags |= PARTICIPANT.CALL_FLAG.WITH_AUDIO
} else if (newTrack.kind === 'video') {
flags |= PARTICIPANT.CALL_FLAG.WITH_VIDEO
}
forceReconnect(signaling, flags)
})
webrtc.on('localMediaStarted', function(/* configuration */) {
console.info('localMediaStarted')
startedWithMedia = true
clearLocalStreamRequestedTimeoutAndHideNotification()
if (signaling.hasFeature('mcu')) {
@ -950,6 +984,8 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
webrtc.on('localMediaError', function(error) {
console.warn('Access to microphone & camera failed', error)
startedWithMedia = false
clearLocalStreamRequestedTimeoutAndHideNotification()
let message