From 901cf32360653714eea17e288901fa80eb472d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 18 Jan 2021 19:59:16 +0100 Subject: Show the average color of the user avatar as video background in Safari MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Safari suffers the same performance hit as Chromium when using the blur filter. However, Safari does not support using the blur filter on canvases, so the same workaround used for Chromium does not work in Safari. To solve this, and to still use a background with colors related to the avatar, the average of the colors in the avatar is used. Signed-off-by: Daniel Calviño Sánchez --- package-lock.json | 5 +++ package.json | 1 + src/components/CallView/shared/VideoBackground.vue | 42 ++++++++++++++++++++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3e19dea0c..bc0dd7851 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7530,6 +7530,11 @@ "simple-swizzle": "^0.2.2" } }, + "color.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/color.js/-/color.js-1.2.0.tgz", + "integrity": "sha512-0ajlNgWWOR7EK9N6l2h0YKsZPzMCLQG5bheCoTGpGfhkR8tB5eQNItdua1oFHDTeq9JKgSzQJqo+Gp3V/xW+Lw==" + }, "colorette": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", diff --git a/package.json b/package.json index a5e42daad..b7cf79f7d 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@nextcloud/vue": "^3.4.0", "@nextcloud/vue-dashboard": "^1.0.1", "attachmediastream": "^2.1.0", + "color.js": "^1.2.0", "crypto-js": "^4.0.0", "debounce": "^1.2.0", "emoji-regex": "^9.2.0", diff --git a/src/components/CallView/shared/VideoBackground.vue b/src/components/CallView/shared/VideoBackground.vue index 8ff2878ba..990e656cb 100644 --- a/src/components/CallView/shared/VideoBackground.vue +++ b/src/components/CallView/shared/VideoBackground.vue @@ -30,7 +30,7 @@ @notify="setBlur" /> diff --git a/src/utils/imageBlurrer.js b/src/utils/imageBlurrer.js deleted file mode 100644 index 2a29e27d1..000000000 --- a/src/utils/imageBlurrer.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * - * @copyright Copyright (c) 2020, Daniel Calviño Sánchez (danxuliu@gmail.com) - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -import { generateFilePath } from '@nextcloud/router' - -let worker - -const pendingResults = {} -let pendingResultsNextId = 0 - -function loadWorker() { - try { - worker = new Worker(generateFilePath('spreed', '', 'js/image-blurrer-worker.js')) - worker.onmessage = function(message) { - const pendingResult = pendingResults[message.data.id] - if (!pendingResult) { - console.debug('No pending result for blurring image with id ' + message.data.id) - - return - } - - pendingResult(message.data.blurredImageAsDataUrl) - - delete pendingResults[message.data.id] - } - } catch (exception) { - worker = null - console.error('Image blurrer worker could not be loaded', exception) - } -} - -function blurSync(image, width, height, blurRadius) { - return new Promise((resolve, reject) => { - const canvas = document.createElement('canvas') - canvas.width = width - canvas.height = height - - const context = canvas.getContext('2d') - context.filter = `blur(${blurRadius}px)` - context.drawImage(image, 0, 0, canvas.width, canvas.height) - - resolve(canvas.toDataURL()) - }) -} - -export default function blur(image, width, height, blurRadius) { - if (typeof OffscreenCanvas === 'undefined') { - return blurSync(image, width, height, blurRadius) - } - - if (worker === undefined) { - loadWorker() - } - - if (!worker) { - return blurSync(image, width, height, blurRadius) - } - - const id = pendingResultsNextId - - pendingResultsNextId++ - - return new Promise((resolve, reject) => { - pendingResults[id] = resolve - - worker.postMessage({ - id: id, - image: image, - width: width, - height: height, - blurRadius: blurRadius, - }) - }) -} diff --git a/src/utils/imageBlurrerWorker.js b/src/utils/imageBlurrerWorker.js deleted file mode 100644 index 756da1ff0..000000000 --- a/src/utils/imageBlurrerWorker.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * - * @copyright Copyright (c) 2020, Daniel Calviño Sánchez (danxuliu@gmail.com) - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -const fileReaderSync = new global.FileReaderSync() - -onmessage = function(message) { - const offscreenCanvas = new OffscreenCanvas(message.data.width, message.data.height) - - const context = offscreenCanvas.getContext('2d') - context.filter = `blur(${message.data.blurRadius}px)` - context.drawImage(message.data.image, 0, 0, offscreenCanvas.width, offscreenCanvas.height) - - offscreenCanvas.convertToBlob().then(blob => { - postMessage({ - id: message.data.id, - blurredImageAsDataUrl: fileReaderSync.readAsDataURL(blob), - }) - }) -} diff --git a/webpack.common.js b/webpack.common.js index fd5e11bbd..959514bb7 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -7,11 +7,6 @@ module.exports = { entry: { 'admin-settings': path.join(__dirname, 'src', 'mainAdminSettings.js'), 'collections': path.join(__dirname, 'src', 'collections.js'), - // There is a "worker-loader" plugin for Webpack, but I was not able to - // get it to work ("publicPath" uses "output.publicPath" rather than the - // one set in the plugin - // https://github.com/webpack-contrib/worker-loader/issues/281). - 'image-blurrer-worker': path.join(__dirname, 'src', 'utils/imageBlurrerWorker.js'), 'talk': path.join(__dirname, 'src', 'main.js'), 'talk-files-sidebar': [ path.join(__dirname, 'src', 'mainFilesSidebar.js'), -- cgit v1.2.3 From 9eb01887df8c72e88f1b2075f913ef3e126a04a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 25 Jan 2021 09:42:34 +0100 Subject: Replace blur with average color in video background in all cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For consistency between browsers now the average color is shown in all cases, even if CSS blur filters work fine in Firefox. Signed-off-by: Daniel Calviño Sánchez --- src/components/CallView/shared/VideoBackground.vue | 51 ++++------------------ 1 file changed, 8 insertions(+), 43 deletions(-) diff --git a/src/components/CallView/shared/VideoBackground.vue b/src/components/CallView/shared/VideoBackground.vue index fc874441e..3359d436f 100644 --- a/src/components/CallView/shared/VideoBackground.vue +++ b/src/components/CallView/shared/VideoBackground.vue @@ -29,14 +29,7 @@ class="observer" @notify="setBlur" /> - -
@@ -49,7 +42,6 @@ import usernameToColor from '@nextcloud/vue/dist/Functions/usernameToColor' import { generateUrl } from '@nextcloud/router' import { ResizeObserver } from 'vue-resize' import { getBuilder } from '@nextcloud/browser-storage' -import browserCheck from '../../../mixins/browserCheck' const browserStorage = getBuilder('nextcloud').persist().build() @@ -72,10 +64,6 @@ export default { ResizeObserver, }, - mixins: [ - browserCheck, - ], - props: { displayName: { type: String, @@ -94,21 +82,20 @@ export default { data() { return { hasPicture: false, - useAverageColor: false, blur: 0, } }, computed: { backgroundImageAverageColor() { - if (!this.backgroundImageUrlToAverage) { + if (!this.backgroundImageUrl) { return '' } - return this.$store.getters.getCachedBackgroundImageAverageColor(this.backgroundImageUrlToAverage) + return this.$store.getters.getCachedBackgroundImageAverageColor(this.backgroundImageUrl) }, backgroundColor() { - if (this.hasPicture && this.useAverageColor) { + if (this.hasPicture) { return this.backgroundImageAverageColor } @@ -131,31 +118,13 @@ export default { backgroundBlur() { return this.gridBlur ? this.gridBlur : this.blur }, - backgroundStyle() { - if (this.useAverageColor) { - return {} - } - - return { - filter: `blur(${this.backgroundBlur}px)`, - } - }, - // Special computed property to combine the properties that should be - // watched to set (or not) the background image average color. - backgroundImageUrlToAverage() { - if (!this.useAverageColor) { - return null - } - - return this.backgroundImageUrl - }, }, watch: { - backgroundImageUrlToAverage: { + backgroundImageUrl: { immediate: true, handler() { - if (!this.backgroundImageUrlToAverage) { + if (!this.backgroundImageUrl) { return } @@ -164,9 +133,9 @@ export default { return } - average(this.backgroundImageUrlToAverage, { format: 'hex' }).then(color => { + average(this.backgroundImageUrl, { format: 'hex' }).then(color => { this.$store.dispatch('setCachedBackgroundImageAverageColor', { - videoBackgroundId: this.backgroundImageUrlToAverage, + videoBackgroundId: this.backgroundImageUrl, backgroundImageAverageColor: color, }) }) @@ -175,10 +144,6 @@ export default { }, async beforeMount() { - if (!this.isFirefox) { - this.useAverageColor = true - } - if (!this.user) { return } -- cgit v1.2.3 From 69b9fe6953d3b69a0cff110d616e427a8ef9aa29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 25 Jan 2021 09:44:25 +0100 Subject: Remove no longer needed blur related code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- src/components/CallView/Grid/Grid.vue | 6 ---- src/components/CallView/shared/Video.vue | 11 ++----- src/components/CallView/shared/VideoBackground.vue | 36 +--------------------- src/store/callViewStore.js | 8 ----- 4 files changed, 3 insertions(+), 58 deletions(-) diff --git a/src/components/CallView/Grid/Grid.vue b/src/components/CallView/Grid/Grid.vue index c56262518..c048850ed 100644 --- a/src/components/CallView/Grid/Grid.vue +++ b/src/components/CallView/Grid/Grid.vue @@ -72,7 +72,6 @@ :is-selected="isSelected(callParticipantModel)" :fit-video="false" :video-container-aspect-ratio="videoContainerAspectRatio" - :video-background-blur="videoBackgroundBlur" :shared-data="sharedDatas[callParticipantModel.attributes.peerId]" @click-video="handleClickVideo($event, callParticipantModel.attributes.peerId)" /> @@ -439,11 +438,6 @@ export default { } }, - // Blur radius for each background in the grid - videoBackgroundBlur() { - return this.$store.getters.getBlurRadius(this.videoWidth, this.videoHeight) - }, - stripeOpen() { return this.$store.getters.isStripeOpen }, diff --git a/src/components/CallView/shared/Video.vue b/src/components/CallView/shared/Video.vue index 2d5c9f3fb..acaec6009 100644 --- a/src/components/CallView/shared/Video.vue +++ b/src/components/CallView/shared/Video.vue @@ -50,8 +50,7 @@