diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.html b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.html index 8ac505a14..7010b3368 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.html +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.html @@ -13,6 +13,13 @@ } + @if (!isVirtualBackgroundSupported()) { +
+

{{ 'PANEL.BACKGROUND.NOT_SUPPORTED' | translate }}

+

{{ 'PANEL.BACKGROUND.NOT_SUPPORTED_DESCRIPTION' | translate }}

+
+ } +

{{ 'PANEL.BACKGROUND.BLURRED_SECTION' | translate }}

@@ -24,6 +31,7 @@ [class.active-effect-btn]="backgroundSelectedId === effect.id" (click)="applyBackground(effect)" [attr.id]="effect.id + '-btn'" + [disabled]="!isVirtualBackgroundSupported()" [matTooltip]=" effect.type === effectType.NONE ? ('PANEL.BACKGROUND.NO_EFFECTS' | translate) @@ -44,7 +52,8 @@ class="effect-button" [id]="'effect-' + effect.id" [class.active-effect-btn]="backgroundSelectedId === effect.id" - (click)="applyBackground(effect)" + [class.disabled]="!isVirtualBackgroundSupported()" + (click)="isVirtualBackgroundSupported() && applyBackground(effect)" >
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.scss b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.scss index 33520888f..fa8e96822 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.scss +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.scss @@ -12,6 +12,26 @@ margin: 10px 0; font-weight: 300; } + +.not-supported-message { + padding: 15px; + margin: 10px; + background-color: var(--ov-warn-color, #ff9800); + border-radius: var(--ov-surface-radius); + color: var(--ov-text-surface-color); + + .warning-title { + font-weight: 500; + margin: 0 0 8px 0; + } + + .warning-description { + font-size: 0.9em; + margin: 0; + opacity: 0.9; + } +} + .effects-container { display: block !important; overflow-y: auto; @@ -33,6 +53,11 @@ cursor: pointer; } +.effect-button.disabled { + opacity: 0.5; + cursor: not-allowed; +} + .active-effect-btn { border: 2px solid var(--ov-accent-action-color); } diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.ts index 1861f8b10..88f63e328 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/background-effects-panel/background-effects-panel.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, EventEmitter, Input, OnInit, Output, Signal } from '@angular/core'; import { Subscription } from 'rxjs'; import { BackgroundEffect, EffectType } from '../../../models/background-effect.model'; import { PanelType } from '../../../models/panel.model'; @@ -23,7 +23,7 @@ export class BackgroundEffectsPanelComponent implements OnInit { effectType = EffectType; backgroundImages: BackgroundEffect[] = []; noEffectAndBlurredBackground: BackgroundEffect[] = []; - private backgrounds: BackgroundEffect[]; + private backgrounds: BackgroundEffect[] = []; private backgroundSubs: Subscription; /** @@ -38,6 +38,14 @@ export class BackgroundEffectsPanelComponent implements OnInit { private cd: ChangeDetectorRef ) {} + /** + * Computed signal that reactively tracks if virtual background is supported. + * Updates automatically when browser support changes. + */ + readonly isVirtualBackgroundSupported: Signal = computed(() => + this.backgroundService.isVirtualBackgroundSupported() + ); + ngOnInit(): void { this.subscribeToBackgroundSelected(); this.backgrounds = this.backgroundService.getBackgrounds(); diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/cn.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/cn.json index e283cba05..6706c5052 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/cn.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/cn.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "没有效果和模糊的背景", "NO_EFFECTS": "没有背景效果", "BLURRED_EFFECT": "模糊的背景", - "IMAGES_SECTION": "背景图像" + "IMAGES_SECTION": "背景图像", + "NOT_SUPPORTED": "此浏览器不支持虚拟背景", + "NOT_SUPPORTED_DESCRIPTION": "您的浏览器不支持背景效果。此功能需要 GPU 加速,可能已被禁用或不可用。" }, "RECORDING": { "TITLE": "录音", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/de.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/de.json index 375ef80be..04243121a 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/de.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/de.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "Keine Effekte und unscharfer Hintergrund", "NO_EFFECTS": "Kein Hintergrundeffekt", "BLURRED_EFFECT": "Unscharfer Hintergrund", - "IMAGES_SECTION": "Hintergrundbilder" + "IMAGES_SECTION": "Hintergrundbilder", + "NOT_SUPPORTED": "Virtuelle Hintergründe werden in diesem Browser nicht unterstützt", + "NOT_SUPPORTED_DESCRIPTION": "Ihr Browser unterstützt keine Hintergrundeffekte. Diese Funktion erfordert GPU-Beschleunigung, die möglicherweise deaktiviert oder nicht verfügbar ist." }, "RECORDING": { "TITLE": "Aufnahme", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/en.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/en.json index 3edc8ee30..84b781ff5 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/en.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/en.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "No effects and blurred background", "NO_EFFECTS": "No background effect", "BLURRED_EFFECT": "Blurred background", - "IMAGES_SECTION": "Background images" + "IMAGES_SECTION": "Background images", + "NOT_SUPPORTED": "Virtual backgrounds are not supported in this browser", + "NOT_SUPPORTED_DESCRIPTION": "Your browser does not support background effects. This feature requires GPU acceleration which may be disabled or unavailable." }, "RECORDING": { "TITLE": "Recording", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/es.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/es.json index ff39fc671..a0ec59544 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/es.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/es.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "Sin efectos y fondo desenfocado", "NO_EFFECTS": "Sin efecto", "BLURRED_EFFECT": "Fondo desenfocado", - "IMAGES_SECTION": "Imágenes de fondo" + "IMAGES_SECTION": "Imágenes de fondo", + "NOT_SUPPORTED": "Los efectos de fondo virtuales no son compatibles con este navegador", + "NOT_SUPPORTED_DESCRIPTION": "Tu navegador no admite efectos de fondo. Esta función requiere aceleración GPU que puede estar deshabilitada o no disponible." }, "RECORDING": { "TITLE": "Grabación", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/fr.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/fr.json index fa921c8e2..7d2ae9e3b 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/fr.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/fr.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "Aucun effet et arrière-plan flou", "NO_EFFECTS": "Aucun effet de fond", "BLURRED_EFFECT": "Arrière-plan flou", - "IMAGES_SECTION": "Images d'arrière-plan" + "IMAGES_SECTION": "Images d'arrière-plan", + "NOT_SUPPORTED": "Les arrière-plans virtuels ne sont pas pris en charge dans ce navigateur", + "NOT_SUPPORTED_DESCRIPTION": "Votre navigateur ne prend pas en charge les effets d'arrière-plan. Cette fonctionnalité nécessite l'accélération GPU qui peut être désactivée ou non disponible." }, "RECORDING": { "TITLE": "Enregistrement", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/hi.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/hi.json index d0733115a..1bd06ea1c 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/hi.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/hi.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "कोई प्रभाव नहीं है और पृष्ठभूमि धुंधली है", "NO_EFFECTS": "कोई पृष्ठभूमि प्रभाव नहीं है", "BLURRED_EFFECT": "पृष्ठभूमि धुंधली है", - "IMAGES_SECTION": "पृष्ठभूमि छवियां" + "IMAGES_SECTION": "पृष्ठभूमि छवियां", + "NOT_SUPPORTED": "इस ब्राउज़र में वर्चुअल बैकग्राउंड समर्थित नहीं है", + "NOT_SUPPORTED_DESCRIPTION": "आपका ब्राउज़र बैकग्राउंड इफेक्ट्स का समर्थन नहीं करता है। इस सुविधा के लिए GPU त्वरण की आवश्यकता है जो अक्षम या अनुपलब्ध हो सकता है।" }, "RECORDING": { "TITLE": "रिकॉर्डिंग", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/it.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/it.json index e92664779..a3026b856 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/it.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/it.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "Nessun effetto e sfondo sfocato", "NO_EFFECTS": "Nessun effetto di sfondo", "BLURRED_EFFECT": "Sfondo sfocato", - "IMAGES_SECTION": "Immagini di sfondo" + "IMAGES_SECTION": "Immagini di sfondo", + "NOT_SUPPORTED": "Gli sfondi virtuali non sono supportati in questo browser", + "NOT_SUPPORTED_DESCRIPTION": "Il tuo browser non supporta gli effetti di sfondo. Questa funzione richiede l'accelerazione GPU che potrebbe essere disabilitata o non disponibile." }, "RECORDING": { "TITLE": "Registrazione", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/ja.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/ja.json index 981b7b184..846f185a6 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/ja.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/ja.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "エフェクトなし、ぼやけた背景", "NO_EFFECTS": "背景エフェクトなし", "BLURRED_EFFECT": "ぼやけた背景", - "IMAGES_SECTION": "背景画像" + "IMAGES_SECTION": "背景画像", + "NOT_SUPPORTED": "このブラウザでは仮想背景はサポートされていません", + "NOT_SUPPORTED_DESCRIPTION": "お使いのブラウザは背景効果をサポートしていません。この機能にはGPUアクセラレーションが必要ですが、無効化されているか利用できません。" }, "RECORDING": { "TITLE": "レコーディング", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/nl.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/nl.json index 3a1b59c24..2728e7826 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/nl.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/nl.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "Geen effecten en onscherpe achtergrond", "NO_EFFECTS": "Geen achtergrondeffect", "BLURRED_EFFECT": "Onscherpe achtergrond", - "IMAGES_SECTION": "Achtergrondafbeeldingen" + "IMAGES_SECTION": "Achtergrondafbeeldingen", + "NOT_SUPPORTED": "Virtuele achtergronden worden niet ondersteund in deze browser", + "NOT_SUPPORTED_DESCRIPTION": "Uw browser ondersteunt geen achtergrondeffecten. Deze functie vereist GPU-versnelling die mogelijk uitgeschakeld of niet beschikbaar is." }, "RECORDING": { "TITLE": "Opname", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/pt.json b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/pt.json index 0cba34641..9bd7eed6e 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/pt.json +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/lang/pt.json @@ -120,7 +120,9 @@ "BLURRED_SECTION": "Sem efeitos e fundo desfocado", "NO_EFFECTS": "Sem efeito de fundo", "BLURRED_EFFECT": "Fundo desfocado", - "IMAGES_SECTION": "Imagens de fundo" + "IMAGES_SECTION": "Imagens de fundo", + "NOT_SUPPORTED": "Fundos virtuais não são suportados neste navegador", + "NOT_SUPPORTED_DESCRIPTION": "Seu navegador não suporta efeitos de fundo. Este recurso requer aceleração de GPU que pode estar desabilitada ou não disponível." }, "RECORDING": { "TITLE": "Gravação", diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/openvidu/openvidu.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/openvidu/openvidu.service.ts index df538b18d..c10393d79 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/openvidu/openvidu.service.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/openvidu/openvidu.service.ts @@ -1,8 +1,14 @@ -import { Injectable } from '@angular/core'; -import { BackgroundProcessor, /*BackgroundProcessorWrapper,*/ SwitchBackgroundProcessorOptions } from '@livekit/track-processors'; +import { Injectable, signal, Signal } from '@angular/core'; +import { + BackgroundProcessor, + supportsBackgroundProcessors, + supportsModernBackgroundProcessors, + /*BackgroundProcessorWrapper,*/ SwitchBackgroundProcessorOptions +} from '@livekit/track-processors'; import { AudioCaptureOptions, ConnectionState, + createLocalTracks, CreateLocalTracksOptions, E2EEOptions, ExternalE2EEKeyProvider, @@ -13,14 +19,12 @@ import { RoomOptions, Track, VideoCaptureOptions, - VideoPresets, - createLocalTracks + VideoPresets } from 'livekit-client'; import { ILogger } from '../../models/logger.model'; import { OpenViduComponentsConfigService } from '../config/directive-config.service'; import { DeviceService } from '../device/device.service'; import { LoggerService } from '../logger/logger.service'; -import { PlatformService } from '../platform/platform.service'; import { StorageService } from '../storage/storage.service'; // TODO: Remove this once livekit-client exports it @@ -58,8 +62,20 @@ export class OpenViduService { /** * Background processor for video tracks. Initialized in disabled mode. * This processor is shared between prejoin and in-room states. + * Only initialized if browser supports background processing (GPU available). */ - private backgroundProcessor: BackgroundProcessorWrapper; + private backgroundProcessor?: BackgroundProcessorWrapper; + + /** + * Signal to track if background processor is supported (requires GPU). + * Set to false if browser doesn't support it or processor initialization fails. + */ + private _isBackgroundProcessorSupported = signal(false); + + /** + * Public readonly signal for background processor support status. + */ + readonly isBackgroundProcessorSupported: Signal = this._isBackgroundProcessorSupported.asReadonly(); /** * @internal @@ -69,11 +85,33 @@ export class OpenViduService { private deviceService: DeviceService, private storageService: StorageService, private configService: OpenViduComponentsConfigService, - private platformService: PlatformService ) { this.log = this.loggerSrv.get('OpenViduService'); // this.isSttReadyObs = this._isSttReady.asObservable(); - this.backgroundProcessor = BackgroundProcessor({ mode: 'disabled' }); + + // Check if browser supports background processors + if (!supportsBackgroundProcessors()) { + this.log.w('Background processors not supported in this browser (GPU may be disabled)'); + this._isBackgroundProcessorSupported.set(false); + return; + } + + // Only initialize processor immediately for browsers supporting modern processors + // Browsers without modern support (e.g., Firefox) will initialize on-demand + if (supportsModernBackgroundProcessors()) { + try { + this.backgroundProcessor = BackgroundProcessor({ mode: 'disabled' }); + this._isBackgroundProcessorSupported.set(true); + this.log.d('Background processor initialized at startup (modern processors supported)'); + } catch (error: any) { + this.log.w('Failed to initialize background processor:', error?.message || error); + this._isBackgroundProcessorSupported.set(false); + } + } else { + // Mark as supported but don't initialize yet - will be created on-demand + this._isBackgroundProcessorSupported.set(true); + this.log.d('Background processors supported but not modern - will initialize on-demand'); + } } /** @@ -275,6 +313,8 @@ export class OpenViduService { return this.localTracks; } + + /** * Switches the background mode on the local video track. * Works both in prejoin and in-room states. @@ -285,20 +325,36 @@ export class OpenViduService { * @internal */ async switchBackgroundMode(options: SwitchBackgroundProcessorOptions): Promise { - // For Firefox, attach processor only when an effect is activated - if (this.platformService.isFirefox()) { - await this.handleFirefoxProcessor(options.mode); + if (!this.isBackgroundProcessorSupported()) { + this.log.w('Background processor not supported (GPU disabled). Virtual background is disabled.'); + return; } - await this.backgroundProcessor.switchTo(options); - this.log.d('Background mode switched:', options); + try { + // For browsers without modern processor support: attach processor on-demand when effect is activated + if (!supportsModernBackgroundProcessors()) { + await this.handleLazyProcessorAttachment(options.mode); + } + + // If processor exists, switch mode (either pre-initialized or just created on-demand) + if (this.backgroundProcessor) { + await this.backgroundProcessor.switchTo(options); + this.log.d('Background mode switched:', options); + } + } catch (error: any) { + this.log.e('Failed to switch background mode:', error?.message || error); + this._isBackgroundProcessorSupported.set(false); + // Don't throw - gracefully disable virtual background instead of crashing + } } /** - * Applies the background processor handling for Firefox browser. + * Handles lazy processor attachment for browsers without modern processor support. + * Creates and attaches processor on-demand when effect is activated. + * This is used for browsers like Firefox that don't support modern background processors. * @internal */ - private async handleFirefoxProcessor(mode: SwitchBackgroundProcessorOptions['mode']): Promise { + private async handleLazyProcessorAttachment(mode: SwitchBackgroundProcessorOptions['mode']): Promise { const videoTrack = await this.getVideoTrack(); if (!videoTrack) return; @@ -306,13 +362,25 @@ export class OpenViduService { const isDisabled = mode === 'disabled'; if (!isDisabled && !hasProcessor) { - this.log.d('Firefox: Attaching processor on effect activation'); - await videoTrack.setProcessor(this.backgroundProcessor); + try { + // Create processor on-demand if not already created + if (!this.backgroundProcessor) { + this.log.d('Creating background processor on-demand'); + this.backgroundProcessor = BackgroundProcessor({ mode: 'disabled' }); + } + + this.log.d('Attaching processor on effect activation (lazy loading)'); + await videoTrack.setProcessor(this.backgroundProcessor); + } catch (error: any) { + this.log.w('Failed to attach background processor (GPU may be disabled):', error?.message || error); + this._isBackgroundProcessorSupported.set(false); + // Continue without crashing - virtual background will be disabled + } return; } if (isDisabled && hasProcessor) { - this.log.d('Firefox: Stopping processor on effect deactivation'); + this.log.d('Stopping processor on effect deactivation'); await videoTrack.stopProcessor(); } } @@ -390,15 +458,24 @@ export class OpenViduService { } // Apply background processor to video track (initialized in disabled mode) - // For Firefox: skip processor attachment to avoid performance issues (applied only when effect is activated) - // For other browsers: attach processor for smooth transitions + // For browsers with modern processor support: attach processor immediately for smooth transitions + // For browsers without modern support: skip attachment, will be applied on-demand when effect is activated const videoTrack = newLocalTracks.find((t) => t.kind === Track.Kind.Video) as LocalVideoTrack | undefined; - debugger; - if (videoTrack && !this.platformService.isFirefox()) { - await videoTrack.setProcessor(this.backgroundProcessor); - this.log.d('Background processor applied to newly created video track'); - } else if (videoTrack && this.platformService.isFirefox()) { - this.log.d('Firefox detected: skipping processor attachment for better performance'); + if (videoTrack && supportsModernBackgroundProcessors()) { + if (this.isBackgroundProcessorSupported() && this.backgroundProcessor) { + try { + await videoTrack.setProcessor(this.backgroundProcessor); + this.log.d('Background processor applied to newly created video track'); + } catch (error: any) { + this.log.w('Failed to apply background processor (GPU may be disabled):', error?.message || error); + this._isBackgroundProcessorSupported.set(false); + // Continue without crashing - virtual background will be disabled + } + } else { + this.log.d('Background processor not supported (GPU disabled or not available)'); + } + } else if (videoTrack && !supportsModernBackgroundProcessors()) { + this.log.d('Modern background processors not supported - will apply processor on-demand when effect is activated'); } // Mute tracks if devices are disabled diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/participant/participant.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/participant/participant.service.ts index fbf2aa442..2b55cd96b 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/participant/participant.service.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/participant/participant.service.ts @@ -406,10 +406,9 @@ export class ParticipantService { // Update Signal - create new reference to trigger reactivity // The Observable will automatically emit via toObservable() if (this.localParticipant) { - const updatedParticipant = Object.assign( - Object.create(Object.getPrototypeOf(this.localParticipant)), - { ...this.localParticipant } - ); + const updatedParticipant = Object.assign(Object.create(Object.getPrototypeOf(this.localParticipant)), { + ...this.localParticipant + }); this.localParticipantWritableSignal.set(updatedParticipant); } else { this.localParticipantWritableSignal.set(undefined); diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/virtual-background/virtual-background.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/virtual-background/virtual-background.service.ts index 27796434f..29c2b98b6 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/virtual-background/virtual-background.service.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/virtual-background/virtual-background.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { computed, Injectable, Signal } from '@angular/core'; import { SwitchBackgroundProcessorOptions } from '@livekit/track-processors'; import { BehaviorSubject, Observable } from 'rxjs'; import { BackgroundEffect, EffectType } from '../../models/background-effect.model'; @@ -59,6 +59,14 @@ export class VirtualBackgroundService { return this.backgrounds; } + /** + * Computed signal that checks if virtual background is supported (requires GPU). + * Reactively tracks the support status from OpenViduService. + */ + readonly isVirtualBackgroundSupported: Signal = computed(() => + this.openviduService.isBackgroundProcessorSupported() + ); + isBackgroundApplied(): boolean { const bgSelected = this.backgroundIdSelected.getValue(); return !!bgSelected && bgSelected !== 'no_effect'; @@ -80,6 +88,12 @@ export class VirtualBackgroundService { * The background processor is centralized in OpenViduService for consistency. */ async applyBackground(bg: BackgroundEffect) { + // Check if virtual background is supported before proceeding + if (!this.isVirtualBackgroundSupported()) { + this.log.w('Virtual background not supported (GPU disabled). Skipping background application.'); + return; + } + // If the background is already applied, do nothing if (this.backgroundIsAlreadyApplied(bg.id)) return;