Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow using images as background in virtual background #9296

Merged

Conversation

danxuliu
Copy link
Member

@danxuliu danxuliu commented Apr 12, 2023

Fixes #9268

This pull request adds makes possible to use image and video files as virtual backgrounds, instead of only blurring the actual background. The blur strength is also exposed now, so it can be customized if needed. A default blur radius/strength of 10 pixels is used (the same as before), but it can be overriden with a different radius to have stronger or lighter blur effects.

There is no support for animated images, like GIF files (only the first frame would be rendered). Use .webm files instead with type VIDEO instead of IMAGE for animated backgrounds, like a looping animation of sea waves or something like that.

Note that the local video is mirrored for the local user, so the images and videos used for the background of the local video will be mirrored as well. Therefore the images and videos should not contain characters, not only for internationalization reasons, but also because it could be confusing for the local user to see them mirrored.

Finally, internally it is possible to use video streams as a virtual background in addition to video files, but that is not exposed in LocalMediaModel. The reason is that there is no support for setting video streams in a persistent way, as the stream can not be directly stored in the localStorage. It would require storing some special value to signal that a stream needs to be fetched from somewhere (like a camera with certain ID, or from a captured desktop) to then start that stream when the call is started. This would require careful thinking, and it is probably not needed by most users, so... for now only blur, image and video virtual backgrounds are exposed.

