Преглед изворни кода

[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
j8
Saúl Ibarra Corretgé пре 8 година
родитељ
комит
7c76f124bf

+ 12
- 0
react/features/base/media/actionTypes.js Прегледај датотеку

@@ -30,3 +30,15 @@ export const SET_CAMERA_FACING_MODE = Symbol('SET_CAMERA_FACING_MODE');
30 30
  * }
31 31
  */
32 32
 export const SET_VIDEO_MUTED = Symbol('SET_VIDEO_MUTED');
33
+
34
+/**
35
+ * The type of (redux) action to toggle the local video camera facing mode. In
36
+ * contrast to SET_CAMERA_FACING_MODE, allows the toggling to be optimally
37
+ * and/or natively implemented without the overhead of separate reads and writes
38
+ * of the current/effective camera facing mode.
39
+ *
40
+ * {
41
+ *     type: TOGGLE_CAMERA_FACING_MODE
42
+ * }
43
+ */
44
+export const TOGGLE_CAMERA_FACING_MODE = Symbol('TOGGLE_CAMERA_FACING_MODE');

+ 12
- 13
react/features/base/media/actions.js Прегледај датотеку

@@ -5,7 +5,8 @@ import type { Dispatch } from 'redux';
5 5
 import {
6 6
     SET_AUDIO_MUTED,
7 7
     SET_CAMERA_FACING_MODE,
8
-    SET_VIDEO_MUTED
8
+    SET_VIDEO_MUTED,
9
+    TOGGLE_CAMERA_FACING_MODE
9 10
 } from './actionTypes';
10 11
 import { CAMERA_FACING_MODE } from './constants';
11 12
 
@@ -73,21 +74,19 @@ export function toggleAudioMuted() {
73 74
 }
74 75
 
75 76
 /**
76
- * Toggles the camera between front and rear (user and environment).
77
+ * Toggles the camera facing mode. Most commonly, for example, mobile devices
78
+ * such as phones have a front/user-facing and a back/environment-facing
79
+ * cameras. In contrast to setCameraFacingMode, allows the toggling to be
80
+ * optimally and/or natively implemented without the overhead of separate reads
81
+ * and writes of the current/effective camera facing mode.
77 82
  *
78
- * @returns {Function}
83
+ * @returns {{
84
+ *     type: TOGGLE_CAMERA_FACING_MODE
85
+ * }}
79 86
  */
80 87
 export function toggleCameraFacingMode() {
81
-    return (dispatch: Dispatch<*>, getState: Function) => {
82
-        let cameraFacingMode
83
-            = getState()['features/base/media'].video.facingMode;
84
-
85
-        cameraFacingMode
86
-            = cameraFacingMode === CAMERA_FACING_MODE.USER
87
-                ? CAMERA_FACING_MODE.ENVIRONMENT
88
-                : CAMERA_FACING_MODE.USER;
89
-
90
-        return dispatch(setCameraFacingMode(cameraFacingMode));
88
+    return {
89
+        type: TOGGLE_CAMERA_FACING_MODE
91 90
     };
92 91
 }
93 92
 

+ 16
- 1
react/features/base/media/reducer.js Прегледај датотеку

@@ -5,7 +5,8 @@ import { ReducerRegistry } from '../redux';
5 5
 import {
6 6
     SET_AUDIO_MUTED,
7 7
     SET_CAMERA_FACING_MODE,
8
-    SET_VIDEO_MUTED
8
+    SET_VIDEO_MUTED,
9
+    TOGGLE_CAMERA_FACING_MODE
9 10
 } from './actionTypes';
10 11
 import { CAMERA_FACING_MODE } from './constants';
11 12
 
@@ -88,6 +89,20 @@ function _video(state = VIDEO_INITIAL_MEDIA_STATE, action) {
88 89
             muted: action.muted
89 90
         };
90 91
 
92
+    case TOGGLE_CAMERA_FACING_MODE: {
93
+        let cameraFacingMode = state.facingMode;
94
+
95
+        cameraFacingMode
96
+            = cameraFacingMode === CAMERA_FACING_MODE.USER
97
+                ? CAMERA_FACING_MODE.ENVIRONMENT
98
+                : CAMERA_FACING_MODE.USER;
99
+
100
+        return {
101
+            ...state,
102
+            facingMode: cameraFacingMode
103
+        };
104
+    }
105
+
91 106
     default:
92 107
         return state;
93 108
     }

+ 33
- 0
react/features/base/tracks/middleware.js Прегледај датотеку

@@ -6,6 +6,7 @@ import {
6 6
     SET_AUDIO_MUTED,
7 7
     SET_CAMERA_FACING_MODE,
8 8
     SET_VIDEO_MUTED,
9
+    TOGGLE_CAMERA_FACING_MODE,
9 10
     setAudioMuted,
10 11
     setVideoMuted
11 12
 } from '../media';
@@ -64,6 +65,38 @@ MiddlewareRegistry.register(store => next => action => {
64 65
         _setMuted(store, action, MEDIA_TYPE.VIDEO);
65 66
         break;
66 67
 
68
+    case TOGGLE_CAMERA_FACING_MODE: {
69
+        const localTrack = _getLocalTrack(store, MEDIA_TYPE.VIDEO);
70
+        let jitsiTrack;
71
+        let mediaStreamTrack;
72
+
73
+        if (localTrack
74
+                && (jitsiTrack = localTrack.jitsiTrack)
75
+                && (mediaStreamTrack = jitsiTrack.track)) {
76
+            // XXX MediaStreamTrack._switchCamera a custom function implemented
77
+            // in react-native-webrtc for video which switches between the
78
+            // cameras via a native WebRTC library implementation without making
79
+            // any changes to the track.
80
+            // FIXME JitsiLocalTrack defines getCameraFacingMode. By calling
81
+            // _switchCamera on MediaStreamTrack without the knowledge of
82
+            // lib-jitsi-meet we are likely introducing an inconsistency in
83
+            // JitsiLocalTrack's state.
84
+            mediaStreamTrack._switchCamera();
85
+
86
+            // Don't mirror the video of the back/environment-facing camera.
87
+            // FIXME Relies on the fact that we always open the camera in
88
+            // user-facing mode first.
89
+            store.dispatch({
90
+                type: TRACK_UPDATED,
91
+                track: {
92
+                    jitsiTrack,
93
+                    mirror: !localTrack.mirror
94
+                }
95
+            });
96
+        }
97
+        break;
98
+    }
99
+
67 100
     case TRACK_UPDATED:
68 101
         return _trackUpdated(store, next, action);
69 102
     }

Loading…
Откажи
Сачувај