Quellcode durchsuchen

feat(virtual-background) add slight blur option

master
Tudor D. Pop vor 4 Jahren
Ursprung
Commit
af28080058
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden

+ 1
- 1
css/modals/virtual-background/_virtual-background.scss Datei anzeigen

1
 .virtual-background-dialog {
1
 .virtual-background-dialog {
2
     display: inline-grid;
2
     display: inline-grid;
3
-    grid-template-columns: auto auto auto auto auto auto auto;
3
+    grid-template-columns: auto auto auto auto auto auto auto auto;
4
     max-width: 370px;
4
     max-width: 370px;
5
     cursor: pointer;
5
     cursor: pointer;
6
     .thumbnail {
6
     .thumbnail {

+ 2
- 1
lang/main.json Datei anzeigen

339
     },
339
     },
340
     "virtualBackground": {
340
     "virtualBackground": {
341
         "title": "Backgrounds",
341
         "title": "Backgrounds",
342
-        "enableBlur": "Enable blur",
342
+        "blur": "Blur",
343
+        "slightBlur": "Slight Blur",
343
         "removeBackground": "Remove background",
344
         "removeBackground": "Remove background",
344
         "uploadImage": "Upload image",
345
         "uploadImage": "Upload image",
345
         "pleaseWait": "Please wait...",
346
         "pleaseWait": "Please wait...",

+ 6
- 7
react/features/stream-effects/virtual-background/JitsiStreamBackgroundEffect.js Datei anzeigen

5
     SET_TIMEOUT,
5
     SET_TIMEOUT,
6
     timerWorkerScript
6
     timerWorkerScript
7
 } from './TimerWorker';
7
 } from './TimerWorker';
8
-const blurValue = '25px';
9
 
8
 
10
 /**
9
 /**
11
  * Represents a modified MediaStream that adds effects to video background.
10
  * Represents a modified MediaStream that adds effects to video background.
40
     constructor(model: Object, options: Object) {
39
     constructor(model: Object, options: Object) {
41
         this._options = options;
40
         this._options = options;
42
 
41
 
43
-        if (this._options.virtualBackground.isVirtualBackground) {
42
+        if (this._options.virtualBackground.backgroundType === 'image') {
44
             this._virtualImage = document.createElement('img');
43
             this._virtualImage = document.createElement('img');
45
             this._virtualImage.crossOrigin = 'anonymous';
44
             this._virtualImage.crossOrigin = 'anonymous';
46
             this._virtualImage.src = this._options.virtualBackground.virtualSource;
45
             this._virtualImage.src = this._options.virtualBackground.virtualSource;
65
      * @param {EventHandler} response - The onmessage EventHandler parameter.
64
      * @param {EventHandler} response - The onmessage EventHandler parameter.
66
      * @returns {void}
65
      * @returns {void}
67
      */
66
      */
68
-    async _onMaskFrameTimer(response: Object) {
67
+    _onMaskFrameTimer(response: Object) {
69
         if (response.data.id === TIMEOUT_TICK) {
68
         if (response.data.id === TIMEOUT_TICK) {
70
-            await this._renderMask();
69
+            this._renderMask();
71
         }
70
         }
72
     }
71
     }
73
 
72
 
83
         //
82
         //
84
 
83
 
85
         // Smooth out the edges.
84
         // Smooth out the edges.
86
-        if (this._options.virtualBackground.isVirtualBackground) {
85
+        if (this._options.virtualBackground.backgroundType === 'image') {
87
             this._outputCanvasCtx.filter = 'blur(4px)';
86
             this._outputCanvasCtx.filter = 'blur(4px)';
88
         } else {
87
         } else {
89
             this._outputCanvasCtx.filter = 'blur(8px)';
88
             this._outputCanvasCtx.filter = 'blur(8px)';
112
         //
111
         //
113
 
112
 
114
         this._outputCanvasCtx.globalCompositeOperation = 'destination-over';
113
         this._outputCanvasCtx.globalCompositeOperation = 'destination-over';
115
-        if (this._options.virtualBackground.isVirtualBackground) {
114
+        if (this._options.virtualBackground.backgroundType === 'image') {
116
             this._outputCanvasCtx.drawImage(
115
             this._outputCanvasCtx.drawImage(
117
                 this._virtualImage,
116
                 this._virtualImage,
118
                 0,
117
                 0,
121
                 this._inputVideoElement.height
120
                 this._inputVideoElement.height
122
             );
121
             );
123
         } else {
122
         } else {
124
-            this._outputCanvasCtx.filter = `blur(${blurValue})`;
123
+            this._outputCanvasCtx.filter = `blur(${this._options.virtualBackground.blurValue}px)`;
125
             this._outputCanvasCtx.drawImage(this._inputVideoElement, 0, 0);
124
             this._outputCanvasCtx.drawImage(this._inputVideoElement, 0, 0);
126
         }
125
         }
127
     }
126
     }

+ 2
- 2
react/features/virtual-background/actionTypes.js Datei anzeigen

6
  *
6
  *
7
  * @returns {{
7
  * @returns {{
8
  *     type: BACKGROUND_ENABLED,
8
  *     type: BACKGROUND_ENABLED,
9
- *     backgroundEffectEnabled: boolean,
9
+ *     backgroundEffectEnabled: boolean
10
  * }}
10
  * }}
11
  */
11
  */
12
 export const BACKGROUND_ENABLED = 'BACKGROUND_ENABLED';
12
 export const BACKGROUND_ENABLED = 'BACKGROUND_ENABLED';
16
  *
16
  *
17
  * @returns {{
17
  * @returns {{
18
  *     type: SET_VIRTUAL_BACKGROUND,
18
  *     type: SET_VIRTUAL_BACKGROUND,
19
- *     isVirtualBackground: boolean,
20
  *     virtualSource: string,
19
  *     virtualSource: string,
20
+ *     blurValue: number,
21
  * }}
21
  * }}
22
  */
22
  */
23
 export const SET_VIRTUAL_BACKGROUND = 'SET_VIRTUAL_BACKGROUND';
23
 export const SET_VIRTUAL_BACKGROUND = 'SET_VIRTUAL_BACKGROUND';

+ 13
- 12
react/features/virtual-background/actions.js Datei anzeigen

9
 /**
9
 /**
10
  * Signals the local participant activate the virtual background video or not.
10
  * Signals the local participant activate the virtual background video or not.
11
  *
11
  *
12
- * @param {boolean} enabled - If true enables video background, false otherwise.
12
+ * @param {Object} options - Represents the virtual background setted options.
13
  * @returns {Promise}
13
  * @returns {Promise}
14
  */
14
  */
15
-export function toggleBackgroundEffect(enabled: boolean) {
15
+export function toggleBackgroundEffect(options: Object) {
16
     return async function(dispatch: Object => Object, getState: () => any) {
16
     return async function(dispatch: Object => Object, getState: () => any) {
17
+        await dispatch(backgroundEnabled(options.enabled));
18
+        await dispatch(setVirtualBackground(options));
17
         const state = getState();
19
         const state = getState();
18
-
19
         const { jitsiTrack } = getLocalVideoTrack(state['features/base/tracks']);
20
         const { jitsiTrack } = getLocalVideoTrack(state['features/base/tracks']);
20
         const virtualBackground = state['features/virtual-background'];
21
         const virtualBackground = state['features/virtual-background'];
21
 
22
 
22
         try {
23
         try {
23
-            if (enabled) {
24
+            if (options.enabled) {
24
                 await jitsiTrack.setEffect(await createVirtualBackgroundEffect(virtualBackground));
25
                 await jitsiTrack.setEffect(await createVirtualBackgroundEffect(virtualBackground));
25
-                dispatch(backgroundEnabled(true));
26
             } else {
26
             } else {
27
                 await jitsiTrack.setEffect(undefined);
27
                 await jitsiTrack.setEffect(undefined);
28
                 dispatch(backgroundEnabled(false));
28
                 dispatch(backgroundEnabled(false));
37
 /**
37
 /**
38
  * Sets the selected virtual background image object.
38
  * Sets the selected virtual background image object.
39
  *
39
  *
40
- * @param {Object} virtualSource - Virtual background image source.
41
- * @param {boolean} isVirtualBackground - Indicate if virtual image is activated.
40
+ * @param {Object} options - Represents the virtual background setted options.
42
  * @returns {{
41
  * @returns {{
43
  *     type: SET_VIRTUAL_BACKGROUND,
42
  *     type: SET_VIRTUAL_BACKGROUND,
44
  *     virtualSource: string,
43
  *     virtualSource: string,
45
- *     isVirtualBackground: boolean,
44
+ *     blurValue: number,
45
+ *     type: string,
46
  * }}
46
  * }}
47
  */
47
  */
48
-export function setVirtualBackground(virtualSource: string, isVirtualBackground: boolean) {
48
+export function setVirtualBackground(options: Object) {
49
     return {
49
     return {
50
         type: SET_VIRTUAL_BACKGROUND,
50
         type: SET_VIRTUAL_BACKGROUND,
51
-        virtualSource,
52
-        isVirtualBackground
51
+        virtualSource: options?.url,
52
+        blurValue: options?.blurValue,
53
+        backgroundType: options?.backgroundType
53
     };
54
     };
54
 }
55
 }
55
 
56
 
59
  * @param {boolean} backgroundEffectEnabled - Indicate if virtual background effect is activated.
60
  * @param {boolean} backgroundEffectEnabled - Indicate if virtual background effect is activated.
60
  * @returns {{
61
  * @returns {{
61
  *      type: BACKGROUND_ENABLED,
62
  *      type: BACKGROUND_ENABLED,
62
- *      backgroundEffectEnabled: boolean,
63
+ *      backgroundEffectEnabled: boolean
63
  * }}
64
  * }}
64
  */
65
  */
65
 export function backgroundEnabled(backgroundEffectEnabled: boolean) {
66
 export function backgroundEnabled(backgroundEffectEnabled: boolean) {

+ 61
- 23
react/features/virtual-background/components/VirtualBackgroundDialog.js Datei anzeigen

10
 import { Icon, IconBlurBackground, IconCancelSelection } from '../../base/icons';
10
 import { Icon, IconBlurBackground, IconCancelSelection } from '../../base/icons';
11
 import { connect } from '../../base/redux';
11
 import { connect } from '../../base/redux';
12
 import { Tooltip } from '../../base/tooltip';
12
 import { Tooltip } from '../../base/tooltip';
13
-import { toggleBackgroundEffect, setVirtualBackground } from '../actions';
13
+import { toggleBackgroundEffect } from '../actions';
14
 import { resizeImage, toDataURL } from '../functions';
14
 import { resizeImage, toDataURL } from '../functions';
15
 import logger from '../logger';
15
 import logger from '../logger';
16
 
16
 
17
-// The limit of virtual background uploads is 21. When the number
18
-// of uploads is 22 we trigger the deleteStoredImage function to delete
17
+// The limit of virtual background uploads is 24. When the number
18
+// of uploads is 25 we trigger the deleteStoredImage function to delete
19
 // the first/oldest uploaded background.
19
 // the first/oldest uploaded background.
20
-const backgroundsLimit = 22;
20
+const backgroundsLimit = 25;
21
 const images = [
21
 const images = [
22
     {
22
     {
23
         id: 1,
23
         id: 1,
67
      * Updates stored images on local storage.
67
      * Updates stored images on local storage.
68
      */
68
      */
69
     useEffect(() => {
69
     useEffect(() => {
70
-        jitsiLocalStorage.setItem('virtualBackgrounds', JSON.stringify(storedImages));
70
+        try {
71
+            jitsiLocalStorage.setItem('virtualBackgrounds', JSON.stringify(storedImages));
72
+        } catch (err) {
73
+            // Preventing localStorage QUOTA_EXCEEDED_ERR
74
+            err && deleteStoredImage(storedImages[0]);
75
+        }
71
         if (storedImages.length === backgroundsLimit) {
76
         if (storedImages.length === backgroundsLimit) {
72
             deleteStoredImage(storedImages[0]);
77
             deleteStoredImage(storedImages[0]);
73
         }
78
         }
74
     }, [ storedImages ]);
79
     }, [ storedImages ]);
75
 
80
 
76
     const [ selected, setSelected ] = useState('');
81
     const [ selected, setSelected ] = useState('');
77
-    const enableBlur = async () => {
82
+    const enableBlur = async (blurValue, selection) => {
78
         isloading(true);
83
         isloading(true);
79
-        setSelected('blur');
80
-        await dispatch(setVirtualBackground('', false));
81
-        await dispatch(toggleBackgroundEffect(true));
84
+        setSelected(selection);
85
+        await dispatch(
86
+            toggleBackgroundEffect({
87
+                backgroundType: 'blur',
88
+                enabled: true,
89
+                blurValue
90
+            })
91
+        );
82
         isloading(false);
92
         isloading(false);
83
     };
93
     };
84
 
94
 
85
     const removeBackground = async () => {
95
     const removeBackground = async () => {
86
         isloading(true);
96
         isloading(true);
87
         setSelected('none');
97
         setSelected('none');
88
-        await dispatch(setVirtualBackground('', false));
89
-        await dispatch(toggleBackgroundEffect(false));
98
+        await dispatch(
99
+            toggleBackgroundEffect({
100
+                enabled: false
101
+            })
102
+        );
90
         isloading(false);
103
         isloading(false);
91
     };
104
     };
92
 
105
 
93
     const setUploadedImageBackground = async image => {
106
     const setUploadedImageBackground = async image => {
94
         isloading(true);
107
         isloading(true);
95
         setSelected(image.id);
108
         setSelected(image.id);
96
-        await dispatch(setVirtualBackground(image.src, true));
97
-        await dispatch(toggleBackgroundEffect(true));
109
+        await dispatch(
110
+            toggleBackgroundEffect({
111
+                backgroundType: 'image',
112
+                enabled: true,
113
+                url: image.src
114
+            })
115
+        );
98
         isloading(false);
116
         isloading(false);
99
     };
117
     };
100
 
118
 
101
     const setImageBackground = async image => {
119
     const setImageBackground = async image => {
102
         isloading(true);
120
         isloading(true);
103
         setSelected(image.id);
121
         setSelected(image.id);
104
-        await dispatch(setVirtualBackground(await toDataURL(image.src), true));
105
-        await dispatch(toggleBackgroundEffect(true));
122
+        const url = await toDataURL(image.src);
123
+
124
+        await dispatch(
125
+            toggleBackgroundEffect({
126
+                backgroundType: 'image',
127
+                enabled: true,
128
+                url
129
+            })
130
+        );
106
         isloading(false);
131
         isloading(false);
107
     };
132
     };
108
 
133
 
111
 
136
 
112
         reader.readAsDataURL(imageFile[0]);
137
         reader.readAsDataURL(imageFile[0]);
113
         reader.onload = async () => {
138
         reader.onload = async () => {
114
-            const resizedImage = await resizeImage(reader.result);
139
+            const url = await resizeImage(reader.result);
115
 
140
 
116
             isloading(true);
141
             isloading(true);
117
             setStoredImages([
142
             setStoredImages([
118
                 ...storedImages,
143
                 ...storedImages,
119
                 {
144
                 {
120
                     id: uuid.v4(),
145
                     id: uuid.v4(),
121
-                    src: resizedImage
146
+                    src: url
122
                 }
147
                 }
123
             ]);
148
             ]);
124
-
125
-            await dispatch(setVirtualBackground(resizedImage, true));
126
-            await dispatch(toggleBackgroundEffect(true));
149
+            await dispatch(
150
+                toggleBackgroundEffect({
151
+                    backgroundType: 'image',
152
+                    enabled: true,
153
+                    url
154
+                })
155
+            );
127
             isloading(false);
156
             isloading(false);
128
         };
157
         };
129
         reader.onerror = () => {
158
         reader.onerror = () => {
137
             hideCancelButton = { true }
166
             hideCancelButton = { true }
138
             submitDisabled = { false }
167
             submitDisabled = { false }
139
             titleKey = { 'virtualBackground.title' }
168
             titleKey = { 'virtualBackground.title' }
140
-            width = 'small'>
169
+            width = '450px'>
141
             {loading ? (
170
             {loading ? (
142
                 <div className = 'virtual-background-loading'>
171
                 <div className = 'virtual-background-loading'>
143
                     <span className = 'loading-content-text'>{t('virtualBackground.pleaseWait')}</span>
172
                     <span className = 'loading-content-text'>{t('virtualBackground.pleaseWait')}</span>
158
                             </div>
187
                             </div>
159
                         </Tooltip>
188
                         </Tooltip>
160
                         <Tooltip
189
                         <Tooltip
161
-                            content = { t('virtualBackground.enableBlur') }
190
+                            content = { t('virtualBackground.slightBlur') }
191
+                            position = { 'top' }>
192
+                            <Icon
193
+                                className = { selected === 'slight-blur' ? 'blur-selected' : '' }
194
+                                onClick = { () => enableBlur(8, 'slight-blur') }
195
+                                size = { 50 }
196
+                                src = { IconBlurBackground } />
197
+                        </Tooltip>
198
+                        <Tooltip
199
+                            content = { t('virtualBackground.blur') }
162
                             position = { 'top' }>
200
                             position = { 'top' }>
163
                             <Icon
201
                             <Icon
164
                                 className = { selected === 'blur' ? 'blur-selected' : '' }
202
                                 className = { selected === 'blur' ? 'blur-selected' : '' }
165
-                                onClick = { () => enableBlur() }
203
+                                onClick = { () => enableBlur(25, 'blur') }
166
                                 size = { 50 }
204
                                 size = { 50 }
167
                                 src = { IconBlurBackground } />
205
                                 src = { IconBlurBackground } />
168
                         </Tooltip>
206
                         </Tooltip>

+ 3
- 2
react/features/virtual-background/reducer.js Datei anzeigen

23
  * specified action.
23
  * specified action.
24
  */
24
  */
25
 ReducerRegistry.register(STORE_NAME, (state = {}, action) => {
25
 ReducerRegistry.register(STORE_NAME, (state = {}, action) => {
26
-    const { virtualSource, isVirtualBackground, backgroundEffectEnabled } = action;
26
+    const { virtualSource, backgroundEffectEnabled, blurValue, backgroundType } = action;
27
 
27
 
28
     switch (action.type) {
28
     switch (action.type) {
29
     case SET_VIRTUAL_BACKGROUND: {
29
     case SET_VIRTUAL_BACKGROUND: {
30
         return {
30
         return {
31
             ...state,
31
             ...state,
32
             virtualSource,
32
             virtualSource,
33
-            isVirtualBackground
33
+            blurValue,
34
+            backgroundType
34
         };
35
         };
35
     }
36
     }
36
     case BACKGROUND_ENABLED: {
37
     case BACKGROUND_ENABLED: {

Laden…
Abbrechen
Speichern