How to use from Vue components

  • If the local participant is in a call:
    • Similar to how the virtual background is enabled or disabled in the LocalMediaControls or in the TopBarMenu
    • Call LocalMediaModel.setVirtualBackgroundBlur(blurStrength), LocalMediaModel.setVirtualBackgroundImage(imageUrl) or LocalMediaModel.setVirtualBackgroundVideo(videoUrl), depending on the virtual background to set
  • If the local participant is not in a call:
    • Similar to how the virtual background is enabled or disabled in the DeviceChecker
    • Call localStorage.setItem('virtualBackgroundType_' + {CONVERSATION_TOKEN}, {VIRTUAL_BACKGROUND_TYPE}) with the desired type, and then depending on the type call localStorage.setItem('virtualBackgroundBlurStrength_' + {CONVERSATION_TOKEN}, {BLUR_STRENGTH}) (for blur type) or localStorage.setItem('virtualBackgroundUrl_' + {CONVERSATION_TOKEN}, {IMAGE_OR_VIDEO_URL}) (for image or video types)
    • It would be recommended, although not strictly needed, to remove the parameters of the other types calling localStorage.removeItem('virtualBackgroundUrl_' + {CONVERSATION_TOKEN}) (for blur type) or localStorage.removeItem('virtualBackgroundBlurStrength_' + {CONVERSATION_TOKEN})` (for image or video types).
    • Be careful not to set a null value for an item, as it will be stored and returned as 'null', rather than as an empty string.

Note that the VirtualBackground node used in the device checker is totally independent from the one used during calls. Therefore, in order to see the virtual background changes in the device checker that node needs to be modified too similar to how it is done in LocalMediaModel:

  • Blur:
virtualBackground.setVirtualBackground({
    backgroundType: VIRTUAL_BACKGROUND.BACKGROUND_TYPE.BLUR,
    blurValue: VIRTUAL_BACKGROUND.BLUR_STRENGTH.DEFAULT, // or any other positive integer, depending on the desired strength
})
  • Image:
virtualBackground.setVirtualBackground({
    backgroundType: VIRTUAL_BACKGROUND.BACKGROUND_TYPE.IMAGE,
    virtualSource: {THE_URL_TO_THE_IMAGE},
})
  • Video:
virtualBackground.setVirtualBackground({
    backgroundType: VIRTUAL_BACKGROUND.BACKGROUND_TYPE.VIDEO,
    virtualSource: {THE_URL_TO_THE_VIDEO},
})

How to test

  • Start a call with video
  • Enable the virtual background
  • Open a browser console
  • Execute the following to set an image background (dirty hack to access LocalMediaModel, but it is not exposed in OCA.Talk):
    document.querySelector('.local-media-controls').__vue__.model.setVirtualBackgroundImage('https://{YOUR-NEXTCLOUD-DOMAIN}/apps/theming/img/background/kamil-porembinski-clouds.jpg')
  • Leave the call
  • Reload the page
  • Join the call
  • The image background will still be used. To change it again to the blur background execute:
    document.querySelector('.local-media-controls').__vue__.model.setVirtualBackgroundBlur()

Even if the type was wrong the blurred background worked as expected, as
the blurred background is used by default when no background type is
specified.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
If no virtual background is needed the virtual background node should be
disabled, which will stop the effect.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The code might be needed in the original Jitsi project, but not in Talk.
It mirrored the video captured from the camera (and only the video
captured from the camera, the background was not touched), but the local
video is shown mirrored after all the composition, so the local user
would see an unmirrored camera video (due to being double-mirrored) on
top of a mirrored shared screen background, and other participants would
received a mirrored camera video on top of a normal shared screen
background.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
There is nothing specific to a desktop share in that type of virtual
background, so it was renamed to the more generic "video stream".

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This makes the option more consistent with image virtual backgrounds.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
"virtualBackground" is a mandatory object (and the rest of the code
assumes that it was given) so there is no need to guard against it being
undefined.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Note that only the background type can be changed while the virtual
background is running. Other options, like the width and height, are
still inmutable after the effect object is created.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
When the virtual background effect is not running there is no need to
play the video that the background is got from. Due to this now it is
paused and started again as needed.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Animated images, like GIFs, can not be used for animated virtual
backgrounds, as only the first frame of the image is taken into account
when drawing an HTMLImageElement to a canvas. To overcome this now
videos can be used too as virtual backgrounds by providing the URL of
the video file, in the same way as with images.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
@danxuliu danxuliu force-pushed the allow-using-images-as-background-in-virtual-background branch from 0c991fc to 817222b Compare April 12, 2023 04:16
@nickvergessen
Copy link
Member

Looking at #9251 (comment)
Question: Is it easily possible to apply the filters on the device checker easily or is more effort/restructuring needed there as it's not using call components, views, webrtc or signaling there?

The type and parameters will be loaded (in a following commit) from the
local storage. However, it will not be possible to load video streams,
so they are not exposed in LocalMediaModel either.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Similarly to other media settings, like whether audio, video and
virtual background are enabled or not, now the virtual background type
is loaded from the local storage when a call is joined.

Note that video streams are not available, though; blur, image and video
background parameters can be stored in the local storage and reused
between calls, even if Talk was closed and opened again. However, a
video stream is a live object that can not be directly persisted; a key
to trigger capturing a stream again from certain source could be used...
but for now there is no support for persisted video streams.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
@danxuliu danxuliu force-pushed the allow-using-images-as-background-in-virtual-background branch from 817222b to e0876ff Compare April 12, 2023 13:22
@danxuliu
Copy link
Member Author

Looking at #9251 (comment) Question: Is it easily possible to apply the filters on the device checker easily or is more effort/restructuring needed there as it's not using call components, views, webrtc or signaling there?

I have added an explanation in the pull request description. The device checker is using a VirtualBackground object, so it should be just a matter of calling virtualBackground.setVirtualBackground({ backgroundType: ...}) with the appropriate values.

@danxuliu danxuliu marked this pull request as ready for review April 17, 2023 12:47
Copy link
Member

@nickvergessen nickvergessen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good and testing works (when executed in console windows of the correct tab 🤦 )

@nickvergessen nickvergessen merged commit 7262eab into master Apr 17, 2023
@nickvergessen nickvergessen deleted the allow-using-images-as-background-in-virtual-background branch April 17, 2023 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

WebRTC "Background image (similar to background blur) in calls"
2 participants