fix(virtual-background): Fix mirror behavior for remote participants.
This commit is contained in:
parent
e1fef8d848
commit
d72b27d46d
|
@ -88,21 +88,28 @@ export default class JitsiStreamBackgroundEffect {
|
||||||
|
|
||||||
const track = this._stream.getVideoTracks()[0];
|
const track = this._stream.getVideoTracks()[0];
|
||||||
const { height, width } = track.getSettings() ?? track.getConstraints();
|
const { height, width } = track.getSettings() ?? track.getConstraints();
|
||||||
|
const { backgroundType } = this._options.virtualBackground;
|
||||||
|
|
||||||
this._outputCanvasElement.height = height;
|
this._outputCanvasElement.height = height;
|
||||||
this._outputCanvasElement.width = width;
|
this._outputCanvasElement.width = width;
|
||||||
this._outputCanvasCtx.globalCompositeOperation = 'copy';
|
this._outputCanvasCtx.globalCompositeOperation = 'copy';
|
||||||
|
|
||||||
// Draw segmentation mask.
|
// Draw segmentation mask.
|
||||||
//
|
|
||||||
|
|
||||||
// Smooth out the edges.
|
// Smooth out the edges.
|
||||||
if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE) {
|
if (backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE) {
|
||||||
this._outputCanvasCtx.filter = 'blur(4px)';
|
this._outputCanvasCtx.filter = 'blur(4px)';
|
||||||
} else {
|
} else {
|
||||||
this._outputCanvasCtx.filter = 'blur(8px)';
|
this._outputCanvasCtx.filter = 'blur(8px)';
|
||||||
}
|
}
|
||||||
|
if (backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
|
||||||
|
// Save current context before applying transformations.
|
||||||
|
this._outputCanvasCtx.save();
|
||||||
|
|
||||||
|
// Flip the canvas and prevent mirror behaviour.
|
||||||
|
this._outputCanvasCtx.scale(-1, 1);
|
||||||
|
this._outputCanvasCtx.translate(-this._outputCanvasElement.width, 0);
|
||||||
|
}
|
||||||
this._outputCanvasCtx.drawImage(
|
this._outputCanvasCtx.drawImage(
|
||||||
this._segmentationMaskCanvas,
|
this._segmentationMaskCanvas,
|
||||||
0,
|
0,
|
||||||
|
@ -114,45 +121,39 @@ export default class JitsiStreamBackgroundEffect {
|
||||||
this._inputVideoElement.width,
|
this._inputVideoElement.width,
|
||||||
this._inputVideoElement.height
|
this._inputVideoElement.height
|
||||||
);
|
);
|
||||||
|
if (backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
|
||||||
|
this._outputCanvasCtx.restore();
|
||||||
|
}
|
||||||
this._outputCanvasCtx.globalCompositeOperation = 'source-in';
|
this._outputCanvasCtx.globalCompositeOperation = 'source-in';
|
||||||
this._outputCanvasCtx.filter = 'none';
|
this._outputCanvasCtx.filter = 'none';
|
||||||
|
|
||||||
// Draw the foreground video.
|
// Draw the foreground video.
|
||||||
//
|
if (backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
|
||||||
|
// Save current context before applying transformations.
|
||||||
this._outputCanvasCtx.drawImage(this._inputVideoElement, 0, 0);
|
|
||||||
|
|
||||||
// Draw the background.
|
|
||||||
//
|
|
||||||
|
|
||||||
this._outputCanvasCtx.globalCompositeOperation = 'destination-over';
|
|
||||||
if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE) {
|
|
||||||
this._outputCanvasCtx.drawImage(
|
|
||||||
this._virtualImage,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this._inputVideoElement.width,
|
|
||||||
this._inputVideoElement.height
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
|
|
||||||
|
|
||||||
// save current context before applying transformations
|
|
||||||
this._outputCanvasCtx.save();
|
this._outputCanvasCtx.save();
|
||||||
|
|
||||||
// flip the canvas and prevent mirror behaviour
|
// Flip the canvas and prevent mirror behaviour.
|
||||||
this._outputCanvasCtx.scale(-1, 1);
|
this._outputCanvasCtx.scale(-1, 1);
|
||||||
this._outputCanvasCtx.translate(-this._outputCanvasElement.width, 0);
|
this._outputCanvasCtx.translate(-this._outputCanvasElement.width, 0);
|
||||||
|
}
|
||||||
|
this._outputCanvasCtx.drawImage(this._inputVideoElement, 0, 0);
|
||||||
|
if (backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
|
||||||
|
this._outputCanvasCtx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the background.
|
||||||
|
|
||||||
|
this._outputCanvasCtx.globalCompositeOperation = 'destination-over';
|
||||||
|
if (backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE
|
||||||
|
|| backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
|
||||||
this._outputCanvasCtx.drawImage(
|
this._outputCanvasCtx.drawImage(
|
||||||
this._virtualVideo,
|
backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE
|
||||||
|
? this._virtualImage : this._virtualVideo,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
this._outputCanvasElement.width,
|
this._outputCanvasElement.width,
|
||||||
this._outputCanvasElement.height
|
this._outputCanvasElement.height
|
||||||
);
|
);
|
||||||
|
|
||||||
// restore the canvas
|
|
||||||
this._outputCanvasCtx.restore();
|
|
||||||
} else {
|
} else {
|
||||||
this._outputCanvasCtx.filter = `blur(${this._options.virtualBackground.blurValue}px)`;
|
this._outputCanvasCtx.filter = `blur(${this._options.virtualBackground.blurValue}px)`;
|
||||||
this._outputCanvasCtx.drawImage(this._inputVideoElement, 0, 0);
|
this._outputCanvasCtx.drawImage(this._inputVideoElement, 0, 0);
|
||||||
|
|
|
@ -188,12 +188,7 @@ function VirtualBackground({
|
||||||
if (storedImages.length === backgroundsLimit) {
|
if (storedImages.length === backgroundsLimit) {
|
||||||
setStoredImages(storedImages.slice(1));
|
setStoredImages(storedImages.slice(1));
|
||||||
}
|
}
|
||||||
if (!_localFlipX) {
|
}, [ storedImages ]);
|
||||||
dispatch(updateSettings({
|
|
||||||
localFlipX: !_localFlipX
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}, [ storedImages, _localFlipX ]);
|
|
||||||
|
|
||||||
|
|
||||||
const enableBlur = useCallback(async () => {
|
const enableBlur = useCallback(async () => {
|
||||||
|
@ -390,8 +385,13 @@ function VirtualBackground({
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await dispatch(toggleBackgroundEffect(options, _jitsiTrack));
|
await dispatch(toggleBackgroundEffect(options, _jitsiTrack));
|
||||||
await setLoading(false);
|
await setLoading(false);
|
||||||
|
if (_localFlipX && options.backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
|
||||||
|
dispatch(updateSettings({
|
||||||
|
localFlipX: !_localFlipX
|
||||||
|
}));
|
||||||
|
}
|
||||||
dispatch(hideDialog());
|
dispatch(hideDialog());
|
||||||
}, [ dispatch, options ]);
|
}, [ dispatch, options, _localFlipX ]);
|
||||||
|
|
||||||
// Prevent the selection of a new virtual background if it has not been applied by default
|
// Prevent the selection of a new virtual background if it has not been applied by default
|
||||||
const cancelVirtualBackground = useCallback(async () => {
|
const cancelVirtualBackground = useCallback(async () => {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { toggleBackgroundEffect } from '../actions';
|
||||||
import { VIRTUAL_BACKGROUND_TYPE } from '../constants';
|
import { VIRTUAL_BACKGROUND_TYPE } from '../constants';
|
||||||
import { localTrackStopped } from '../functions';
|
import { localTrackStopped } from '../functions';
|
||||||
|
|
||||||
const videoClassName = 'video-preview-video flipVideoX';
|
const videoClassName = 'video-preview-video';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code PureComponent} props of {@link VirtualBackgroundPreview}.
|
* The type of the React {@code PureComponent} props of {@link VirtualBackgroundPreview}.
|
||||||
|
|
Loading…
Reference in New Issue