浏览代码

[RN] Make video track fade-in effect cross-platform

Android uses a SurfaceView to render video, which is not quite a View, so the
fade-in animation (which varies the opacity) doesn't work.

Instead, add an opaque black view covering the video, which transitions to
transparent. This creates much smoother transitions on Android, while behaving
the same.

In addition, I removed the flip animation for local tracks, which is no longer
used, since the camera is switched without changing tracks.
master
Saúl Ibarra Corretgé 7 年前
父节点
当前提交
75f6786588

+ 14
- 29
react/features/base/media/components/native/VideoTrack.js 查看文件

@@ -1,5 +1,5 @@
1 1
 import React from 'react';
2
-import { Animated } from 'react-native';
2
+import { Animated, View } from 'react-native';
3 3
 import { connect } from 'react-redux';
4 4
 
5 5
 import AbstractVideoTrack from '../AbstractVideoTrack';
@@ -41,8 +41,7 @@ class VideoTrack extends AbstractVideoTrack {
41 41
          */
42 42
         this.state = {
43 43
             ...this.state,
44
-            fade: new Animated.Value(1),
45
-            flip: new Animated.Value(1)
44
+            fade: new Animated.Value(0)
46 45
         };
47 46
     }
48 47
 
@@ -53,11 +52,14 @@ class VideoTrack extends AbstractVideoTrack {
53 52
      * @returns {ReactElement}
54 53
      */
55 54
     render() {
55
+        const animatedStyles
56
+            = [ styles.videoCover, this._getAnimationStyles() ];
57
+
56 58
         return (
57
-            <Animated.View
58
-                style = { [ styles.video, this._getAnimationStyles() ] }>
59
+            <View style = { styles.video } >
59 60
                 { super.render() }
60
-            </Animated.View>
61
+                <Animated.View style = { animatedStyles } />
62
+            </View>
61 63
         );
62 64
     }
63 65
 
@@ -76,23 +78,14 @@ class VideoTrack extends AbstractVideoTrack {
76 78
         if (this._animation) {
77 79
             this._animation.stop();
78 80
             this._animation = null;
79
-            this.state.fade.setValue(1);
80
-            this.state.flip.setValue(1);
81
+            this.state.fade.setValue(0);
81 82
         }
82 83
 
83
-        // If we're switching between two local video tracks, that actually
84
-        // means we're switching local cameras, so we'll use a flip animation.
85
-        // Otherwise, we'll use fade animation.
86
-        const animation
87
-            = oldValue && newValue && oldValue.local && newValue.local
88
-                ? 'flip'
89
-                : 'fade';
90
-
91
-        return this._animateVideoTrack(animation, 0)
84
+        return this._animateVideoTrack(1)
92 85
             .then(() => {
93 86
                 super._setVideoTrack(newValue);
94 87
 
95
-                return this._animateVideoTrack(animation, 1);
88
+                return this._animateVideoTrack(0);
96 89
             })
97 90
             .catch(() => {
98 91
                 console.log('Animation was stopped');
@@ -102,17 +95,15 @@ class VideoTrack extends AbstractVideoTrack {
102 95
     /**
103 96
      * Animates the display of the state videoTrack.
104 97
      *
105
-     * @param {string} animatedValue - The name of the state property which
106
-     * specifies the Animated.Value to be animated.
107 98
      * @param {number} toValue - The value to which the specified animatedValue
108 99
      * is to be animated.
109 100
      * @private
110 101
      * @returns {Promise}
111 102
      */
112
-    _animateVideoTrack(animatedValue, toValue) {
103
+    _animateVideoTrack(toValue) {
113 104
         return new Promise((resolve, reject) => {
114 105
             this._animation
115
-                = Animated.timing(this.state[animatedValue], { toValue });
106
+                = Animated.timing(this.state.fade, { toValue });
116 107
             this._animation.start(result => {
117 108
                 this._animation = null;
118 109
                 result.finished ? resolve() : reject();
@@ -128,13 +119,7 @@ class VideoTrack extends AbstractVideoTrack {
128 119
      */
129 120
     _getAnimationStyles() {
130 121
         return {
131
-            opacity: this.state.fade,
132
-            transform: [ {
133
-                rotateY: this.state.flip.interpolate({
134
-                    inputRange: [ 0, 1 ],
135
-                    outputRange: [ '90deg', '0deg' ]
136
-                })
137
-            } ]
122
+            opacity: this.state.fade
138 123
         };
139 124
     }
140 125
 

+ 20
- 8
react/features/base/media/components/native/styles.js 查看文件

@@ -1,15 +1,27 @@
1 1
 import { StyleSheet } from 'react-native';
2
-
3
-/**
4
- * Make {@code Video} fill its container.
5
- */
6
-const video = {
7
-    flex: 1
8
-};
2
+import { ColorPalette } from '../../../styles';
9 3
 
10 4
 /**
11 5
  * The styles of the feature base/media.
12 6
  */
13 7
 export default StyleSheet.create({
14
-    video
8
+    /**
9
+     * Make {@code Video} fill its container.
10
+     */
11
+    video: {
12
+        flex: 1
13
+    },
14
+
15
+    /**
16
+     * Black cover for the video, which will be animated by reducing its opacity
17
+     * and create a fade-in effect.
18
+     */
19
+    videoCover: {
20
+        backgroundColor: ColorPalette.black,
21
+        height: '100%',
22
+        left: 0,
23
+        position: 'absolute',
24
+        top: 0,
25
+        width: '100%'
26
+    }
15 27
 });

正在加载...
取消
保存