[RN] Use native API for toggling cameras
Use the curstom _switchCamera API provided by react-native-webrtc to toggle the camera instead of destroying the current track and creating a new one. _switchCamera is implemented at a low level, so the track perceives no changes, thus being a lot faster and less involved since the capturer doesn't need to be destroyed and re-created. In addition, don't mirror the video for the back camera. Ref: https://github.com/oney/react-native-webrtc/pull/235
This commit is contained in:
parent
f5973e0eee
commit
7c76f124bf
|
@ -30,3 +30,15 @@ export const SET_CAMERA_FACING_MODE = Symbol('SET_CAMERA_FACING_MODE');
|
|||
* }
|
||||
*/
|
||||
export const SET_VIDEO_MUTED = Symbol('SET_VIDEO_MUTED');
|
||||
|
||||
/**
|
||||
* The type of (redux) action to toggle the local video camera facing mode. In
|
||||
* contrast to SET_CAMERA_FACING_MODE, allows the toggling to be optimally
|
||||
* and/or natively implemented without the overhead of separate reads and writes
|
||||
* of the current/effective camera facing mode.
|
||||
*
|
||||
* {
|
||||
* type: TOGGLE_CAMERA_FACING_MODE
|
||||
* }
|
||||
*/
|
||||
export const TOGGLE_CAMERA_FACING_MODE = Symbol('TOGGLE_CAMERA_FACING_MODE');
|
||||
|
|
|
@ -5,7 +5,8 @@ import type { Dispatch } from 'redux';
|
|||
import {
|
||||
SET_AUDIO_MUTED,
|
||||
SET_CAMERA_FACING_MODE,
|
||||
SET_VIDEO_MUTED
|
||||
SET_VIDEO_MUTED,
|
||||
TOGGLE_CAMERA_FACING_MODE
|
||||
} from './actionTypes';
|
||||
import { CAMERA_FACING_MODE } from './constants';
|
||||
|
||||
|
@ -73,21 +74,19 @@ export function toggleAudioMuted() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Toggles the camera between front and rear (user and environment).
|
||||
* Toggles the camera facing mode. Most commonly, for example, mobile devices
|
||||
* such as phones have a front/user-facing and a back/environment-facing
|
||||
* cameras. In contrast to setCameraFacingMode, allows the toggling to be
|
||||
* optimally and/or natively implemented without the overhead of separate reads
|
||||
* and writes of the current/effective camera facing mode.
|
||||
*
|
||||
* @returns {Function}
|
||||
* @returns {{
|
||||
* type: TOGGLE_CAMERA_FACING_MODE
|
||||
* }}
|
||||
*/
|
||||
export function toggleCameraFacingMode() {
|
||||
return (dispatch: Dispatch<*>, getState: Function) => {
|
||||
let cameraFacingMode
|
||||
= getState()['features/base/media'].video.facingMode;
|
||||
|
||||
cameraFacingMode
|
||||
= cameraFacingMode === CAMERA_FACING_MODE.USER
|
||||
? CAMERA_FACING_MODE.ENVIRONMENT
|
||||
: CAMERA_FACING_MODE.USER;
|
||||
|
||||
return dispatch(setCameraFacingMode(cameraFacingMode));
|
||||
return {
|
||||
type: TOGGLE_CAMERA_FACING_MODE
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ import { ReducerRegistry } from '../redux';
|
|||
import {
|
||||
SET_AUDIO_MUTED,
|
||||
SET_CAMERA_FACING_MODE,
|
||||
SET_VIDEO_MUTED
|
||||
SET_VIDEO_MUTED,
|
||||
TOGGLE_CAMERA_FACING_MODE
|
||||
} from './actionTypes';
|
||||
import { CAMERA_FACING_MODE } from './constants';
|
||||
|
||||
|
@ -88,6 +89,20 @@ function _video(state = VIDEO_INITIAL_MEDIA_STATE, action) {
|
|||
muted: action.muted
|
||||
};
|
||||
|
||||
case TOGGLE_CAMERA_FACING_MODE: {
|
||||
let cameraFacingMode = state.facingMode;
|
||||
|
||||
cameraFacingMode
|
||||
= cameraFacingMode === CAMERA_FACING_MODE.USER
|
||||
? CAMERA_FACING_MODE.ENVIRONMENT
|
||||
: CAMERA_FACING_MODE.USER;
|
||||
|
||||
return {
|
||||
...state,
|
||||
facingMode: cameraFacingMode
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
SET_AUDIO_MUTED,
|
||||
SET_CAMERA_FACING_MODE,
|
||||
SET_VIDEO_MUTED,
|
||||
TOGGLE_CAMERA_FACING_MODE,
|
||||
setAudioMuted,
|
||||
setVideoMuted
|
||||
} from '../media';
|
||||
|
@ -64,6 +65,38 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
_setMuted(store, action, MEDIA_TYPE.VIDEO);
|
||||
break;
|
||||
|
||||
case TOGGLE_CAMERA_FACING_MODE: {
|
||||
const localTrack = _getLocalTrack(store, MEDIA_TYPE.VIDEO);
|
||||
let jitsiTrack;
|
||||
let mediaStreamTrack;
|
||||
|
||||
if (localTrack
|
||||
&& (jitsiTrack = localTrack.jitsiTrack)
|
||||
&& (mediaStreamTrack = jitsiTrack.track)) {
|
||||
// XXX MediaStreamTrack._switchCamera a custom function implemented
|
||||
// in react-native-webrtc for video which switches between the
|
||||
// cameras via a native WebRTC library implementation without making
|
||||
// any changes to the track.
|
||||
// FIXME JitsiLocalTrack defines getCameraFacingMode. By calling
|
||||
// _switchCamera on MediaStreamTrack without the knowledge of
|
||||
// lib-jitsi-meet we are likely introducing an inconsistency in
|
||||
// JitsiLocalTrack's state.
|
||||
mediaStreamTrack._switchCamera();
|
||||
|
||||
// Don't mirror the video of the back/environment-facing camera.
|
||||
// FIXME Relies on the fact that we always open the camera in
|
||||
// user-facing mode first.
|
||||
store.dispatch({
|
||||
type: TRACK_UPDATED,
|
||||
track: {
|
||||
jitsiTrack,
|
||||
mirror: !localTrack.mirror
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRACK_UPDATED:
|
||||
return _trackUpdated(store, next, action);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue