openvidu-testapp: update dependency. Improved test scenarios

v2compatibility
pabloFuente 2024-09-23 15:28:08 +02:00
parent 1f489f2443
commit bbb70dd3ee
4 changed files with 285 additions and 216 deletions

View File

@ -23,8 +23,8 @@
"colormap": "2.3.2", "colormap": "2.3.2",
"core-js": "3.26.1", "core-js": "3.26.1",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"openvidu-browser-v2compatibility": "3.0.0-beta1", "openvidu-browser-v2compatibility": "3.0.0-beta2",
"openvidu-node-client-v2compatibility": "3.0.0-beta1", "openvidu-node-client-v2compatibility": "3.0.0-beta2",
"rxjs": "7.5.7", "rxjs": "7.5.7",
"tslib": "2.4.1", "tslib": "2.4.1",
"zone.js": "0.12.0" "zone.js": "0.12.0"
@ -8190,9 +8190,9 @@
} }
}, },
"node_modules/openvidu-browser-v2compatibility": { "node_modules/openvidu-browser-v2compatibility": {
"version": "3.0.0-beta1", "version": "3.0.0-beta2",
"resolved": "https://registry.npmjs.org/openvidu-browser-v2compatibility/-/openvidu-browser-v2compatibility-3.0.0-beta1.tgz", "resolved": "https://registry.npmjs.org/openvidu-browser-v2compatibility/-/openvidu-browser-v2compatibility-3.0.0-beta2.tgz",
"integrity": "sha512-p4ouS/9xfbaskhsu8f/dHS9mHnz2O48dHZl+WJFqW8YUJyo9OCcTc2VK7Wt1ILnF0OIqnerlZcjuSZwfmRr5wg==", "integrity": "sha512-IDDsunat/ln1vvSRaFtmXG4oEgYT+jYe9BX22+nLGyiSLpOE/w6oDDy6QAsnu6mTBQHQixJoVdNusEynjozd5A==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@livekit/egress-sdk": "^0.2.0", "@livekit/egress-sdk": "^0.2.0",
@ -8273,9 +8273,9 @@
} }
}, },
"node_modules/openvidu-node-client-v2compatibility": { "node_modules/openvidu-node-client-v2compatibility": {
"version": "3.0.0-beta1", "version": "3.0.0-beta2",
"resolved": "https://registry.npmjs.org/openvidu-node-client-v2compatibility/-/openvidu-node-client-v2compatibility-3.0.0-beta1.tgz", "resolved": "https://registry.npmjs.org/openvidu-node-client-v2compatibility/-/openvidu-node-client-v2compatibility-3.0.0-beta2.tgz",
"integrity": "sha512-BmTTJIfagiWDlthidtQcEvP5clfYmVznh1Xm3nL1GXaAIT0fC7gmn4tvfiUtH3oh2V9TijV7pD1I8ICjf5zdFg==", "integrity": "sha512-wULJ7MqXosNALtYyr9qgcXbh5M/aPINhDTpBJsstudbzqQyyLbou+jkjYhjnpNXOeJid2Ebyg5gYo4ndZf46zA==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"axios": "1.7.1", "axios": "1.7.1",
@ -17792,9 +17792,9 @@
} }
}, },
"openvidu-browser-v2compatibility": { "openvidu-browser-v2compatibility": {
"version": "3.0.0-beta1", "version": "3.0.0-beta2",
"resolved": "https://registry.npmjs.org/openvidu-browser-v2compatibility/-/openvidu-browser-v2compatibility-3.0.0-beta1.tgz", "resolved": "https://registry.npmjs.org/openvidu-browser-v2compatibility/-/openvidu-browser-v2compatibility-3.0.0-beta2.tgz",
"integrity": "sha512-p4ouS/9xfbaskhsu8f/dHS9mHnz2O48dHZl+WJFqW8YUJyo9OCcTc2VK7Wt1ILnF0OIqnerlZcjuSZwfmRr5wg==", "integrity": "sha512-IDDsunat/ln1vvSRaFtmXG4oEgYT+jYe9BX22+nLGyiSLpOE/w6oDDy6QAsnu6mTBQHQixJoVdNusEynjozd5A==",
"requires": { "requires": {
"@livekit/egress-sdk": "^0.2.0", "@livekit/egress-sdk": "^0.2.0",
"@livekit/track-processors": "^0.3.1", "@livekit/track-processors": "^0.3.1",
@ -17849,9 +17849,9 @@
} }
}, },
"openvidu-node-client-v2compatibility": { "openvidu-node-client-v2compatibility": {
"version": "3.0.0-beta1", "version": "3.0.0-beta2",
"resolved": "https://registry.npmjs.org/openvidu-node-client-v2compatibility/-/openvidu-node-client-v2compatibility-3.0.0-beta1.tgz", "resolved": "https://registry.npmjs.org/openvidu-node-client-v2compatibility/-/openvidu-node-client-v2compatibility-3.0.0-beta2.tgz",
"integrity": "sha512-BmTTJIfagiWDlthidtQcEvP5clfYmVznh1Xm3nL1GXaAIT0fC7gmn4tvfiUtH3oh2V9TijV7pD1I8ICjf5zdFg==", "integrity": "sha512-wULJ7MqXosNALtYyr9qgcXbh5M/aPINhDTpBJsstudbzqQyyLbou+jkjYhjnpNXOeJid2Ebyg5gYo4ndZf46zA==",
"requires": { "requires": {
"axios": "1.7.1", "axios": "1.7.1",
"buffer": "6.0.3" "buffer": "6.0.3"

View File

@ -14,8 +14,8 @@
"colormap": "2.3.2", "colormap": "2.3.2",
"core-js": "3.26.1", "core-js": "3.26.1",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"openvidu-browser-v2compatibility": "3.0.0-beta1", "openvidu-browser-v2compatibility": "3.0.0-beta2",
"openvidu-node-client-v2compatibility": "3.0.0-beta1", "openvidu-node-client-v2compatibility": "3.0.0-beta2",
"rxjs": "7.5.7", "rxjs": "7.5.7",
"tslib": "2.4.1", "tslib": "2.4.1",
"zone.js": "0.12.0" "zone.js": "0.12.0"
@ -47,4 +47,4 @@
"test": "ng test" "test": "ng test"
}, },
"version": "2.30.0" "version": "2.30.0"
} }

