openvidu-testapp: move STT button to stream dialog

pull/758/head
pabloFuente 2022-11-04 12:00:32 +01:00
parent 4d80f823b4
commit dd62c033df
8 changed files with 71 additions and 56 deletions

View File

@ -1033,7 +1033,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
} }
}); });
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .filter-btn")).click(); user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .other-operations-btn")).click();
Thread.sleep(1000); Thread.sleep(1000);
user.getDriver().findElement(By.id("apply-filter-btn")).click(); user.getDriver().findElement(By.id("apply-filter-btn")).click();
user.getDriver().findElement(By.id("close-dialog-btn")).click(); user.getDriver().findElement(By.id("close-dialog-btn")).click();
@ -2160,7 +2160,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Assert.assertTrue("Video is not average green", RecordingUtils.checkVideoAverageRgbGreen(rgb)); Assert.assertTrue("Video is not average green", RecordingUtils.checkVideoAverageRgbGreen(rgb));
// Try to apply none allowed filter // Try to apply none allowed filter
user.getDriver().findElement(By.cssSelector(".filter-btn")).click(); user.getDriver().findElement(By.cssSelector(".other-operations-btn")).click();
Thread.sleep(1000); Thread.sleep(1000);
WebElement filterTypeInput = user.getDriver().findElement(By.id("filter-type-field")); WebElement filterTypeInput = user.getDriver().findElement(By.id("filter-type-field"));
@ -2242,7 +2242,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Assert.assertTrue("Video is not average gray", RecordingUtils.checkVideoAverageRgbGray(rgb)); Assert.assertTrue("Video is not average gray", RecordingUtils.checkVideoAverageRgbGray(rgb));
// Remove filter // Remove filter
user.getDriver().findElement(By.cssSelector(".filter-btn")).click(); user.getDriver().findElement(By.cssSelector(".other-operations-btn")).click();
Thread.sleep(500); Thread.sleep(500);
user.getDriver().findElement(By.id("remove-filter-btn")).click(); user.getDriver().findElement(By.id("remove-filter-btn")).click();
user.getWaiter().until( user.getWaiter().until(
@ -2308,7 +2308,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
.assertMediaTracks(user.getDriver().findElements(By.tagName("video")), false, true)); .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), false, true));
// Publisher applies ZBarCode filter to itself // Publisher applies ZBarCode filter to itself
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .filter-btn")).click(); user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .other-operations-btn")).click();
Thread.sleep(500); Thread.sleep(500);
WebElement input = user.getDriver().findElement(By.id("filter-type-field")); WebElement input = user.getDriver().findElement(By.id("filter-type-field"));
input.clear(); input.clear();
@ -2353,7 +2353,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Thread.sleep(500); Thread.sleep(500);
// Moderator subscribes to CodeFound event for the Publisher's stream // Moderator subscribes to CodeFound event for the Publisher's stream
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .filter-btn")).click(); user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .other-operations-btn")).click();
Thread.sleep(500); Thread.sleep(500);
input = user.getDriver().findElement(By.id("filter-event-type-field")); input = user.getDriver().findElement(By.id("filter-event-type-field"));
input.clear(); input.clear();
@ -4052,7 +4052,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
event.keySet().size()); event.keySet().size());
// Filter event webhook // Filter event webhook
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .filter-btn")).click(); user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .other-operations-btn")).click();
Thread.sleep(500); Thread.sleep(500);
WebElement input = user.getDriver().findElement(By.id("filter-type-field")); WebElement input = user.getDriver().findElement(By.id("filter-type-field"));
input.clear(); input.clear();

View File

