mirror of
https://github.com/nextcloud/spreed.git
synced 2025-12-18 05:20:50 +01:00
For the inference part, the old Selfie Segmentation using tflite has been replaced by the modern MediaPipe vision tasks API, which runs on GPU if available (otherwise gracefully falls back to wasm/CPU). For compositing (applying the mask), a new custom WebGL2 compositor performs all work directly on GPU (completely avoiding CPU-GPU back & forth); if WebGL2 is not available, the old canvas compositing is used. This change introduces significant gains in CPU usage during video calls that use blurring/backgrounds, since the CPU is now mostly idle and all work is done on GPU. As a bonus, virtual backgrounds are now also available on Safari (WebGL compositor only). The old JitsiStreamBackgroundEffect class has been replaced by the new VideoStreamBackgroundEffect. Signed-off-by: Dimitris Kazakos <nemphys@gmail.com>
221 lines
5.6 KiB
JavaScript
221 lines
5.6 KiB
JavaScript
/*
|
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
const browserslistConfig = require('@nextcloud/browserslist-config')
|
|
const { defineConfig } = require('@rspack/cli')
|
|
const { CopyRspackPlugin } = require('@rspack/core')
|
|
const { CssExtractRspackPlugin, LightningCssMinimizerRspackPlugin, DefinePlugin, ProgressPlugin, SwcJsMinimizerRspackPlugin } = require('@rspack/core')
|
|
const NodePolyfillPlugin = require('@rspack/plugin-node-polyfill')
|
|
const path = require('node:path')
|
|
const { VueLoaderPlugin } = require('vue-loader')
|
|
|
|
module.exports = defineConfig((env) => {
|
|
const appName = process.env.npm_package_name
|
|
const appVersion = process.env.npm_package_version
|
|
|
|
const mode = (env.development && 'development') || (env.production && 'production') || process.env.NODE_ENV || 'production'
|
|
const isDev = mode === 'development'
|
|
process.env.NODE_ENV = mode
|
|
|
|
console.info('Building', appName, appVersion, '\n')
|
|
|
|
return {
|
|
target: 'web',
|
|
mode,
|
|
devtool: isDev ? 'cheap-source-map' : 'source-map',
|
|
|
|
entry: {
|
|
'admin-settings': path.join(__dirname, 'src', 'mainAdminSettings.js'),
|
|
collections: path.join(__dirname, 'src', 'collections.js'),
|
|
main: path.join(__dirname, 'src', 'main.js'),
|
|
recording: path.join(__dirname, 'src', 'mainRecording.js'),
|
|
'files-sidebar': [
|
|
path.join(__dirname, 'src', 'mainFilesSidebar.js'),
|
|
path.join(__dirname, 'src', 'mainFilesSidebarLoader.js'),
|
|
],
|
|
'public-share-auth-sidebar': path.join(__dirname, 'src', 'mainPublicShareAuthSidebar.js'),
|
|
'public-share-sidebar': path.join(__dirname, 'src', 'mainPublicShareSidebar.js'),
|
|
flow: path.join(__dirname, 'src', 'flow.js'),
|
|
deck: path.join(__dirname, 'src', 'deck.js'),
|
|
maps: path.join(__dirname, 'src', 'maps.js'),
|
|
search: path.join(__dirname, 'src', 'search.js'),
|
|
icons: path.join(__dirname, 'src', 'icons.css'),
|
|
},
|
|
|
|
output: {
|
|
path: path.resolve('./js'),
|
|
filename: `${appName}-[name].js?v=[contenthash]`,
|
|
chunkFilename: `${appName}-[name].js?v=[contenthash]`,
|
|
// Set publicPath via __webpack_public_path__
|
|
publicPath: 'auto',
|
|
// We are working with .wasm and .tflite files as resources on a public path: it must be with the original name in the output folder's root
|
|
assetModuleFilename: '[name][ext]?v=[contenthash]',
|
|
// We are working with .wasm files as resources on a public path: disabling default wasm loading as source
|
|
wasmLoading: false,
|
|
enabledWasmLoadingTypes: [],
|
|
clean: true,
|
|
devtoolNamespace: appName,
|
|
// Make sure sourcemaps have a proper path and do not leak local paths
|
|
// Source: @nextcloud/webpack-vue-config
|
|
devtoolModuleFilenameTemplate(info) {
|
|
const rootDir = process.cwd()
|
|
const rel = path.relative(rootDir, info.absoluteResourcePath)
|
|
return `webpack:///${appName}/${rel}`
|
|
},
|
|
},
|
|
|
|
devServer: {
|
|
hot: true,
|
|
host: '127.0.0.1',
|
|
port: 3000,
|
|
client: {
|
|
overlay: false,
|
|
},
|
|
devMiddleware: {
|
|
writeToDisk: true,
|
|
},
|
|
headers: {
|
|
'Access-Control-Allow-Origin': '*',
|
|
},
|
|
},
|
|
|
|
optimization: {
|
|
chunkIds: 'named',
|
|
splitChunks: {
|
|
automaticNameDelimiter: '-',
|
|
cacheGroups: {
|
|
defaultVendors: {
|
|
reuseExistingChunk: true,
|
|
},
|
|
},
|
|
},
|
|
minimize: !isDev,
|
|
minimizer: [
|
|
new SwcJsMinimizerRspackPlugin({
|
|
minimizerOptions: {
|
|
targets: browserslistConfig,
|
|
},
|
|
}),
|
|
new LightningCssMinimizerRspackPlugin({
|
|
minimizerOptions: {
|
|
targets: browserslistConfig,
|
|
},
|
|
}),
|
|
],
|
|
},
|
|
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.vue$/,
|
|
loader: 'vue-loader',
|
|
options: {
|
|
experimentalInlineMatchResource: true,
|
|
},
|
|
},
|
|
{
|
|
test: /\.css$/,
|
|
use: [
|
|
{
|
|
loader: CssExtractRspackPlugin.loader,
|
|
},
|
|
'css-loader',
|
|
],
|
|
},
|
|
{
|
|
test: /\.scss$/,
|
|
use: [
|
|
{
|
|
loader: CssExtractRspackPlugin.loader,
|
|
},
|
|
'css-loader',
|
|
'sass-loader',
|
|
],
|
|
},
|
|
{
|
|
test: /\.ts$/,
|
|
exclude: [/node_modules/],
|
|
loader: 'builtin:swc-loader',
|
|
options: {
|
|
jsc: {
|
|
parser: {
|
|
syntax: 'typescript',
|
|
},
|
|
},
|
|
env: {
|
|
targets: browserslistConfig,
|
|
},
|
|
},
|
|
type: 'javascript/auto',
|
|
},
|
|
{
|
|
test: /\.(png|jpe?g|gif|svg|webp)$/i,
|
|
type: 'asset',
|
|
},
|
|
{
|
|
test: /\.(woff2?|eot|ttf|otf)$/i,
|
|
type: 'asset/resource',
|
|
},
|
|
{
|
|
test: /\.wasm$/i,
|
|
type: 'asset/resource',
|
|
},
|
|
{
|
|
test: /\.tflite$/i,
|
|
type: 'asset/resource',
|
|
},
|
|
{
|
|
resourceQuery: /raw/,
|
|
type: 'asset/source',
|
|
},
|
|
],
|
|
},
|
|
|
|
plugins: [
|
|
new ProgressPlugin(),
|
|
|
|
new VueLoaderPlugin(),
|
|
|
|
new NodePolyfillPlugin(),
|
|
|
|
new DefinePlugin({
|
|
IS_DESKTOP: false,
|
|
__IS_DESKTOP__: false,
|
|
appName: JSON.stringify(appName),
|
|
appVersion: JSON.stringify(appVersion),
|
|
}),
|
|
|
|
new CssExtractRspackPlugin({
|
|
filename: '../css/talk-[name].css',
|
|
chunkFilename: '../css/chunks/[id].chunk.css',
|
|
ignoreOrder: true,
|
|
}),
|
|
|
|
// Bundle wasm and tflite files required for virtual background feature
|
|
new CopyRspackPlugin({
|
|
patterns: [
|
|
{
|
|
from: path.resolve(__dirname, 'node_modules', '@mediapipe/tasks-vision', 'wasm'),
|
|
to: path.resolve(__dirname, 'js'),
|
|
},
|
|
{
|
|
from: path.resolve(__dirname, 'src', 'utils', 'media', 'effects', 'virtual-background', 'vendor', 'models', 'selfie_segmenter.tflite'),
|
|
to: path.resolve(__dirname, 'js'),
|
|
},
|
|
],
|
|
}),
|
|
],
|
|
|
|
resolve: {
|
|
extensions: ['*', '.ts', '.js', '.vue'],
|
|
symlinks: false,
|
|
fallback: {
|
|
fs: false,
|
|
},
|
|
},
|
|
|
|
cache: true,
|
|
}
|
|
})
|