View File

@ -1,32 +1,38 @@
import { HttpClient, HttpHeaders } from '@angular/common/http'; import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from "@angular/core";
import { Subscription } from 'rxjs'; import { Subscription } from "rxjs";
import { OpenviduParamsService } from '../../services/openvidu-params.service'; import { OpenviduParamsService } from "../../services/openvidu-params.service";
import { TestFeedService } from '../../services/test-feed.service'; import { TestFeedService } from "../../services/test-feed.service";
import { ScenarioPropertiesDialogComponent } from '../dialogs/scenario-properties-dialog/scenario-properties-dialog.component'; import { ScenarioPropertiesDialogComponent } from "../dialogs/scenario-properties-dialog/scenario-properties-dialog.component";
import { SessionConf } from '../openvidu-instance/openvidu-instance.component'; import { SessionConf } from "../openvidu-instance/openvidu-instance.component";
import { StreamManagerWrapper } from '../users-table/table-video.component'; import { StreamManagerWrapper } from "../users-table/table-video.component";
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from "@angular/material/dialog";
import { import {
ConnectionEvent, OpenVidu, PublisherProperties, Session, ConnectionEvent,
OpenVidu,
PublisherProperties,
Session,
SessionDisconnectedEvent, SessionDisconnectedEvent,
StreamEvent, StreamEvent,
StreamManagerEvent StreamManagerEvent,
} from 'openvidu-browser-v2compatibility'; } from "openvidu-browser-v2compatibility";
import { import {
MediaMode, OpenVidu as OpenViduAPI, RecordingLayout, RecordingMode, SessionProperties as SessionPropertiesAPI MediaMode,
} from 'openvidu-node-client-v2compatibility'; OpenVidu as OpenViduAPI,
RecordingLayout,
RecordingMode,
SessionProperties as SessionPropertiesAPI,
} from "openvidu-node-client-v2compatibility";
@Component({ @Component({
selector: 'app-test-scenarios', selector: "app-test-scenarios",
templateUrl: './test-scenarios.component.html', templateUrl: "./test-scenarios.component.html",
styleUrls: ['./test-scenarios.component.css'] styleUrls: ["./test-scenarios.component.css"],
}) })
export class TestScenariosComponent implements OnInit, OnDestroy { export class TestScenariosComponent implements OnInit, OnDestroy {
fixedSessionId = "SCENARIO_TEST";
fixedSessionId = 'SCENARIO_TEST';
openviduUrl: string; openviduUrl: string;
openviduSecret: string; openviduSecret: string;
@ -40,7 +46,7 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
users: SessionConf[] = []; users: SessionConf[] = [];
connections: string[] = []; connections: string[] = [];
publishers: StreamManagerWrapper[] = []; publishers: StreamManagerWrapper[] = [];
subscribers: { connectionId: string, subs: StreamManagerWrapper[] }[] = []; subscribers: { connectionId: string; subs: StreamManagerWrapper[] }[] = [];
totalNumberOfStreams = 0; totalNumberOfStreams = 0;
manyToMany = 2; manyToMany = 2;
oneToMany = 2; oneToMany = 2;
@ -56,38 +62,38 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
recordingMode: RecordingMode.MANUAL, recordingMode: RecordingMode.MANUAL,
defaultRecordingProperties: { defaultRecordingProperties: {
recordingLayout: RecordingLayout.BEST_FIT, recordingLayout: RecordingLayout.BEST_FIT,
customLayout: '' customLayout: "",
}, },
customSessionId: '' customSessionId: "",
}; };
turnConf = 'auto'; turnConf = "auto";
manualTurnConf: RTCIceServer = { urls: [] }; manualTurnConf: RTCIceServer = { urls: [] };
publisherProperties: PublisherProperties = { publisherProperties: PublisherProperties = {
audioSource: undefined, audioSource: undefined,
videoSource: undefined, videoSource: undefined,
frameRate: 1, frameRate: 1,
resolution: '80x60', resolution: "40x30",
mirror: true, mirror: true,
publishAudio: true, publishAudio: true,
publishVideo: true publishVideo: true,
}; };
report; report;
numberOfReports = 0; numberOfReports = 0;
stringifyAllReports = ''; stringifyAllReports = "";
textAreaValue = ''; textAreaValue = "";
isFocusedOnReport = false; isFocusedOnReport = false;
private API_PATH = 'openvidu/api'; private API_PATH = "openvidu/api";
constructor( constructor(
private openviduParamsService: OpenviduParamsService, private openviduParamsService: OpenviduParamsService,
private testFeedService: TestFeedService, private testFeedService: TestFeedService,
private dialog: MatDialog, private dialog: MatDialog,
private http: HttpClient private http: HttpClient
) { } ) {}
ngOnInit() { ngOnInit() {
const openviduParams = this.openviduParamsService.getParams(); const openviduParams = this.openviduParamsService.getParams();
@ -95,15 +101,19 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
this.openviduSecret = openviduParams.openviduSecret; this.openviduSecret = openviduParams.openviduSecret;
this.paramsSubscription = this.openviduParamsService.newParams$.subscribe( this.paramsSubscription = this.openviduParamsService.newParams$.subscribe(
params => { (params) => {
this.openviduUrl = params.openviduUrl; this.openviduUrl = params.openviduUrl;
this.openviduSecret = params.openviduSecret; this.openviduSecret = params.openviduSecret;
}); }
);
this.eventsInfoSubscription = this.testFeedService.newLastEvent$.subscribe( this.eventsInfoSubscription = this.testFeedService.newLastEvent$.subscribe(
newEvent => { (newEvent) => {
(window as any).myEvents += ('<br>' + this.testFeedService.stringifyEventNoCircularDependencies(newEvent)); (window as any).myEvents +=
}); "<br>" +
this.testFeedService.stringifyEventNoCircularDependencies(newEvent);
}
);
} }
ngOnDestroy() { ngOnDestroy() {
@ -113,7 +123,6 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
} }
loadScenario(subsPubs: number, pubs: number, subs: number): void { loadScenario(subsPubs: number, pubs: number, subs: number): void {
this.totalNumberOfStreams = pubs + subsPubs; // Number of outgoing streams this.totalNumberOfStreams = pubs + subsPubs; // Number of outgoing streams
this.totalNumberOfStreams += pubs * (subs + subsPubs); // Publishers only times total number of subscribers this.totalNumberOfStreams += pubs * (subs + subsPubs); // Publishers only times total number of subscribers
if (subsPubs > 0) { if (subsPubs > 0) {
@ -122,7 +131,10 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
} }
this.users = []; this.users = [];
this.report = { 'streamsOut': { 'numberOfElements': 0, 'content': [] }, 'streamsIn': { 'numberOfElements': 0, 'content': [] } }; this.report = {
streamsOut: { numberOfElements: 0, content: [] },
streamsIn: { numberOfElements: 0, content: [] },
};
this.loadSubsPubs(subsPubs); this.loadSubsPubs(subsPubs);
this.loadPubs(pubs); this.loadPubs(pubs);
this.loadSubs(subs); this.loadSubs(subs);
@ -134,6 +146,11 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
for (const session of this.sessions) { for (const session of this.sessions) {
session.disconnect(); session.disconnect();
} }
if (!!this.OV_NodeClient) {
this.OV_NodeClient.activeSessions.forEach(async (session) => {
await session.close();
});
}
this.publishers = []; this.publishers = [];
this.subscribers = []; this.subscribers = [];
this.OVs = []; this.OVs = [];
@ -142,8 +159,8 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
this.scenarioPlaying = false; this.scenarioPlaying = false;
delete this.report; delete this.report;
this.numberOfReports = 0; this.numberOfReports = 0;
this.textAreaValue = ''; this.textAreaValue = "";
this.stringifyAllReports = ''; this.stringifyAllReports = "";
} }
private loadSubsPubs(n: number): void { private loadSubsPubs(n: number): void {
@ -151,7 +168,7 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
this.users.push({ this.users.push({
subscribeTo: true, subscribeTo: true,
publishTo: true, publishTo: true,
startSession: true startSession: true,
}); });
} }
} }
@ -161,7 +178,7 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
this.users.push({ this.users.push({
subscribeTo: true, subscribeTo: true,
publishTo: false, publishTo: false,
startSession: true startSession: true,
}); });
} }
} }
@ -171,26 +188,25 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
this.users.push({ this.users.push({
subscribeTo: false, subscribeTo: false,
publishTo: true, publishTo: true,
startSession: true startSession: true,
}); });
} }
} }
private startSession() { private startSession() {
for (const user of this.users) { for (const user of this.users) {
this.getToken().then(token => { this.getToken().then((token) => {
const startTimeForUser = Date.now(); const startTimeForUser = Date.now();
const OV = new OpenVidu(); const OV = new OpenVidu();
OV.setAdvancedConfiguration({ OV.setAdvancedConfiguration({
noStreamPlayingEventExceptionTimeout: 50000 noStreamPlayingEventExceptionTimeout: 50000,
}); });
if (this.turnConf === 'freeice') { if (this.turnConf === "freeice") {
OV.setAdvancedConfiguration({ iceServers: 'freeice' }); OV.setAdvancedConfiguration({ iceServers: "freeice" });
} else if (this.turnConf === 'manual') { } else if (this.turnConf === "manual") {
OV.setAdvancedConfiguration({ iceServers: [this.manualTurnConf] }); OV.setAdvancedConfiguration({ iceServers: [this.manualTurnConf] });
} }
const session = OV.initSession(); const session = OV.initSession();
@ -198,90 +214,117 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
this.OVs.push(OV); this.OVs.push(OV);
this.sessions.push(session); this.sessions.push(session);
session.on('connectionCreated', (event: ConnectionEvent) => { session.on("connectionCreated", (event: ConnectionEvent) => {
this.testFeedService.pushNewEvent({ user: 0, event });
if (this.connections.indexOf(event.connection.connectionId) === -1) { if (this.connections.indexOf(event.connection.connectionId) === -1) {
this.connections.push(event.connection.connectionId); this.connections.push(event.connection.connectionId);
} }
}); });
session.on('sessionDisconnected', (event: SessionDisconnectedEvent) => { session.on("sessionDisconnected", (event: SessionDisconnectedEvent) => {
this.testFeedService.pushNewEvent({ user: 0, event }); this.testFeedService.pushNewEvent({ user: 0, event });
}); });
session.on('reconnecting', () => { session.on("reconnecting", () => {
const event = { cancelable: false, target: session, type: 'reconnecting', hasBeenPrevented: false, isDefaultPrevented: undefined, preventDefault: undefined, callDefaultBehavior: undefined }; const event = {
cancelable: false,
target: session,
type: "reconnecting",
hasBeenPrevented: false,
isDefaultPrevented: undefined,
preventDefault: undefined,
callDefaultBehavior: undefined,
};
this.testFeedService.pushNewEvent({ user: 0, event }); this.testFeedService.pushNewEvent({ user: 0, event });
}); });
session.on('reconnected', () => { session.on("reconnected", () => {
const event = { cancelable: false, target: session, type: 'reconnected', hasBeenPrevented: false, isDefaultPrevented: undefined, preventDefault: undefined, callDefaultBehavior: undefined }; const event = {
cancelable: false,
target: session,
type: "reconnected",
hasBeenPrevented: false,
isDefaultPrevented: undefined,
preventDefault: undefined,
callDefaultBehavior: undefined,
};
this.testFeedService.pushNewEvent({ user: 0, event }); this.testFeedService.pushNewEvent({ user: 0, event });
}); });
if (user.subscribeTo) { if (user.subscribeTo) {
session.on('streamCreated', (event: StreamEvent) => { session.on("streamCreated", (event: StreamEvent) => {
this.testFeedService.pushNewEvent({ user: 0, event }); this.testFeedService.pushNewEvent({ user: 0, event });
const subscriber = session.subscribe(event.stream, undefined); const subscriber = session.subscribe(event.stream, undefined);
const sub = this.subscribers.find(s => s.connectionId === session.connection.connectionId); const sub = this.subscribers.find(
(s) => s.connectionId === session.connection.connectionId
);
if (!sub) { if (!sub) {
this.subscribers.push({ this.subscribers.push({
connectionId: session.connection.connectionId, connectionId: session.connection.connectionId,
subs: [{ subs: [
startTime: startTimeForUser, {
connectionId: session.connection.connectionId, startTime: startTimeForUser,
streamManager: subscriber, connectionId: session.connection.connectionId,
state: { 'connected': (Date.now() - startTimeForUser) } streamManager: subscriber,
}] state: { connected: Date.now() - startTimeForUser },
},
],
}); });
} else { } else {
sub.subs.push({ sub.subs.push({
startTime: startTimeForUser, startTime: startTimeForUser,
connectionId: session.connection.connectionId, connectionId: session.connection.connectionId,
streamManager: subscriber, streamManager: subscriber,
state: { 'connected': (Date.now() - startTimeForUser) } state: { connected: Date.now() - startTimeForUser },
}); });
} }
subscriber.on('streamPlaying', (e: StreamManagerEvent) => { subscriber.on("streamPlaying", (e: StreamManagerEvent) => {
this.testFeedService.pushNewEvent({ user: 0, event: e }); this.testFeedService.pushNewEvent({ user: 0, event: e });
this.subscribers this.subscribers
.find(s => s.connectionId === session.connection.connectionId).subs .find((s) => s.connectionId === session.connection.connectionId)
.find(s => s.streamManager.stream.connection.connectionId === subscriber.stream.connection.connectionId) .subs.find(
.state['playing'] = (Date.now() - startTimeForUser); (s) =>
s.streamManager.stream.connection.connectionId ===
subscriber.stream.connection.connectionId
).state["playing"] = Date.now() - startTimeForUser;
}); });
}); });
} }
session.connect(token) session
.connect(token)
.then(() => { .then(() => {
if (user.publishTo) { if (user.publishTo) {
const publisher = OV.initPublisher(
const publisher = OV.initPublisher(undefined, this.publisherProperties); undefined,
this.publisherProperties
);
const publisherWrapper = { const publisherWrapper = {
startTime: startTimeForUser, startTime: startTimeForUser,
connectionId: session.connection.connectionId, connectionId: session.connection.connectionId,
streamManager: publisher, streamManager: publisher,
state: { 'connecting': (Date.now() - startTimeForUser) } state: { connecting: Date.now() - startTimeForUser },
}; };
publisher.on('streamCreated', event => { publisher.on("streamCreated", (event) => {
this.testFeedService.pushNewEvent({ user: 0, event }); this.testFeedService.pushNewEvent({ user: 0, event });
publisherWrapper.state['connected'] = (Date.now() - startTimeForUser); publisherWrapper.state["connected"] =
Date.now() - startTimeForUser;
}); });
publisher.on('streamPlaying', event => { publisher.on("streamPlaying", (event) => {
this.testFeedService.pushNewEvent({ user: 0, event }); this.testFeedService.pushNewEvent({ user: 0, event });
publisherWrapper.state['playing'] = (Date.now() - startTimeForUser); publisherWrapper.state["playing"] =
Date.now() - startTimeForUser;
}); });
session.publish(publisher).catch(() => { session.publish(publisher).catch(() => {
publisherWrapper.state['errorConnecting'] = (Date.now() - startTimeForUser); publisherWrapper.state["errorConnecting"] =
Date.now() - startTimeForUser;
}); });
this.publishers.push(publisherWrapper); this.publishers.push(publisherWrapper);
} }
}) })
.catch(); .catch();
@ -294,10 +337,11 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
if (!this.sessionProperties.customSessionId) { if (!this.sessionProperties.customSessionId) {
this.sessionProperties.customSessionId = this.fixedSessionId; this.sessionProperties.customSessionId = this.fixedSessionId;
} }
return this.OV_NodeClient.createSession(this.sessionProperties) return this.OV_NodeClient.createSession(this.sessionProperties).then(
.then(async (session_NodeClient) => { async (session_NodeClient) => {
return (await session_NodeClient.createConnection()).token; return (await session_NodeClient.createConnection()).token;
}); }
);
} }
openScenarioPropertiesDialog() { openScenarioPropertiesDialog() {
@ -305,13 +349,13 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
data: { data: {
publisherProperties: this.publisherProperties, publisherProperties: this.publisherProperties,
turnConf: this.turnConf, turnConf: this.turnConf,
manualTurnConf: this.manualTurnConf manualTurnConf: this.manualTurnConf,
}, },
width: '300px', width: "300px",
disableClose: true disableClose: true,
}); });
dialogRef.afterClosed().subscribe(result => { dialogRef.afterClosed().subscribe((result) => {
if (!!result) { if (!!result) {
this.publisherProperties = result.publisherProperties; this.publisherProperties = result.publisherProperties;
this.turnConf = result.turnConf; this.turnConf = result.turnConf;
@ -321,120 +365,139 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
} }
addReportForStream(event: StreamManagerWrapper) { addReportForStream(event: StreamManagerWrapper) {
event.streamManager.stream.getSelectedIceCandidate() // event.streamManager.stream.getSelectedIceCandidate()
.then(localCandidatePair => { // .then(localCandidatePair => {
// let newReport;
let newReport; // if (event.streamManager.remote) {
// newReport = {
if (event.streamManager.remote) { // connectionId: event.connectionId,
newReport = { // startTime: event.startTime,
connectionId: event.connectionId, // streamId: event.streamManager.stream.streamId,
startTime: event.startTime, // state: event.state,
streamId: event.streamManager.stream.streamId, // candidatePairSelectedByBrowser: {
state: event.state, // localCandidate: localCandidatePair.localCandidate,
candidatePairSelectedByBrowser: { // remoteCandidate: localCandidatePair.remoteCandidate
localCandidate: localCandidatePair.localCandidate, // },
remoteCandidate: localCandidatePair.remoteCandidate // candidatePairSelectedByKms: {
}, // localCandidate: {},
candidatePairSelectedByKms: { // remoteCandidate: {}
localCandidate: {}, // },
remoteCandidate: {} // iceCandidatesSentByBrowser:
}, // event.streamManager.stream.getLocalIceCandidateList().map((c: RTCIceCandidate) => c.candidate),
iceCandidatesSentByBrowser: // iceCandidatesReceivedByBrowser:
event.streamManager.stream.getLocalIceCandidateList().map((c: RTCIceCandidate) => c.candidate), // event.streamManager.stream.getRemoteIceCandidateList().map((c: RTCIceCandidate) => c.candidate),
iceCandidatesReceivedByBrowser: // };
event.streamManager.stream.getRemoteIceCandidateList().map((c: RTCIceCandidate) => c.candidate), // this.report.streamsIn.numberOfElements++;
}; // this.report.streamsIn.content.push(newReport);
// } else {
this.report.streamsIn.numberOfElements++; // newReport = {
this.report.streamsIn.content.push(newReport); // connectionId: event.connectionId,
} else { // startTime: event.startTime,
newReport = { // streamId: event.streamManager.stream.streamId,
connectionId: event.connectionId, // state: event.state,
startTime: event.startTime, // candidatePairSelectedByBrowser: {
streamId: event.streamManager.stream.streamId, // localCandidate: localCandidatePair.localCandidate,
state: event.state, // remoteCandidate: localCandidatePair.remoteCandidate
candidatePairSelectedByBrowser: { // },
localCandidate: localCandidatePair.localCandidate, // candidatePairSelectedByKms: {
remoteCandidate: localCandidatePair.remoteCandidate // localCandidate: {},
}, // remoteCandidate: {}
candidatePairSelectedByKms: { // },
localCandidate: {}, // iceCandidatesSentByBrowser:
remoteCandidate: {} // event.streamManager.stream.getLocalIceCandidateList().map((c: RTCIceCandidate) => c.candidate),
}, // iceCandidatesReceivedByBrowser:
iceCandidatesSentByBrowser: // event.streamManager.stream.getRemoteIceCandidateList().map((c: RTCIceCandidate) => c.candidate)
event.streamManager.stream.getLocalIceCandidateList().map((c: RTCIceCandidate) => c.candidate), // };
iceCandidatesReceivedByBrowser: // this.report.streamsOut.numberOfElements++;
event.streamManager.stream.getRemoteIceCandidateList().map((c: RTCIceCandidate) => c.candidate) // this.report.streamsOut.content.push(newReport);
}; // }
// if (++this.numberOfReports === this.totalNumberOfStreams) {
this.report.streamsOut.numberOfElements++; // this.updateRemoteStreamsInfo();
this.report.streamsOut.content.push(newReport); // }
} // })
// .catch();
if (++this.numberOfReports === this.totalNumberOfStreams) {
this.updateRemoteStreamsInfo();
}
})
.catch();
} }
private updateRemoteStreamsInfo() { private updateRemoteStreamsInfo() {
let headers = new HttpHeaders(); let headers = new HttpHeaders();
headers = headers.append('Authorization', 'Basic ' + btoa('OPENVIDUAPP:' + this.openviduSecret)); headers = headers.append(
this.http.get(this.openviduUrl + this.API_PATH + '/sessions/' + this.fixedSessionId + '?webRtcStats=true', { headers }).subscribe( "Authorization",
sessionInfo => { "Basic " + btoa("OPENVIDUAPP:" + this.openviduSecret)
this.report.streamsOut.content.forEach(report => {
const streamOutRemoteInfo = sessionInfo['connections'].content
.find(c => c.connectionId === report.connectionId).publishers
.find(p => {
report.webrtcEndpointName = p.webrtcEndpointName;
report.localSdp = p.localSdp;
report.remoteSdp = p.remoteSdp;
return p.webrtcEndpointName === report.streamId;
});
report.candidatePairSelectedByKms = {
localCandidate: this.parseRemoteCandidatePair(streamOutRemoteInfo.localCandidate),
remoteCandidate: this.parseRemoteCandidatePair(streamOutRemoteInfo.remoteCandidate)
};
report.serverEvents = streamOutRemoteInfo.events;
for (const ev of report.serverEvents) {
ev.timestamp = Number(ev.timestamp) - report.startTime;
}
});
this.report.streamsIn.content.forEach(report => {
const streamInRemoteInfo = sessionInfo['connections'].content
.find(c => c.connectionId === report.connectionId).subscribers
.find(p => {
report.webrtcEndpointName = p.webrtcEndpointName;
report.localSdp = p.localSdp;
report.remoteSdp = p.remoteSdp;
return p.webrtcEndpointName === report.connectionId + '_' + report.streamId;
});
report.candidatePairSelectedByKms = {
localCandidate: this.parseRemoteCandidatePair(streamInRemoteInfo.localCandidate),
remoteCandidate: this.parseRemoteCandidatePair(streamInRemoteInfo.remoteCandidate)
};
report.serverEvents = streamInRemoteInfo.events;
for (const ev of report.serverEvents) {
ev.timestamp = Number(ev.timestamp) - report.startTime;
}
});
this.stringifyAllReports = JSON.stringify(this.report, null, '\t');
console.log('Info has changed: ' + !(this.stringifyAllReports === this.textAreaValue));
this.textAreaValue = this.stringifyAllReports;
},
error => { }
); );
this.http
.get(
this.openviduUrl +
this.API_PATH +
"/sessions/" +
this.fixedSessionId +
"?webRtcStats=true",
{ headers }
)
.subscribe(
(sessionInfo) => {
this.report.streamsOut.content.forEach((report) => {
const streamOutRemoteInfo = sessionInfo["connections"].content
.find((c) => c.connectionId === report.connectionId)
.publishers.find((p) => {
report.webrtcEndpointName = p.webrtcEndpointName;
report.localSdp = p.localSdp;
report.remoteSdp = p.remoteSdp;
return p.webrtcEndpointName === report.streamId;
});
report.candidatePairSelectedByKms = {
localCandidate: this.parseRemoteCandidatePair(
streamOutRemoteInfo.localCandidate
),
remoteCandidate: this.parseRemoteCandidatePair(
streamOutRemoteInfo.remoteCandidate
),
};
report.serverEvents = streamOutRemoteInfo.events;
for (const ev of report.serverEvents) {
ev.timestamp = Number(ev.timestamp) - report.startTime;
}
});
this.report.streamsIn.content.forEach((report) => {
const streamInRemoteInfo = sessionInfo["connections"].content
.find((c) => c.connectionId === report.connectionId)
.subscribers.find((p) => {
report.webrtcEndpointName = p.webrtcEndpointName;
report.localSdp = p.localSdp;
report.remoteSdp = p.remoteSdp;
return (
p.webrtcEndpointName ===
report.connectionId + "_" + report.streamId
);
});
report.candidatePairSelectedByKms = {
localCandidate: this.parseRemoteCandidatePair(
streamInRemoteInfo.localCandidate
),
remoteCandidate: this.parseRemoteCandidatePair(
streamInRemoteInfo.remoteCandidate
),
};
report.serverEvents = streamInRemoteInfo.events;
for (const ev of report.serverEvents) {
ev.timestamp = Number(ev.timestamp) - report.startTime;
}
});
this.stringifyAllReports = JSON.stringify(this.report, null, "\t");
console.log(
"Info has changed: " +
!(this.stringifyAllReports === this.textAreaValue)
);
this.textAreaValue = this.stringifyAllReports;
},
(error) => {}
);
} }
private parseRemoteCandidatePair(candidateStr: string) { private parseRemoteCandidatePair(candidateStr: string) {
if (!candidateStr) { if (!candidateStr) {
return 'ERROR: No remote candidate available'; return "ERROR: No remote candidate available";
} }
const array = candidateStr.split(/\s+/); const array = candidateStr.split(/\s+/);
return { return {
@ -443,18 +506,25 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
transport: array[2].toLowerCase(), transport: array[2].toLowerCase(),
candidateType: array[7], candidateType: array[7],
priority: array[3], priority: array[3],
raw: candidateStr raw: candidateStr,
}; };
} }
focusOnReportForStream(event) { focusOnReportForStream(event) {
this.isFocusedOnReport = true; this.isFocusedOnReport = true;
let jsonObject = !!event.in ? this.report.streamsIn : this.report.streamsOut; let jsonObject = !!event.in
jsonObject = jsonObject.content.find(stream => { ? this.report.streamsIn
const webrtcEndpointName = !!event.in ? event.connectionId + '_' + event.streamId : event.streamId; : this.report.streamsOut;
return (stream.connectionId === event.connectionId && stream.webrtcEndpointName === webrtcEndpointName); jsonObject = jsonObject.content.find((stream) => {
const webrtcEndpointName = !!event.in
? event.connectionId + "_" + event.streamId
: event.streamId;
return (
stream.connectionId === event.connectionId &&
stream.webrtcEndpointName === webrtcEndpointName
);
}); });
this.textAreaValue = JSON.stringify(jsonObject, null, '\t'); this.textAreaValue = JSON.stringify(jsonObject, null, "\t");
} }
/*addReportForStreamConcurrent(event: StreamManagerWrapper) { /*addReportForStreamConcurrent(event: StreamManagerWrapper) {
@ -517,5 +587,4 @@ export class TestScenariosComponent implements OnInit, OnDestroy {
error => { } error => { }
); );
}*/ }*/
} }

View File

@ -9,7 +9,7 @@ import { StreamManager } from 'openvidu-browser-v2compatibility';
*ngIf="!success() && !fail()" [diameter]="24"> *ngIf="!success() && !fail()" [diameter]="24">
</mat-spinner> </mat-spinner>
<mat-icon [color]="'warn'" *ngIf="success() || fail()" <mat-icon [color]="'warn'" *ngIf="success() || fail()"
matTooltip aria-label="Select report" (click)="emitClickIconEvent($event)">{{success() ? 'done' : 'warning'}}</mat-icon> matTooltip aria-label="Select report" (click)="emitClickIconEvent($event)" [attr.data-status]="success() ? 'success' : 'waiting'">{{success() ? 'done' : 'warning'}}</mat-icon>
</div> </div>
<app-ov-video [streamManager]="streamManager.streamManager" <app-ov-video [streamManager]="streamManager.streamManager"
[attrstyle]="'width: 120px; height: initial'"> [attrstyle]="'width: 120px; height: initial'">
@ -39,7 +39,7 @@ export class TableVideoComponent implements AfterViewInit, DoCheck {
streamManager: this.streamManager.streamManager streamManager: this.streamManager.streamManager
}); });
} }
}, 10000); }, 18000);
} }
ngDoCheck() { ngDoCheck() {