mirror of https://github.com/OpenVidu/openvidu.git
openvidu-node-client: advanced Subscriber with webrtc props support
parent
e30b365f1d
commit
dd0016671e
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Connection } from './Connection';
|
import { Connection } from './Connection';
|
||||||
|
import { Publisher } from './Publisher';
|
||||||
import { Recording } from './Recording';
|
import { Recording } from './Recording';
|
||||||
import { RecordingProperties } from './RecordingProperties';
|
import { RecordingProperties } from './RecordingProperties';
|
||||||
import { Session } from './Session';
|
import { Session } from './Session';
|
||||||
|
@ -482,22 +483,26 @@ export class OpenVidu {
|
||||||
const addWebRtcStatsToConnections = (connection: Connection, connectionsExtendedInfo: any) => {
|
const addWebRtcStatsToConnections = (connection: Connection, connectionsExtendedInfo: any) => {
|
||||||
const connectionExtended = connectionsExtendedInfo.find(c => c.connectionId === connection.connectionId);
|
const connectionExtended = connectionsExtendedInfo.find(c => c.connectionId === connection.connectionId);
|
||||||
if (!!connectionExtended) {
|
if (!!connectionExtended) {
|
||||||
connection['publishersWebRtc'] = [];
|
const publisherArray = [];
|
||||||
connection.publishers.forEach(pub => {
|
connection.publishers.forEach(pub => {
|
||||||
const publisherExtended = connectionExtended.publishers.find(p => p.streamId === pub.streamId);
|
const publisherExtended = connectionExtended.publishers.find(p => p.streamId === pub.streamId);
|
||||||
const pubAux = {};
|
const pubAux = {};
|
||||||
// Standard properties
|
// Standard properties
|
||||||
pubAux['streamId'] = pub.streamId;
|
pubAux['streamId'] = pub.streamId;
|
||||||
pubAux['createdAt'] = pub.createdAt;
|
pubAux['createdAt'] = pub.createdAt;
|
||||||
pubAux['audioActive'] = pub.audioActive;
|
const mediaOptions = {
|
||||||
pubAux['videoActive'] = pub.videoActive;
|
audioActive: pub.audioActive,
|
||||||
pubAux['hasAudio'] = pub.hasAudio;
|
videoActive: pub.videoActive,
|
||||||
pubAux['hasVideo'] = pub.hasVideo;
|
hasAudio: pub.hasAudio,
|
||||||
pubAux['typeOfVideo'] = pub.typeOfVideo;
|
hasVideo: pub.hasVideo,
|
||||||
pubAux['frameRate'] = pub.frameRate;
|
typeOfVideo: pub.typeOfVideo,
|
||||||
pubAux['videoDimensions'] = pub.videoDimensions;
|
frameRate: pub.frameRate,
|
||||||
|
videoDimensions: pub.videoDimensions
|
||||||
|
};
|
||||||
|
pubAux['mediaOptions'] = mediaOptions;
|
||||||
|
const newPublisher = new Publisher(pubAux);
|
||||||
// WebRtc properties
|
// WebRtc properties
|
||||||
pubAux['webRtc'] = {
|
newPublisher['webRtc'] = {
|
||||||
kms: {
|
kms: {
|
||||||
events: publisherExtended.events,
|
events: publisherExtended.events,
|
||||||
localCandidate: publisherExtended.localCandidate,
|
localCandidate: publisherExtended.localCandidate,
|
||||||
|
@ -506,12 +511,13 @@ export class OpenVidu {
|
||||||
webrtcTagName: publisherExtended.webrtcTagName
|
webrtcTagName: publisherExtended.webrtcTagName
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
newPublisher['localCandidatePair'] = parseRemoteCandidatePair(newPublisher['webRtc'].kms.remoteCandidate);
|
||||||
if (!!publisherExtended.serverStats) {
|
if (!!publisherExtended.serverStats) {
|
||||||
pubAux['webRtc'].kms.serverStats = publisherExtended.serverStats;
|
newPublisher['webRtc'].kms.serverStats = publisherExtended.serverStats;
|
||||||
}
|
}
|
||||||
connection['publishersWebRtc'].push(pubAux);
|
publisherArray.push(newPublisher);
|
||||||
});
|
});
|
||||||
connection['subscribersWebRtc'] = [];
|
const subscriberArray = [];
|
||||||
connection.subscribers.forEach(sub => {
|
connection.subscribers.forEach(sub => {
|
||||||
const subscriberExtended = connectionExtended.subscribers.find(s => s.streamId === sub);
|
const subscriberExtended = connectionExtended.subscribers.find(s => s.streamId === sub);
|
||||||
const subAux = {};
|
const subAux = {};
|
||||||
|
@ -529,14 +535,32 @@ export class OpenVidu {
|
||||||
webrtcTagName: subscriberExtended.webrtcTagName
|
webrtcTagName: subscriberExtended.webrtcTagName
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
subAux['localCandidatePair'] = parseRemoteCandidatePair(subAux['webRtc'].kms.remoteCandidate);
|
||||||
if (!!subscriberExtended.serverStats) {
|
if (!!subscriberExtended.serverStats) {
|
||||||
subAux['webRtc'].kms.serverStats = subscriberExtended.serverStats;
|
subAux['webRtc'].kms.serverStats = subscriberExtended.serverStats;
|
||||||
}
|
}
|
||||||
connection['subscribersWebRtc'].push(subAux);
|
subscriberArray.push(subAux);
|
||||||
});
|
});
|
||||||
|
connection.publishers = publisherArray;
|
||||||
|
connection.subscribers = subscriberArray;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const parseRemoteCandidatePair = (candidateStr: string) => {
|
||||||
|
if (!candidateStr) {
|
||||||
|
return 'ERROR: No remote candidate available';
|
||||||
|
}
|
||||||
|
const array = candidateStr.split(/\s+/);
|
||||||
|
return {
|
||||||
|
portNumber: array[5],
|
||||||
|
ipAddress: array[4],
|
||||||
|
transport: array[2].toLowerCase(),
|
||||||
|
candidateType: array[7],
|
||||||
|
priority: array[3],
|
||||||
|
raw: candidateStr
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
return new Promise<boolean>((resolve, reject) => {
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
axios.get(
|
axios.get(
|
||||||
'https://' + OpenVidu.hostname + ':' + OpenVidu.port + OpenVidu.API_SESSIONS + '?webRtcStats=true',
|
'https://' + OpenVidu.hostname + ':' + OpenVidu.port + OpenVidu.API_SESSIONS + '?webRtcStats=true',
|
||||||
|
@ -567,20 +591,19 @@ export class OpenVidu {
|
||||||
});
|
});
|
||||||
if (!!storedSession) {
|
if (!!storedSession) {
|
||||||
const fetchedSession: Session = new Session().resetSessionWithJson(session);
|
const fetchedSession: Session = new Session().resetSessionWithJson(session);
|
||||||
let changed = !storedSession.equalTo(fetchedSession);
|
fetchedSession.activeConnections.forEach(connection => {
|
||||||
fetchedSession.activeConnections.forEach((connection, index1) => {
|
|
||||||
addWebRtcStatsToConnections(connection, session.connections.content);
|
addWebRtcStatsToConnections(connection, session.connections.content);
|
||||||
if (!changed) { // Check if server webrtc information has changed in any Publisher/Subscriber
|
|
||||||
for (let index2 = 0; (index2 < connection['publishersWebRtc'].length && !changed); index2++) {
|
|
||||||
changed = changed || JSON.stringify(connection['publishersWebRtc'][index2]['webRtc']) !== JSON.stringify(storedSession.activeConnections[index1]['publishersWebRtc'][index2]['webRtc']);
|
|
||||||
}
|
|
||||||
if (!changed) {
|
|
||||||
for (let index2 = 0; (index2 < connection['subscribersWebRtc'].length && !changed); index2++) {
|
|
||||||
changed = changed || JSON.stringify(connection['subscribersWebRtc'][index2]['webRtc']) !== JSON.stringify(storedSession.activeConnections[index1]['subscribersWebRtc'][index2]['webRtc']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let changed = !storedSession.equalTo(fetchedSession);
|
||||||
|
if (!changed) { // Check if server webrtc information has changed in any Publisher object (Session.equalTo does not check Publisher.webRtc auxiliary object)
|
||||||
|
fetchedSession.activeConnections.forEach((connection, index1) => {
|
||||||
|
for (let index2 = 0; (index2 < connection['publishers'].length && !changed); index2++) {
|
||||||
|
changed = changed || JSON.stringify(connection['publishers'][index2]['webRtc']) !== JSON.stringify(storedSession.activeConnections[index1]['publishers'][index2]['webRtc']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
storedSession = fetchedSession;
|
storedSession = fetchedSession;
|
||||||
this.activeSessions[sessionIndex] = storedSession;
|
this.activeSessions[sessionIndex] = storedSession;
|
||||||
|
|
|
@ -274,7 +274,17 @@ export class Session {
|
||||||
if (!!connectionClosed) {
|
if (!!connectionClosed) {
|
||||||
connectionClosed.publishers.forEach(publisher => {
|
connectionClosed.publishers.forEach(publisher => {
|
||||||
this.activeConnections.forEach(con => {
|
this.activeConnections.forEach(con => {
|
||||||
con.subscribers = con.subscribers.filter(subscriber => subscriber !== publisher.streamId);
|
con.subscribers = con.subscribers.filter(subscriber => {
|
||||||
|
// tslint:disable:no-string-literal
|
||||||
|
if (!!subscriber['streamId']) {
|
||||||
|
// Subscriber with advanced webRtc configuration properties
|
||||||
|
return (subscriber['streamId'] !== publisher.streamId);
|
||||||
|
// tslint:enable:no-string-literal
|
||||||
|
} else {
|
||||||
|
// Regular string subscribers
|
||||||
|
return subscriber !== publisher.streamId;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -334,7 +344,17 @@ export class Session {
|
||||||
// Try to remove the Publisher from the Connection publishers collection
|
// Try to remove the Publisher from the Connection publishers collection
|
||||||
connection.publishers = connection.publishers.filter(pub => pub.streamId !== streamId);
|
connection.publishers = connection.publishers.filter(pub => pub.streamId !== streamId);
|
||||||
// Try to remove the Publisher from the Connection subscribers collection
|
// Try to remove the Publisher from the Connection subscribers collection
|
||||||
connection.subscribers = connection.subscribers.filter(sub => sub !== streamId);
|
if (!!connection.subscribers && connection.subscribers.length > 0) {
|
||||||
|
// tslint:disable:no-string-literal
|
||||||
|
if (!!connection.subscribers[0]['streamId']) {
|
||||||
|
// Subscriber with advanced webRtc configuration properties
|
||||||
|
connection.subscribers = connection.subscribers.filter(sub => sub['streamId'] !== streamId);
|
||||||
|
// tslint:enable:no-string-literal
|
||||||
|
} else {
|
||||||
|
// Regular string subscribers
|
||||||
|
connection.subscribers = connection.subscribers.filter(sub => sub !== streamId);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
console.log("Stream '" + streamId + "' unpublished");
|
console.log("Stream '" + streamId + "' unpublished");
|
||||||
resolve();
|
resolve();
|
||||||
|
|
Loading…
Reference in New Issue