@ -24,7 +24,7 @@ import { SessionApiDialogComponent } from './components/dialogs/session-api-dial
import { EventsDialogComponent } from './components/dialogs/events-dialog/events-dialog.component'; import { EventsDialogComponent } from './components/dialogs/events-dialog/events-dialog.component';
import { PublisherPropertiesDialogComponent } from './components/dialogs/publisher-properties-dialog/publisher-properties-dialog.component'; import { PublisherPropertiesDialogComponent } from './components/dialogs/publisher-properties-dialog/publisher-properties-dialog.component';
import { ScenarioPropertiesDialogComponent } from './components/dialogs/scenario-properties-dialog/scenario-properties-dialog.component'; import { ScenarioPropertiesDialogComponent } from './components/dialogs/scenario-properties-dialog/scenario-properties-dialog.component';
import { FilterDialogComponent } from './components/dialogs/filter-dialog/filter-dialog.component'; import { OtherStreamOperationsDialogComponent } from './components/dialogs/other-stream-operations-dialog/other-stream-operations-dialog.component';
import { ShowCodecDialogComponent } from './components/dialogs/show-codec-dialog/show-codec-dialog.component'; import { ShowCodecDialogComponent } from './components/dialogs/show-codec-dialog/show-codec-dialog.component';
import { RecordingPropertiesComponent } from './components/dialogs/recording-properties/recording-properties.component'; import { RecordingPropertiesComponent } from './components/dialogs/recording-properties/recording-properties.component';
@ -52,7 +52,7 @@ import { ShowIceServerConfiguredDialog } from './components/dialogs/show-configu
LocalRecordingDialogComponent, LocalRecordingDialogComponent,
PublisherPropertiesDialogComponent, PublisherPropertiesDialogComponent,
ScenarioPropertiesDialogComponent, ScenarioPropertiesDialogComponent,
FilterDialogComponent, OtherStreamOperationsDialogComponent,
ShowCodecDialogComponent, ShowCodecDialogComponent,
ShowIceServerConfiguredDialog, ShowIceServerConfiguredDialog,
SessionInfoDialogComponent, SessionInfoDialogComponent,
@ -82,7 +82,7 @@ import { ShowIceServerConfiguredDialog } from './components/dialogs/show-configu
LocalRecordingDialogComponent, LocalRecordingDialogComponent,
PublisherPropertiesDialogComponent, PublisherPropertiesDialogComponent,
ScenarioPropertiesDialogComponent, ScenarioPropertiesDialogComponent,
FilterDialogComponent, OtherStreamOperationsDialogComponent,
ShowCodecDialogComponent, ShowCodecDialogComponent,
ShowIceServerConfiguredDialog, ShowIceServerConfiguredDialog,
SessionInfoDialogComponent SessionInfoDialogComponent

View File

@ -1,10 +1,10 @@
<div> <div>
<div fxLayout="row" fxLayoutGap="20px"> <div fxLayout="row" fxLayoutGap="20px">
<div> <div *ngIf="session.connection == stream.connection || session.capabilities.forceDisconnect">
<h2 mat-dialog-title>Filter application</h2> <h2 mat-dialog-title>Filter application</h2>
<mat-dialog-content> <mat-dialog-content>
<label class="label">Apply filter</label> <label class="label">Apply filter</label>
<button mat-button id="apply-filter-btn" (click)="apply()">Apply</button> <button mat-button id="apply-filter-btn" (click)="applyFilter()">Apply</button>
<mat-form-field> <mat-form-field>
<input matInput id="filter-type-field" placeholder="Type" [(ngModel)]="filterType"> <input matInput id="filter-type-field" placeholder="Type" [(ngModel)]="filterType">
</mat-form-field> </mat-form-field>
@ -27,11 +27,9 @@
<textarea id="filter-response-text-area" [(ngModel)]="response" matInput readonly></textarea> <textarea id="filter-response-text-area" [(ngModel)]="response" matInput readonly></textarea>
</mat-form-field> </mat-form-field>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions>
<button mat-button id="close-dialog-btn" [mat-dialog-close]="{session: session}">CLOSE</button>
</mat-dialog-actions>
</div> </div>
<div> <div>
<div *ngIf="session.connection == stream.connection || session.capabilities.forceDisconnect">
<h2 mat-dialog-title>Filter events</h2> <h2 mat-dialog-title>Filter events</h2>
<mat-dialog-content> <mat-dialog-content>
<mat-form-field> <mat-form-field>
@ -43,6 +41,21 @@
<label class="label">Remove listener of filter event</label> <label class="label">Remove listener of filter event</label>
<button mat-button id="unsub-filter-event-btn" (click)="unsubFilterEvent()">Remove listener</button> <button mat-button id="unsub-filter-event-btn" (click)="unsubFilterEvent()">Remove listener</button>
</mat-dialog-content> </mat-dialog-content>
<mat-divider style="margin: 25px 0"></mat-divider>
</div>
<h2 mat-dialog-title>Speech To Text</h2>
<mat-dialog-content>
<mat-form-field>
<input matInput id="stt-lang-field" placeholder="Language" [(ngModel)]="sttLang">
</mat-form-field>
<label class="label">Subscribe to Speech To Text</label>
<button mat-button id="sub-stt-btn" (click)="subStt()">Subscribe</button>
<label class="label">Unsubscribe from Speech To Text</label>
<button mat-button id="unsub-stt-btn" (click)="unsubStt()">Unsubscribe</button>
</mat-dialog-content>
</div> </div>
</div> </div>
<mat-dialog-actions>
<button mat-button id="close-dialog-btn" [mat-dialog-close]="{session: session}">CLOSE</button>
</mat-dialog-actions>
</div> </div>

