fix(AudioOnly+web): crash when untoggle audio only
Because on web video track is stored both in redux and in 'localVideo' field, video is attempted to be unmuted twice when turning off the audio only mode. This will crash the app with 'unmute operation is already in progress'. This commit will prevent from taking action from the web world if the video track already exists and will make the redux side rollback unmuted status in case unmute fails.
This commit is contained in:
parent
2525bb2805
commit
122a7f6346
|
@ -752,6 +752,9 @@ export default {
|
|||
if (!this._localTracksInitialized) {
|
||||
this.videoMuted = mute;
|
||||
|
||||
return;
|
||||
} else if (localVideo && localVideo.isMuted() === mute) {
|
||||
// NO-OP
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1994,7 +1997,23 @@ export default {
|
|||
);
|
||||
|
||||
APP.UI.addListener(UIEvents.TOGGLE_AUDIO_ONLY, audioOnly => {
|
||||
this.muteVideo(audioOnly);
|
||||
|
||||
// FIXME On web video track is stored both in redux and in
|
||||
// 'localVideo' field, video is attempted to be unmuted twice when
|
||||
// turning off the audio only mode. This will crash the app with
|
||||
// 'unmute operation is already in progress'.
|
||||
// Because there's no logic in redux about creating new track in
|
||||
// case unmute when not track exists the things have to go through
|
||||
// muteVideo logic in such case.
|
||||
const tracks = APP.store.getState()['features/base/tracks'];
|
||||
const isTrackInRedux
|
||||
= Boolean(
|
||||
tracks.find(
|
||||
track => track.jitsiTrack
|
||||
&& track.jitsiTrack.getType() === 'video'));
|
||||
if (!isTrackInRedux) {
|
||||
this.muteVideo(audioOnly);
|
||||
}
|
||||
|
||||
// Immediately update the UI by having remote videos and the large
|
||||
// video update themselves instead of waiting for some other event
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
setCameraFacingMode,
|
||||
setVideoMuted
|
||||
} from './actions';
|
||||
import { CAMERA_FACING_MODE } from './constants';
|
||||
import { CAMERA_FACING_MODE, MEDIA_TYPE } from './constants';
|
||||
|
||||
/**
|
||||
* Middleware that captures CONFERENCE_LEFT action and restores initial state
|
||||
|
@ -70,6 +70,15 @@ function _syncTrackMutedState(store, track) {
|
|||
// fired before track gets to state.
|
||||
if (track.muted !== muted) {
|
||||
track.muted = muted;
|
||||
setTrackMuted(track.jitsiTrack, muted);
|
||||
setTrackMuted(track.jitsiTrack, muted)
|
||||
.catch(error => {
|
||||
console.error(`setTrackMuted(${muted}) failed`, error);
|
||||
const setMuted
|
||||
= track.mediaType === MEDIA_TYPE.AUDIO
|
||||
? setAudioMuted : setVideoMuted;
|
||||
|
||||
// Failed to sync muted state - dispatch rollback action
|
||||
store.dispatch(setMuted(!muted));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,9 +174,5 @@ export function setTrackMuted(track, muted) {
|
|||
|
||||
const f = muted ? 'mute' : 'unmute';
|
||||
|
||||
return track[f]()
|
||||
.catch(err => {
|
||||
console.warn(`Track ${f} was rejected:`, err);
|
||||
throw err;
|
||||
});
|
||||
return track[f]();
|
||||
}
|
||||
|
|
|
@ -160,7 +160,19 @@ function _getLocalTrack(store, mediaType: MEDIA_TYPE) {
|
|||
function _setMuted(store, action, mediaType: MEDIA_TYPE) {
|
||||
const localTrack = _getLocalTrack(store, mediaType);
|
||||
|
||||
localTrack && setTrackMuted(localTrack.jitsiTrack, action.muted);
|
||||
if (localTrack) {
|
||||
setTrackMuted(localTrack.jitsiTrack, action.muted)
|
||||
.catch(error => {
|
||||
console.error(`setTrackMuted(${action.muted}) failed`, error);
|
||||
|
||||
const setMuted
|
||||
= mediaType === MEDIA_TYPE.AUDIO
|
||||
? setAudioMuted : setVideoMuted;
|
||||
|
||||
// Failed to modify muted state - dispatch rollback action
|
||||
store.dispatch(setMuted(!action.muted));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue