diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts
index e8d28b66..10c0d048 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts
@@ -30,6 +30,8 @@ import { StorageService } from '../../services/storage/storage.service';
* | **displayParticipantName** | `boolean` | {@link StreamDisplayParticipantNameDirective} |
* | **displayAudioDetection** | `boolean` | {@link StreamDisplayAudioDetectionDirective} |
* | **settingsButton** | `boolean` | {@link StreamSettingsButtonDirective} |
+ * | **resolution** | `string` | {@link StreamResolutionDirective} |
+ * | **frameRate** | `number` | {@link StreamFrameRateDirective} |
*
*
* See all {@link ApiDirectiveModule API Directives}
@@ -60,7 +62,7 @@ import { StorageService } from '../../services/storage/storage.service';
animations: [
trigger('posterAnimation', [
transition(':enter', [style({ opacity: 0 }), animate('100ms', style({ opacity: 1 }))]),
- transition(':leave', [style({ opacity: 1 }), animate('200ms', style({ opacity: 0 }))]),
+ transition(':leave', [style({ opacity: 1 }), animate('200ms', style({ opacity: 0 }))])
])
]
})
@@ -140,6 +142,7 @@ export class StreamComponent implements OnInit {
if (this._stream.participant) {
this.nickname = this._stream.participant.nickname;
}
+
}
/**
@@ -174,6 +177,12 @@ export class StreamComponent implements OnInit {
this.subscribeToStreamDirectives();
}
+ async ngAfterViewInit() {
+ if (this._stream.streamManager) {
+ await this.openviduService.updateVideoEncodingParameters(this._stream.streamManager);
+ }
+ }
+
ngOnDestroy() {
this.cdkSrv.setSelector('body');
if (this.settingsButtonSub) this.settingsButtonSub.unsubscribe();
@@ -214,7 +223,7 @@ export class StreamComponent implements OnInit {
* @ignore
*/
toggleMuteForcibly() {
- if(this._stream.participant){
+ if (this._stream.participant) {
this.participantService.setRemoteMutedForcibly(this._stream.participant.id, !this._stream.participant.isMutedForcibly);
}
}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts
index 1240eee5..183ec44a 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts
@@ -63,6 +63,7 @@ import { LangOption } from '../../models/lang.model';
* | **participantName** | `string` | {@link ParticipantNameDirective} |
* | **videoMuted** | `boolean` | {@link VideoMutedDirective} |
* | **audioMuted** | `boolean` | {@link AudioMutedDirective} |
+ | **simulcast** | `boolean` | {@link SimulcastDirective} |
* | **toolbarScreenshareButton** | `boolean` | {@link ToolbarScreenshareButtonDirective} |
* | **toolbarFullscreenButton** | `boolean` | {@link ToolbarFullscreenButtonDirective} |
* | **toolbarCaptionsButton** | `boolean` | {@link ToolbarCaptionsButtonDirective} |
@@ -75,6 +76,8 @@ import { LangOption } from '../../models/lang.model';
* | **streamDisplayParticipantName** | `boolean` | {@link StreamDisplayParticipantNameDirective} |
* | **streamDisplayAudioDetection** | `boolean` | {@link StreamDisplayAudioDetectionDirective} |
* | **streamSettingsButton** | `boolean` | {@link StreamSettingsButtonDirective} |
+ * | **streamFrameRate** | `number` | {@link StreamFrameRateDirective} |
+ * | **streamResolution** | `string` | {@link StreamResolutionDirective} |
* | **participantPanelItemMuteButton** | `boolean` | {@link ParticipantPanelItemMuteButtonDirective} |
* | **recordingActivityRecordingList** | `{@link RecordingInfo}[]` | {@link RecordingActivityRecordingsListDirective} |
* | **recordingActivityRecordingError** | `any` | {@link RecordingActivityRecordingErrorDirective} |
@@ -603,7 +606,12 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
private async initwebcamPublisher(): Promise {
return new Promise(async (resolve, reject) => {
try {
- const publisher = await this.openviduService.initDefaultPublisher();
+ const pp = {
+ resolution: this.libService.getStreamResolution(),
+ frameRate: this.libService.getStreamFrameRate(),
+ videoSimulcast: this.libService.isSimulcastEnabled()
+ };
+ const publisher = await this.openviduService.initDefaultPublisher(pp);
if (publisher) {
publisher.once('accessDenied', async (e: any) => {
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts
index 08d78ae0..8d7cb0a6 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts
@@ -8,7 +8,9 @@ import { RecordingActivityRecordingErrorDirective, RecordingActivityRecordingsLi
import {
StreamDisplayAudioDetectionDirective,
StreamDisplayParticipantNameDirective,
- StreamSettingsButtonDirective
+ StreamSettingsButtonDirective,
+ StreamFrameRateDirective,
+ StreamResolutionDirective
} from './stream.directive';
import {
ToolbarActivitiesPanelButtonDirective,
@@ -32,7 +34,8 @@ import {
MinimalDirective,
ParticipantNameDirective,
PrejoinDirective,
- VideoMutedDirective
+ VideoMutedDirective,
+ SimulcastDirective
} from './videoconference.directive';
@NgModule({
@@ -44,6 +47,7 @@ import {
CaptionsLangDirective,
PrejoinDirective,
VideoMutedDirective,
+ SimulcastDirective,
AudioMutedDirective,
ToolbarScreenshareButtonDirective,
ToolbarFullscreenButtonDirective,
@@ -61,6 +65,8 @@ import {
StreamDisplayParticipantNameDirective,
StreamDisplayAudioDetectionDirective,
StreamSettingsButtonDirective,
+ StreamFrameRateDirective,
+ StreamResolutionDirective,
LogoDirective,
ParticipantPanelItemMuteButtonDirective,
ParticipantNameDirective,
@@ -80,6 +86,7 @@ import {
CaptionsLangDirective,
PrejoinDirective,
VideoMutedDirective,
+ SimulcastDirective,
AudioMutedDirective,
ToolbarScreenshareButtonDirective,
ToolbarFullscreenButtonDirective,
@@ -97,6 +104,8 @@ import {
StreamDisplayParticipantNameDirective,
StreamDisplayAudioDetectionDirective,
StreamSettingsButtonDirective,
+ StreamFrameRateDirective,
+ StreamResolutionDirective,
LogoDirective,
ParticipantPanelItemMuteButtonDirective,
ParticipantNameDirective,
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/stream.directive.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/stream.directive.ts
index afecdf7a..51893254 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/stream.directive.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/stream.directive.ts
@@ -1,6 +1,108 @@
import { AfterViewInit, Directive, ElementRef, Input, OnDestroy } from '@angular/core';
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
+
+/**
+ * The **frameRate** directive allows initialize the publisher with a specific frame rate in stream component.
+ *
+ * Default: `30`
+ *
+ * It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `stream` component:
+ *
+ * @example
+ *
+ *
+ * \
+ * And it also can be used in the {@link StreamComponent}.
+ * @example
+ *
+ */
+@Directive({
+ selector: 'ov-videoconference[streamFrameRate], ov-stream[frameRate]'
+})
+export class StreamFrameRateDirective implements AfterViewInit, OnDestroy {
+ @Input() set streamFrameRate(value: number) {
+ this._frameRate = value;
+ this.update(this._frameRate);
+ }
+ @Input() set frameRate(value: number) {
+ this._frameRate = value;
+ this.update(this._frameRate);
+ }
+
+ _frameRate: number;
+
+ constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
+
+ ngOnDestroy(): void {
+ this.clear();
+ }
+
+ ngAfterViewInit() {
+ this.update(this._frameRate);
+ }
+
+ update(value: number) {
+ if (this.libService.streamFrameRate.getValue() !== value) {
+ this.libService.streamFrameRate.next(value);
+ }
+ }
+
+ clear() {
+ this.update(30);
+ }
+}
+
+/**
+ * The **resolution** directive allows to set a specific participant resolution in stream component.
+ *
+ * Default: `640x480`
+ *
+ * It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `stream` component:
+ *
+ * @example
+ *
+ *
+ * \
+ * And it also can be used in the {@link StreamComponent}.
+ * @example
+ *
+ */
+@Directive({
+ selector: 'ov-videoconference[streamResolution], ov-stream[resolution]'
+})
+export class StreamResolutionDirective implements AfterViewInit, OnDestroy {
+ @Input() set streamResolution(value: string) {
+ this._resolution = value;
+ this.update(this._resolution);
+ }
+ @Input() set resolution(value: string) {
+ this._resolution = value;
+ this.update(this._resolution);
+ }
+
+ _resolution: string;
+
+ constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
+
+ ngOnDestroy(): void {
+ this.clear();
+ }
+
+ ngAfterViewInit() {
+ this.update(this._resolution);
+ }
+
+ update(value: string) {
+ if (this.libService.streamResolution.getValue() !== value) {
+ this.libService.streamResolution.next(value);
+ }
+ }
+
+ clear() {
+ this.update('640x480');
+ }
+}
/**
* The **displayParticipantName** directive allows show/hide the participants name in stream component.
*
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts
index 453aafba..26e1ccae 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts
@@ -5,7 +5,6 @@ import { OpenViduAngularConfigService } from '../../services/config/openvidu-ang
import { TranslateService } from '../../services/translate/translate.service';
import { LangOption } from '../../models/lang.model';
-
/**
* The **minimal** directive applies a minimal UI hiding all controls except for cam and mic.
*
@@ -79,7 +78,7 @@ export class MinimalDirective implements OnDestroy {
* @example
*
*/
- @Directive({
+@Directive({
selector: 'ov-videoconference[lang]'
})
export class LangDirective implements OnDestroy {
@@ -152,7 +151,7 @@ export class LangOptionsDirective implements OnDestroy {
/**
* @ignore
*/
- @Input() set langOptions(value: LangOption []) {
+ @Input() set langOptions(value: LangOption[]) {
this.update(value);
}
@@ -178,7 +177,7 @@ export class LangOptionsDirective implements OnDestroy {
/**
* @ignore
*/
- update(value: LangOption [] | undefined) {
+ update(value: LangOption[] | undefined) {
this.translateService.setLanguageOptions(value);
}
}
@@ -208,7 +207,7 @@ export class LangOptionsDirective implements OnDestroy {
* @example
*
*/
- @Directive({
+@Directive({
selector: 'ov-videoconference[captionsLang]'
})
export class CaptionsLangDirective implements OnDestroy {
@@ -269,14 +268,14 @@ export class CaptionsLangDirective implements OnDestroy {
* @example
*
*/
- @Directive({
+@Directive({
selector: 'ov-videoconference[captionsLangOptions]'
})
export class CaptionsLangOptionsDirective implements OnDestroy {
/**
* @ignore
*/
- @Input() set captionsLangOptions(value: CaptionsLangOption []) {
+ @Input() set captionsLangOptions(value: CaptionsLangOption[]) {
this.update(value);
}
@@ -302,12 +301,11 @@ export class CaptionsLangOptionsDirective implements OnDestroy {
/**
* @ignore
*/
- update(value: CaptionsLangOption [] | undefined) {
+ update(value: CaptionsLangOption[] | undefined) {
this.captionService.setLanguageOptions(value);
}
}
-
/**
* The **participantName** directive sets the participant name. It can be useful for aplications which doesn't need the prejoin page.
*
@@ -477,7 +475,6 @@ export class VideoMutedDirective implements OnDestroy {
selector: 'ov-videoconference[audioMuted]'
})
export class AudioMutedDirective implements OnDestroy {
-
/**
* @ignore
*/
@@ -510,3 +507,56 @@ export class AudioMutedDirective implements OnDestroy {
}
}
}
+
+/**
+ * The **simulcast** directive allows to enable/disable the Simulcast feature. Simulcast is a technique that allows
+ * to send multiple versions of the same video stream at different resolutions, framerates and qualities. This way,
+ * the receiver can subscribe to the most appropriate stream for its current network conditions.
+ *
+ * It is only available for {@link VideoconferenceComponent} and **only if OpenVidu Server was configured to use the
+ * mediasoup media server**. Otherwise, Simulcast will be disabled.
+ *
+ * Default: `false`
+ *
+ * @example
+ *
+ */
+@Directive({
+ selector: 'ov-videoconference[simulcast]'
+})
+export class SimulcastDirective implements OnDestroy {
+ /**
+ * @ignore
+ */
+ @Input() set simulcast(value: boolean) {
+ this.update(value);
+ }
+
+ /**
+ * @ignore
+ */
+ constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
+
+ /**
+ * @ignore
+ */
+ ngOnDestroy(): void {
+ this.clear();
+ }
+
+ /**
+ * @ignore
+ */
+ clear() {
+ this.update(false);
+ }
+
+ /**
+ * @ignore
+ */
+ update(value: boolean) {
+ if (this.libService.simulcast.getValue() !== value) {
+ this.libService.simulcast.next(value);
+ }
+ }
+}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts
index 2b2e3ae6..6398d218 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts
@@ -19,6 +19,9 @@ export class OpenViduAngularConfigService {
prejoin = >new BehaviorSubject(true);
prejoinObs: Observable;
+ simulcast = >new BehaviorSubject(false);
+ simulcastObs: Observable;
+
videoMuted = >new BehaviorSubject(undefined);
videoMutedObs: Observable;
audioMuted = >new BehaviorSubject(undefined);
@@ -50,6 +53,11 @@ export class OpenViduAngularConfigService {
displaySessionName = >new BehaviorSubject(true);
displaySessionNameObs: Observable;
+ streamFrameRate = >new BehaviorSubject(30);
+ streamFrameRateObs: Observable;
+
+ streamResolution = >new BehaviorSubject('640x480');
+ streamResolutionObs: Observable;
displayLogo = >new BehaviorSubject(true);
displayLogoObs: Observable;
displayParticipantName = >new BehaviorSubject(true);
@@ -91,6 +99,7 @@ export class OpenViduAngularConfigService {
this.prejoinObs = this.prejoin.asObservable();
this.videoMutedObs = this.videoMuted.asObservable();
this.audioMutedObs = this.audioMuted.asObservable();
+ this.simulcastObs = this.simulcast.asObservable();
//Toolbar observables
this.screenshareButtonObs = this.screenshareButton.asObservable();
this.fullscreenButtonObs = this.fullscreenButton.asObservable();
@@ -106,6 +115,8 @@ export class OpenViduAngularConfigService {
this.toolbarSettingsButtonObs = this.toolbarSettingsButton.asObservable();
this.captionsButtonObs = this.captionsButton.asObservable();
//Stream observables
+ this.streamFrameRateObs = this.streamFrameRate.asObservable();
+ this.streamResolutionObs = this.streamResolution.asObservable();
this.displayParticipantNameObs = this.displayParticipantName.asObservable();
this.displayAudioDetectionObs = this.displayAudioDetection.asObservable();
this.streamSettingsButtonObs = this.streamSettingsButton.asObservable();
@@ -145,4 +156,16 @@ export class OpenViduAngularConfigService {
isBroadcastingEnabled(): boolean {
return this.broadcastingButton.getValue() && this.broadcastingActivity.getValue();
}
+
+ getStreamResolution(): string {
+ return this.streamResolution.getValue();
+ }
+
+ getStreamFrameRate(): number {
+ return this.streamFrameRate.getValue();
+ }
+
+ isSimulcastEnabled(): boolean {
+ return this.simulcast.getValue() || false;
+ }
}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts
index ef06f53b..7666468b 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts
@@ -8,7 +8,8 @@ import {
PublisherProperties,
Session,
SignalOptions,
- Stream
+ Stream,
+ StreamManager
} from 'openvidu-browser';
import { BehaviorSubject, Observable } from 'rxjs';
@@ -49,7 +50,7 @@ export class OpenViduService {
* @internal
*/
constructor(
- protected openviduAngularConfigSrv: OpenViduAngularConfigService,
+ protected libService: OpenViduAngularConfigService,
protected platformService: PlatformService,
protected loggerSrv: LoggerService,
private injector: Injector,
@@ -69,13 +70,13 @@ export class OpenViduService {
interval: 50
}
});
- if (this.openviduAngularConfigSrv.isProduction()) this.OV.enableProdMode();
+ if (this.libService.isProduction()) this.OV.enableProdMode();
this.webcamSession = this.OV.initSession();
// Initialize screen session only if it is not mobile platform
if (!this.platformService.isMobile()) {
this.OVScreen = new OpenVidu();
- if (this.openviduAngularConfigSrv.isProduction()) this.OVScreen.enableProdMode();
+ if (this.libService.isProduction()) this.OVScreen.enableProdMode();
this.screenSession = this.OVScreen.initSession();
}
}
@@ -244,11 +245,34 @@ export class OpenViduService {
this.disconnectSession(this.screenSession);
}
+ async updateVideoEncodingParameters(streamManager: StreamManager) {
+ if (!streamManager) return;
+ const track = streamManager?.stream.getMediaStream().getVideoTracks()[0];
+ const videoSender = streamManager?.stream
+ .getRTCPeerConnection()
+ .getSenders()
+ .find((sender) => sender.track === track);
+
+ if (!videoSender) return;
+
+ const parameters: RTCRtpSendParameters = videoSender.getParameters();
+ const desiredFrameRate = this.libService.getStreamFrameRate();
+ const desiredWidth = Number(this.libService.getStreamResolution().split('x')[0]);
+ const desiredResolution = Number(track?.getConstraints()?.width) / desiredWidth ?? 1.0;
+ parameters.encodings.forEach((encoding: RTCRtpEncodingParameters) => {
+ if (desiredFrameRate > 0 && encoding['maxFramerate'] !== desiredFrameRate) encoding['maxFramerate'] = desiredFrameRate;
+ if (desiredResolution >= 1 && encoding['scaleResolutionDownBy'] !== desiredResolution) {
+ encoding['scaleResolutionDownBy'] = desiredResolution;
+ }
+ });
+ await videoSender.setParameters(parameters);
+ }
+
/**
* @internal
* Initialize a publisher checking devices saved on storage or if participant have devices available.
*/
- async initDefaultPublisher(): Promise {
+ async initDefaultPublisher(pp?: Partial): Promise {
const hasVideoDevices = this.deviceService.hasVideoDeviceAvailable();
const hasAudioDevices = this.deviceService.hasAudioDeviceAvailable();
const isVideoActive = !this.deviceService.isVideoMuted();
@@ -259,7 +283,7 @@ export class OpenViduService {
if (hasVideoDevices) {
// Video is active, assign the device selected
- videoSource = this.deviceService.getCameraSelected().device;
+ videoSource = this.deviceService.getCameraSelected()?.device ?? false;
} else if (!isVideoActive && hasVideoDevices) {
// Video is muted, assign the default device
// videoSource = undefined;
@@ -267,18 +291,21 @@ export class OpenViduService {
if (hasAudioDevices) {
// Audio is active, assign the device selected
- audioSource = this.deviceService.getMicrophoneSelected().device;
+ audioSource = this.deviceService.getMicrophoneSelected()?.device ?? false;
} else if (!isAudioActive && hasAudioDevices) {
// Audio is muted, assign the default device
// audioSource = undefined;
}
- const mirror = this.deviceService.getCameraSelected() && this.deviceService.getCameraSelected().type === CameraType.FRONT;
+ const mirror = this.deviceService.getCameraSelected() && this.deviceService.getCameraSelected()?.type === CameraType.FRONT;
const properties: PublisherProperties = {
videoSource,
audioSource,
publishVideo: isVideoActive,
publishAudio: isAudioActive,
+ resolution: pp?.resolution ?? '640x480',
+ frameRate: pp?.frameRate ?? 30,
+ videoSimulcast: pp?.videoSimulcast ?? false,
mirror
};
if (hasVideoDevices || hasAudioDevices) {
@@ -520,7 +547,6 @@ export class OpenViduService {
}
}
-
/**
* @internal
* @param pp {@link PublisherProperties}
@@ -538,7 +564,7 @@ export class OpenViduService {
this.forceStopMediaTracks(participantService.getMyCameraPublisher().stream.getMediaStream(), trackType);
return this.OV.getUserMedia(pp);
} catch (error) {
- console.warn('Error creating MediaStream', error);
+ this.log.w('Error creating MediaStream', error);
if ((error).name === OpenViduErrorName.DEVICE_ACCESS_DENIED) {
this.log.w('The device requested is not available. Restoring the older one');
// The track requested is not available so we are getting the old tracks ids for recovering the track
@@ -559,7 +585,7 @@ export class OpenViduService {
*/
myNicknameHasBeenChanged(): boolean {
const participantService = this.injector.get(ParticipantService);
- let oldNickname: string = "";
+ let oldNickname: string = '';
try {
const connData = JSON.parse(this.cleanConnectionData(this.webcamSession.connection.data));
oldNickname = connData.clientData;
diff --git a/openvidu-components-angular/src/app/openvidu-call/call.component.html b/openvidu-components-angular/src/app/openvidu-call/call.component.html
index 0c5057c8..df54d5f9 100644
--- a/openvidu-components-angular/src/app/openvidu-call/call.component.html
+++ b/openvidu-components-angular/src/app/openvidu-call/call.component.html
@@ -1,11 +1,18 @@
-
+ {{ 'CUSTOM.BUTTON' | translate }}
-
+
diff --git a/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html b/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html
index d7fad23e..4dd44d98 100644
--- a/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html
+++ b/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html
@@ -1,5 +1,6 @@
+ */
+ @Input() set simulcast(value: string | boolean) {
+ this._simulcast = this.castToBoolean(value);
+ }
+
/**
* The **toolbarScreenshareButton** attribute allows show/hide the screenshare toolbar button.
*
@@ -524,6 +551,36 @@ export class OpenviduWebComponentComponent implements OnInit {
@Input() set streamSettingsButton(value: string | boolean) {
this._streamSettingsButton = this.castToBoolean(value);
}
+
+ /**
+ * The **resolution** directive allows to set a specific participant resolution in stream component.
+ *
+ * Default: `640x480`
+ *
+ *
+ * WARNING: If you want to use this parameter to OpenVidu Web Component statically, you have to replace the camelCase with a hyphen between words.
+ *
+ * @example
+ *
+ */
+ @Input() set streamResolution(value: string) {
+ this._streamResolution = value;
+ }
+
+ /**
+ * The **frameRate** directive allows initialize the publisher with a specific frame rate in stream component.
+ *
+ * Default: `30`
+ *
+ *
+ * WARNING: If you want to use this parameter to OpenVidu Web Component statically, you have to replace the camelCase with a hyphen between words.
+ *
+ * @example
+ *
+ */
+ @Input() set streamFrameRate(value: number) {
+ this._streamFrameRate = Number(value);
+ }
/**
* The **participantPanelItemMuteButton** attribute allows show/hide the muted button in participant panel item component.
*