View File

@ -5,33 +5,35 @@ import { Session, Stream, FilterEvent } from 'openvidu-browser';
@Component({ @Component({
selector: 'app-session-api-dialog', selector: 'app-session-api-dialog',
templateUrl: './filter-dialog.component.html', templateUrl: './other-stream-operations-dialog.component.html',
styleUrls: ['./filter-dialog.component.css'], styleUrls: ['./other-stream-operations-dialog.component.css'],
}) })
export class FilterDialogComponent { export class OtherStreamOperationsDialogComponent {
session: Session; session: Session;
stream: Stream; stream: Stream;
filterEventHandler: (FilterEvent) => void; filterEventHandler: (FilterEvent) => void;
filterType = 'GStreamerFilter'; filterType = 'GStreamerFilter'; // 'VB:image';
filterOptions = '{"command": "videobalance saturation=0.0"}'; filterOptions = '{"command": "videobalance saturation=0.0"}'; // '{"url": "https://openvidu.io/img/vb/office.jpeg"}';
filterMethod = 'setElementProperty'; filterMethod = 'setElementProperty'; // 'update';
filterParams = '{"propertyName":"saturation","propertyValue":"1.0"}'; filterParams = '{"propertyName":"saturation","propertyValue":"1.0"}'; // '{"url": "http://localhost:4443/virtual-background/backgrounds/mountain.jpeg", "maskRadius":0.1, "backgroundCoverage":0.6, "lightWrapping":0.3}';
eventType: string; eventType: string;
sttLang: string = 'en-US';
response: string; response: string;
constructor(public dialogRef: MatDialogRef<FilterDialogComponent>, constructor(public dialogRef: MatDialogRef<OtherStreamOperationsDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data) { @Inject(MAT_DIALOG_DATA) public data) {
this.session = data.session; this.session = data.session;
this.stream = data.stream; this.stream = data.stream;
this.filterEventHandler = data.filterEventHandler; this.filterEventHandler = data.filterEventHandler;
} }
apply() { applyFilter() {
console.log('Applying filter'); console.log('Applying filter');
this.stream.applyFilter(this.filterType, JSON.parse(this.filterOptions)) this.stream.applyFilter(this.filterType, JSON.parse(this.filterOptions))
.then(() => { .then(() => {
@ -101,4 +103,22 @@ export class FilterDialogComponent {
} }
} }
async subStt() {
try {
await this.session.subscribeToSpeechToText(this.stream, this.sttLang);
this.response = 'Subscribed to STT';
} catch (error) {
this.response = 'Error [' + error.message + ']';
}
}
async unsubStt() {
try {
await this.session.unsubscribeFromSpeechToText(this.stream);
this.response = 'Unsubscribed from STT';
} catch (error) {
this.response = 'Error [' + error.message + ']';
}
}
} }

View File

@ -64,7 +64,7 @@ p {
float: right; float: right;
} }
.filter-btn { .other-operations-btn {
float: right; float: right;
} }

View File

@ -5,8 +5,8 @@
<button class="video-btn events-btn bottom-left-rounded" title="Publisher events" (click)="openPublisherEventsDialog()"> <button class="video-btn events-btn bottom-left-rounded" title="Publisher events" (click)="openPublisherEventsDialog()">
<mat-icon aria-label="Publisher events" class="mat-icon material-icons" role="img" aria-hidden="true">notifications</mat-icon> <mat-icon aria-label="Publisher events" class="mat-icon material-icons" role="img" aria-hidden="true">notifications</mat-icon>
</button> </button>
<button class="video-btn filter-btn" *ngIf="!this.unpublished" title="Filter configuration" (click)="filterConfig()"> <button class="video-btn other-operations-btn" *ngIf="!this.unpublished" title="Other operations" (click)="otherOperations()">
<mat-icon aria-label="Filter configuration" class="mat-icon material-icons" role="img" aria-hidden="true">filter_vintage</mat-icon> <mat-icon aria-label="Other operations" class="mat-icon material-icons" role="img" aria-hidden="true">settings</mat-icon>
</button> </button>
<button class="video-btn stats-button bottom-left-rounded" title="Peer Connection Stats" (click)="showCodecUsed()"> <button class="video-btn stats-button bottom-left-rounded" title="Peer Connection Stats" (click)="showCodecUsed()">
<mat-icon aria-label="Peer Connection Stats" class="mat-icon material-icons" role="img" aria-hidden="true">info</mat-icon> <mat-icon aria-label="Peer Connection Stats" class="mat-icon material-icons" role="img" aria-hidden="true">info</mat-icon>
@ -35,9 +35,6 @@
<button *ngIf="!this.unpublished" class="video-btn reconnect-publisher-btn" title="Reconnect publisher" (click)="reconnect()"> <button *ngIf="!this.unpublished" class="video-btn reconnect-publisher-btn" title="Reconnect publisher" (click)="reconnect()">
<mat-icon aria-label="Reconnect publisher" class="mat-icon material-icons" role="img" aria-hidden="true">refresh</mat-icon> <mat-icon aria-label="Reconnect publisher" class="mat-icon material-icons" role="img" aria-hidden="true">refresh</mat-icon>
</button> </button>
<button *ngIf="streamManager.stream.hasAudio && !this.unpublished" class="video-btn stt-btn" title="Speech To Text" (click)="speechToText()">
<mat-icon aria-label="Speech To Text" class="mat-icon material-icons" role="img" aria-hidden="true">{{captionIcon}}</mat-icon>
</button>
<button *ngIf="!this.unpublished" class="video-btn rec-btn publisher-rec-btn" title="Record" (click)="record()"> <button *ngIf="!this.unpublished" class="video-btn rec-btn publisher-rec-btn" title="Record" (click)="record()">
<mat-icon aria-label="Start/Stop local recording" class="mat-icon material-icons" role="img" aria-hidden="true"> <mat-icon aria-label="Start/Stop local recording" class="mat-icon material-icons" role="img" aria-hidden="true">
{{recordIcon}}</mat-icon> {{recordIcon}}</mat-icon>
@ -55,8 +52,8 @@
<button *ngIf="subbed" class="video-btn events-btn bottom-left-rounded" title="Subscriber events" (click)="openSubscriberEventsDialog()"> <button *ngIf="subbed" class="video-btn events-btn bottom-left-rounded" title="Subscriber events" (click)="openSubscriberEventsDialog()">
<mat-icon aria-label="Subscriber events" class="mat-icon material-icons" role="img" aria-hidden="true">notifications</mat-icon> <mat-icon aria-label="Subscriber events" class="mat-icon material-icons" role="img" aria-hidden="true">notifications</mat-icon>
</button> </button>
<button *ngIf="OV.session.capabilities.forceDisconnect" class="video-btn filter-btn" title="Filter configuration" (click)="filterConfig()"> <button class="video-btn other-operations-btn" title="Other operations" (click)="otherOperations()">
<mat-icon aria-label="Filter configuration" class="mat-icon material-icons" role="img" aria-hidden="true">filter_vintage</mat-icon> <mat-icon aria-label="Other operations" class="mat-icon material-icons" role="img" aria-hidden="true">settings</mat-icon>
</button> </button>
<button class="video-btn stats-button bottom-left-rounded" title="Peer Connection Stats" (click)="showCodecUsed()"> <button class="video-btn stats-button bottom-left-rounded" title="Peer Connection Stats" (click)="showCodecUsed()">
<mat-icon aria-label="Peer Connection Stats" class="mat-icon material-icons" role="img" aria-hidden="true">info</mat-icon> <mat-icon aria-label="Peer Connection Stats" class="mat-icon material-icons" role="img" aria-hidden="true">info</mat-icon>
@ -82,9 +79,6 @@
<button *ngIf="!!pubSubVideoIcon" class="video-btn reconnect-subscriber-btn" title="Reconnect subscriber" (click)="reconnect()"> <button *ngIf="!!pubSubVideoIcon" class="video-btn reconnect-subscriber-btn" title="Reconnect subscriber" (click)="reconnect()">
<mat-icon aria-label="Reconnect subscriber" class="mat-icon material-icons" role="img" aria-hidden="true">refresh</mat-icon> <mat-icon aria-label="Reconnect subscriber" class="mat-icon material-icons" role="img" aria-hidden="true">refresh</mat-icon>
</button> </button>
<button *ngIf="streamManager.stream.hasAudio && !!captionIcon" class="video-btn stt-btn" title="Speech To Text" (click)="speechToText()">
<mat-icon aria-label="Speech To Text" class="mat-icon material-icons" role="img" aria-hidden="true">{{captionIcon}}</mat-icon>
</button>
<button *ngIf="OV.session.capabilities.forceUnpublish" class="video-btn force-unpub-btn" title="Force Unpublish" (click)="forceUnpublish()"> <button *ngIf="OV.session.capabilities.forceUnpublish" class="video-btn force-unpub-btn" title="Force Unpublish" (click)="forceUnpublish()">
<mat-icon aria-label="Force unpublish" class="mat-icon material-icons" role="img" aria-hidden="true">voice_over_off</mat-icon> <mat-icon aria-label="Force unpublish" class="mat-icon material-icons" role="img" aria-hidden="true">voice_over_off</mat-icon>
</button> </button>

View File

@ -21,7 +21,7 @@ import { MuteSubscribersService } from '../../services/mute-subscribers.service'
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { LocalRecordingDialogComponent } from '../dialogs/local-recording-dialog/local-recording-dialog.component'; import { LocalRecordingDialogComponent } from '../dialogs/local-recording-dialog/local-recording-dialog.component';
import { ExtensionDialogComponent } from '../dialogs/extension-dialog/extension-dialog.component'; import { ExtensionDialogComponent } from '../dialogs/extension-dialog/extension-dialog.component';
import { FilterDialogComponent } from '../dialogs/filter-dialog/filter-dialog.component'; import { OtherStreamOperationsDialogComponent } from '../dialogs/other-stream-operations-dialog/other-stream-operations-dialog.component';
import { OpenViduEvent } from '../openvidu-instance/openvidu-instance.component'; import { OpenViduEvent } from '../openvidu-instance/openvidu-instance.component';
import { ShowIceServerConfiguredDialog } from '../dialogs/show-configured-ice/show-configured-ice.component'; import { ShowIceServerConfiguredDialog } from '../dialogs/show-configured-ice/show-configured-ice.component';
@ -69,7 +69,6 @@ export class VideoComponent implements OnInit, OnDestroy {
pubSubAudioIcon = 'mic'; pubSubAudioIcon = 'mic';
recordIcon = 'fiber_manual_record'; recordIcon = 'fiber_manual_record';
pauseRecordIcon = ''; pauseRecordIcon = '';
captionIcon = 'closed_caption_disabled';
// Stats // Stats
usedVideoCodec: string; usedVideoCodec: string;
@ -166,7 +165,6 @@ export class VideoComponent implements OnInit, OnDestroy {
this.pubSubVideoIcon = ''; this.pubSubVideoIcon = '';
this.pubSubAudioIcon = ''; this.pubSubAudioIcon = '';
this.captionIcon = '';
this.recordIcon = ''; this.recordIcon = '';
this.pauseRecordIcon = ''; this.pauseRecordIcon = '';
this.pubSubIcon = 'play_arrow'; this.pubSubIcon = 'play_arrow';
@ -187,7 +185,6 @@ export class VideoComponent implements OnInit, OnDestroy {
this.pubSubVideoIcon = 'videocam'; this.pubSubVideoIcon = 'videocam';
this.pubSubAudioIcon = 'mic'; this.pubSubAudioIcon = 'mic';
this.captionIcon = 'closed_caption_disabled';
this.recordIcon = 'fiber_manual_record'; this.recordIcon = 'fiber_manual_record';
this.pauseRecordIcon = ''; this.pauseRecordIcon = '';
this.pubSubIcon = 'stop'; this.pubSubIcon = 'stop';
@ -337,15 +334,6 @@ export class VideoComponent implements OnInit, OnDestroy {
.catch(error => console.error(`Error while reconnecting stream ${this.streamManager.stream} (${this.streamManager.remote ? 'Subscriber' : 'Publisher'})`, error)); .catch(error => console.error(`Error while reconnecting stream ${this.streamManager.stream} (${this.streamManager.remote ? 'Subscriber' : 'Publisher'})`, error));
} }
async speechToText() {
if (this.captionIcon === 'closed_caption_disabled') {
await this.streamManager.stream.session.subscribeToSpeechToText(this.streamManager.stream, 'en-US');
} else {
await this.streamManager.stream.session.unsubscribeFromSpeechToText(this.streamManager.stream);
}
this.captionIcon = this.captionIcon === 'closed_caption_disabled' ? 'closed_caption' : 'closed_caption_disabled';
}
updateSubscriberEvents(oldValues) { updateSubscriberEvents(oldValues) {
const sub: Subscriber = <Subscriber>this.streamManager; const sub: Subscriber = <Subscriber>this.streamManager;
@ -806,8 +794,8 @@ export class VideoComponent implements OnInit, OnDestroy {
this.OV.session.forceDisconnect(this.streamManager.stream.connection); this.OV.session.forceDisconnect(this.streamManager.stream.connection);
} }
filterConfig() { otherOperations() {
this.dialog.open(FilterDialogComponent, { this.dialog.open(OtherStreamOperationsDialogComponent, {
data: { data: {
session: this.streamManager.stream.session, session: this.streamManager.stream.session,
stream: this.streamManager.stream, stream: this.streamManager.stream,