openvidu-components: Stored virtual background in local storage

Saved background in use in local storage for reapplying it at future meetings
pull/758/head
Carlos Santos 2022-11-07 11:48:43 +01:00
parent fb5c56cd87
commit ce4b783ef0
5 changed files with 69 additions and 19 deletions

View File

@ -14,7 +14,7 @@
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content class="sidenav-main"> <mat-sidenav-content class="sidenav-main">
<div id="layout-container"> <div id="layout-container" #layoutContainer>
<ng-container *ngTemplateOutlet="layoutTemplate"></ng-container> <ng-container *ngTemplateOutlet="layoutTemplate"></ng-container>
</div> </div>
</mat-sidenav-content> </mat-sidenav-content>

View File

@ -7,6 +7,7 @@ import {
EventEmitter, EventEmitter,
HostListener, HostListener,
Input, Input,
OnDestroy,
OnInit, OnInit,
Output, Output,
TemplateRef, TemplateRef,
@ -44,6 +45,7 @@ import { PlatformService } from '../../services/platform/platform.service';
import { RecordingService } from '../../services/recording/recording.service'; import { RecordingService } from '../../services/recording/recording.service';
import { TokenService } from '../../services/token/token.service'; import { TokenService } from '../../services/token/token.service';
import { TranslateService } from '../../services/translate/translate.service'; import { TranslateService } from '../../services/translate/translate.service';
import { VirtualBackgroundService } from '../../services/virtual-background/virtual-background.service';
/** /**
* @internal * @internal
@ -53,10 +55,10 @@ import { TranslateService } from '../../services/translate/translate.service';
selector: 'ov-session', selector: 'ov-session',
templateUrl: './session.component.html', templateUrl: './session.component.html',
styleUrls: ['./session.component.css'], styleUrls: ['./session.component.css'],
animations: [trigger('sessionAnimation', [transition(':enter', [style({ opacity: 0 }), animate('400ms', style({ opacity: 1 }))])])], animations: [trigger('sessionAnimation', [transition(':enter', [style({ opacity: 0 }), animate('50ms', style({ opacity: 1 }))])])],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class SessionComponent implements OnInit { export class SessionComponent implements OnInit, OnDestroy {
@ContentChild('toolbar', { read: TemplateRef }) toolbarTemplate: TemplateRef<any>; @ContentChild('toolbar', { read: TemplateRef }) toolbarTemplate: TemplateRef<any>;
@ContentChild('panel', { read: TemplateRef }) panelTemplate: TemplateRef<any>; @ContentChild('panel', { read: TemplateRef }) panelTemplate: TemplateRef<any>;
@ContentChild('layout', { read: TemplateRef }) layoutTemplate: TemplateRef<any>; @ContentChild('layout', { read: TemplateRef }) layoutTemplate: TemplateRef<any>;
@ -100,6 +102,7 @@ export class SessionComponent implements OnInit {
private translateService: TranslateService, private translateService: TranslateService,
private captionService: CaptionService, private captionService: CaptionService,
private platformService: PlatformService, private platformService: PlatformService,
private backgroundService: VirtualBackgroundService,
private cd: ChangeDetectorRef private cd: ChangeDetectorRef
) { ) {
this.log = this.loggerSrv.get('SessionComponent'); this.log = this.loggerSrv.get('SessionComponent');
@ -152,6 +155,16 @@ export class SessionComponent implements OnInit {
}, 0); }, 0);
} }
@ViewChild('layoutContainer')
set layoutContainer(container: ElementRef) {
setTimeout(async () => {
if (container) {
// Apply background from storage when layout container is in DOM
await this.backgroundService.applyBackgroundFromStorage();
}
}, 0);
}
async ngOnInit() { async ngOnInit() {
if (!this.usedInPrejoinPage) { if (!this.usedInPrejoinPage) {
if (!this.tokenService.getScreenToken()) { if (!this.tokenService.getScreenToken()) {

View File

@ -8,5 +8,6 @@ export enum Storage {
AUDIO_MUTED = 'openviduCallAudioMuted', AUDIO_MUTED = 'openviduCallAudioMuted',
VIDEO_MUTED = 'openviduCallVideoMuted', VIDEO_MUTED = 'openviduCallVideoMuted',
LANG = 'openviduCallLang', LANG = 'openviduCallLang',
CAPTION_LANG = 'openviduCallCaptionLang' CAPTION_LANG = 'openviduCallCaptionLang',
BACKGROUND = "openviduCallBackground"
} }

View File

@ -21,7 +21,7 @@ export class StorageService {
return this.get(Storage.USER_NICKNAME); return this.get(Storage.USER_NICKNAME);
} }
setNickname(name: string){ setNickname(name: string) {
this.set(Storage.USER_NICKNAME, name); this.set(Storage.USER_NICKNAME, name);
} }
getVideoDevice() { getVideoDevice() {
@ -54,7 +54,7 @@ export class StorageService {
this.set(Storage.AUDIO_MUTED, `${muted}`); this.set(Storage.AUDIO_MUTED, `${muted}`);
} }
setLang(lang: string){ setLang(lang: string) {
this.set(Storage.LANG, lang); this.set(Storage.LANG, lang);
} }
@ -62,7 +62,7 @@ export class StorageService {
return this.get(Storage.LANG); return this.get(Storage.LANG);
} }
setCaptionLang(lang: string){ setCaptionLang(lang: string) {
this.set(Storage.CAPTION_LANG, lang); this.set(Storage.CAPTION_LANG, lang);
} }
@ -70,15 +70,35 @@ export class StorageService {
return this.get(Storage.CAPTION_LANG); return this.get(Storage.CAPTION_LANG);
} }
setBackground(id: string) {
this.set(Storage.BACKGROUND, id);
}
getBackground(): string {
return this.get(Storage.BACKGROUND);
}
removeBackground() {
this.remove(Storage.BACKGROUND);
}
private set(key: string, item: any) { private set(key: string, item: any) {
const value = JSON.stringify({ item: item }); const value = JSON.stringify({ item: item });
// this.log.d('Storing on localStorage "' + key + '" with value "' + value + '"'); // this.log.d('Storing on localStorage "' + key + '" with value "' + value + '"');
this.storage.setItem(key, value); this.storage.setItem(key, value);
} }
private get(key: string): any { private get(key: string): any {
const value = JSON.parse(this.storage.getItem(key)); const str = this.storage.getItem(key);
return value?.item ? value.item : null; if (!!str) {
return JSON.parse(str).item;
}
return null;
} }
private remove(key: string) {
this.storage.removeItem(key);
}
public clear() { public clear() {
this.log.d('Clearing localStorage'); this.log.d('Clearing localStorage');
this.storage.clear(); this.storage.clear();

View File

@ -2,8 +2,8 @@ import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { BackgroundEffect, EffectType } from '../../models/background-effect.model'; import { BackgroundEffect, EffectType } from '../../models/background-effect.model';
import { ParticipantService } from '../participant/participant.service'; import { ParticipantService } from '../participant/participant.service';
import { StorageService } from '../storage/storage.service';
import { TokenService } from '../token/token.service'; import { TokenService } from '../token/token.service';
import { TranslateService } from '../translate/translate.service';
/** /**
* @internal * @internal
@ -38,7 +38,11 @@ export class VirtualBackgroundService {
{ id: '18', type: EffectType.IMAGE, thumbnail: 'assets/backgrounds/thumbnails/bg-18.jpg', src: 'assets/backgrounds/bg-18.jpg' } { id: '18', type: EffectType.IMAGE, thumbnail: 'assets/backgrounds/thumbnails/bg-18.jpg', src: 'assets/backgrounds/bg-18.jpg' }
]; ];
constructor(private participantService: ParticipantService, private translateService: TranslateService, private tokenService: TokenService) { constructor(
private participantService: ParticipantService,
private storageService: StorageService,
private tokenService: TokenService
) {
this.backgroundSelectedObs = this.backgroundSelected.asObservable(); this.backgroundSelectedObs = this.backgroundSelected.asObservable();
} }
@ -51,22 +55,33 @@ export class VirtualBackgroundService {
return !!bgSelected && bgSelected !== 'no_effect'; return !!bgSelected && bgSelected !== 'no_effect';
} }
async applyBackground(effect: BackgroundEffect) { async applyBackgroundFromStorage() {
if (effect.id !== this.backgroundSelected.getValue()) { const bgId = this.storageService.getBackground();
if (!!bgId) {
const background = this.backgrounds.find((bg) => bg.id === bgId);
if (background) {
this.applyBackground(background);
}
}
}
async applyBackground(bg: BackgroundEffect) {
if (bg.id !== this.backgroundSelected.getValue()) {
const filter = this.participantService.getMyCameraPublisher().stream.filter; const filter = this.participantService.getMyCameraPublisher().stream.filter;
const isBackgroundSelected = !!filter && filter.type.startsWith('VB:'); const isBackgroundSelected = !!filter && filter.type.startsWith('VB:');
let options = { token: this.tokenService.getWebcamToken(), url: '' }; let options = { token: this.tokenService.getWebcamToken(), url: '' };
if (effect.type === EffectType.IMAGE) { if (bg.type === EffectType.IMAGE) {
options.url = effect.src; options.url = bg.src;
} }
if (isBackgroundSelected && this.hasSameTypeAsAbove(effect.type)) { if (isBackgroundSelected && this.hasSameTypeAsAbove(bg.type)) {
this.replaceBackground(effect); this.replaceBackground(bg);
} else { } else {
await this.removeBackground(); await this.removeBackground();
await this.participantService.getMyCameraPublisher().stream.applyFilter(`VB:${effect.type.toLowerCase()}`, options); await this.participantService.getMyCameraPublisher().stream.applyFilter(`VB:${bg.type.toLowerCase()}`, options);
} }
this.backgroundSelected.next(effect.id); this.storageService.setBackground(bg.id);
this.backgroundSelected.next(bg.id);
} }
} }
@ -74,6 +89,7 @@ export class VirtualBackgroundService {
if (!!this.isBackgroundApplied()) { if (!!this.isBackgroundApplied()) {
this.backgroundSelected.next('no_effect'); this.backgroundSelected.next('no_effect');
await this.participantService.getMyCameraPublisher().stream.removeFilter(); await this.participantService.getMyCameraPublisher().stream.removeFilter();
this.storageService.removeBackground();
} }
} }