mirror of https://github.com/OpenVidu/openvidu.git
Stream start speaking and stop speaking events
parent
06a2725da8
commit
7e47f19c3c
|
@ -124,7 +124,7 @@ export class Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsubscribe(subscriber: Subscriber) {
|
unsubscribe(subscriber: Subscriber) {
|
||||||
this.session.unsuscribe(subscriber.stream);
|
this.session.unsubscribe(subscriber.stream);
|
||||||
subscriber.stream.removeVideo();
|
subscriber.stream.removeVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,8 @@ export class Connection {
|
||||||
}
|
}
|
||||||
|
|
||||||
addStream( stream: Stream ) {
|
addStream( stream: Stream ) {
|
||||||
this.streams[stream.getIdInParticipant()] = stream;
|
this.streams[stream.streamId] = stream;
|
||||||
this.room.getStreams()[stream.getIdInParticipant()] = stream;
|
this.room.getStreams()[stream.streamId] = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
getStreams() {
|
getStreams() {
|
||||||
|
@ -79,6 +79,7 @@ export class Connection {
|
||||||
sendVideo: streamOptions.sendVideo,
|
sendVideo: streamOptions.sendVideo,
|
||||||
recvAudio: ( streamOptions.audioActive == undefined ? true : streamOptions.audioActive ),
|
recvAudio: ( streamOptions.audioActive == undefined ? true : streamOptions.audioActive ),
|
||||||
recvVideo: ( streamOptions.videoActive == undefined ? true : streamOptions.videoActive ),
|
recvVideo: ( streamOptions.videoActive == undefined ? true : streamOptions.videoActive ),
|
||||||
|
typeOfVideo: streamOptions.typeOfVideo,
|
||||||
activeAudio: streamOptions.activeAudio,
|
activeAudio: streamOptions.activeAudio,
|
||||||
activeVideo: streamOptions.activeVideo,
|
activeVideo: streamOptions.activeVideo,
|
||||||
data: streamOptions.data,
|
data: streamOptions.data,
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class SessionInternal {
|
||||||
private ee = new EventEmitter();
|
private ee = new EventEmitter();
|
||||||
private streams = {};
|
private streams = {};
|
||||||
private participants = {};
|
private participants = {};
|
||||||
private participantsSpeaking: Connection[] = [];
|
private publishersSpeaking: Connection[] = [];
|
||||||
private connected = false;
|
private connected = false;
|
||||||
public localParticipant: Connection;
|
public localParticipant: Connection;
|
||||||
private subscribeToStreams: boolean;
|
private subscribeToStreams: boolean;
|
||||||
|
@ -206,13 +206,13 @@ export class SessionInternal {
|
||||||
|
|
||||||
private activateUpdateMainSpeaker() {
|
private activateUpdateMainSpeaker() {
|
||||||
|
|
||||||
setInterval(() => {
|
/*setInterval(() => {
|
||||||
if (this.participantsSpeaking.length > 0) {
|
if (this.publishersSpeaking.length > 0) {
|
||||||
this.ee.emitEvent('update-main-speaker', [{
|
this.ee.emitEvent('publisherStartSpeaking', [{
|
||||||
participantId: this.participantsSpeaking[this.participantsSpeaking.length - 1]
|
participantId: this.publishersSpeaking[this.publishersSpeaking.length - 1]
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
}, this.updateSpeakerInterval);
|
}, this.updateSpeakerInterval);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
getLocalParticipant() {
|
getLocalParticipant() {
|
||||||
|
@ -244,16 +244,16 @@ export class SessionInternal {
|
||||||
stream.subscribe();
|
stream.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsuscribe(stream) {
|
unsubscribe(stream) {
|
||||||
console.info("Unsubscribing from " + stream.getId());
|
console.info("Unsubscribing from " + stream.streamId);
|
||||||
this.openVidu.sendRequest('unsubscribeFromVideo', {
|
this.openVidu.sendRequest('unsubscribeFromVideo', {
|
||||||
sender: stream.getId()
|
sender: stream.streamId
|
||||||
},
|
},
|
||||||
function (error, response) {
|
function (error, response) {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error("Error unsubscribing from Subscriber", error);
|
console.error("Error unsubscribing from Subscriber", error);
|
||||||
} else {
|
} else {
|
||||||
console.info("Unsubscribed correctly from " + stream.getId());
|
console.info("Unsubscribed correctly from " + stream.streamId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -512,7 +512,7 @@ export class SessionInternal {
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.unsuscribe(stream);
|
this.unsubscribe(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,19 +546,25 @@ export class SessionInternal {
|
||||||
}
|
}
|
||||||
|
|
||||||
addParticipantSpeaking(participantId) {
|
addParticipantSpeaking(participantId) {
|
||||||
this.participantsSpeaking.push(participantId);
|
this.publishersSpeaking.push(participantId);
|
||||||
|
this.ee.emitEvent('publisherStartSpeaking', [{
|
||||||
|
participantId: participantId
|
||||||
|
}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeParticipantSpeaking(participantId) {
|
removeParticipantSpeaking(participantId) {
|
||||||
let pos = -1;
|
let pos = -1;
|
||||||
for (let i = 0; i < this.participantsSpeaking.length; i++) {
|
for (let i = 0; i < this.publishersSpeaking.length; i++) {
|
||||||
if (this.participantsSpeaking[i] == participantId) {
|
if (this.publishersSpeaking[i] == participantId) {
|
||||||
pos = i;
|
pos = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos != -1) {
|
if (pos != -1) {
|
||||||
this.participantsSpeaking.splice(pos, 1);
|
this.publishersSpeaking.splice(pos, 1);
|
||||||
|
this.ee.emitEvent('publisherStopSpeaking', [{
|
||||||
|
participantId: participantId
|
||||||
|
}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,11 +53,14 @@ export interface VideoOptions {
|
||||||
export class Stream {
|
export class Stream {
|
||||||
|
|
||||||
public connection: Connection;
|
public connection: Connection;
|
||||||
|
public streamId: string;
|
||||||
|
public hasVideo: boolean;
|
||||||
|
public hasAudio: boolean;
|
||||||
|
public typeOfVideo: string; // 'CAMERA' or 'SCREEN'
|
||||||
|
|
||||||
ee = new EventEmitter();
|
ee = new EventEmitter();
|
||||||
private wrStream: MediaStream;
|
private wrStream: MediaStream;
|
||||||
private wp: any;
|
private wp: any;
|
||||||
private id: string;
|
|
||||||
private video: HTMLVideoElement;
|
private video: HTMLVideoElement;
|
||||||
private videoElements: VideoOptions[] = [];
|
private videoElements: VideoOptions[] = [];
|
||||||
private elements: HTMLDivElement[] = [];
|
private elements: HTMLDivElement[] = [];
|
||||||
|
@ -96,7 +99,7 @@ export class Stream {
|
||||||
this.addEventListener('src-added', (srcEvent) => {
|
this.addEventListener('src-added', (srcEvent) => {
|
||||||
this.videoSrcObject = srcEvent.srcObject;
|
this.videoSrcObject = srcEvent.srcObject;
|
||||||
if (this.video) this.video.srcObject = srcEvent.srcObject;
|
if (this.video) this.video.srcObject = srcEvent.srcObject;
|
||||||
console.debug("Video srcObject [" + srcEvent.srcObject + "] added to stream [" + this.getId() + "]");
|
console.debug("Video srcObject [" + srcEvent.srcObject + "] added to stream [" + this.streamId + "]");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,11 +142,6 @@ export class Stream {
|
||||||
this.video = video;
|
this.video = video;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getRecvVideo() {
|
getRecvVideo() {
|
||||||
return this.recvVideo;
|
return this.recvVideo;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +181,7 @@ export class Stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
getChannelName() {
|
getChannelName() {
|
||||||
return this.getId() + '_' + this.chanId++;
|
return this.streamId + '_' + this.chanId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,7 +237,7 @@ export class Stream {
|
||||||
|
|
||||||
showSpinner(spinnerParentId: string) {
|
showSpinner(spinnerParentId: string) {
|
||||||
let progress = document.createElement('div');
|
let progress = document.createElement('div');
|
||||||
progress.id = 'progress-' + this.getId();
|
progress.id = 'progress-' + this.streamId;
|
||||||
progress.style.background = "center transparent url('img/spinner.gif') no-repeat";
|
progress.style.background = "center transparent url('img/spinner.gif') no-repeat";
|
||||||
let spinnerParent = document.getElementById(spinnerParentId);
|
let spinnerParent = document.getElementById(spinnerParentId);
|
||||||
if (spinnerParent) {
|
if (spinnerParent) {
|
||||||
|
@ -248,7 +246,7 @@ export class Stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
hideSpinner(spinnerId?: string) {
|
hideSpinner(spinnerId?: string) {
|
||||||
spinnerId = (spinnerId === undefined) ? this.getId() : spinnerId;
|
spinnerId = (spinnerId === undefined) ? this.streamId : spinnerId;
|
||||||
hide('progress-' + spinnerId);
|
hide('progress-' + spinnerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +254,7 @@ export class Stream {
|
||||||
|
|
||||||
this.video = document.createElement('video');
|
this.video = document.createElement('video');
|
||||||
|
|
||||||
this.video.id = (this.local ? 'local-' : 'remote-') + 'video-' + this.getId();
|
this.video.id = (this.local ? 'local-' : 'remote-') + 'video-' + this.streamId;
|
||||||
this.video.autoplay = true;
|
this.video.autoplay = true;
|
||||||
this.video.controls = false;
|
this.video.controls = false;
|
||||||
this.video.srcObject = this.videoSrcObject;
|
this.video.srcObject = this.videoSrcObject;
|
||||||
|
@ -269,13 +267,13 @@ export class Stream {
|
||||||
if (this.local && !this.displayMyRemote()) {
|
if (this.local && !this.displayMyRemote()) {
|
||||||
this.video.muted = true;
|
this.video.muted = true;
|
||||||
this.video.oncanplay = () => {
|
this.video.oncanplay = () => {
|
||||||
console.info("Local 'Stream' with id [" + this.getId() + "] video is now playing");
|
console.info("Local 'Stream' with id [" + this.streamId + "] video is now playing");
|
||||||
this.ee.emitEvent('video-is-playing', [{
|
this.ee.emitEvent('video-is-playing', [{
|
||||||
element: this.video
|
element: this.video
|
||||||
}]);
|
}]);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this.video.title = this.getId();
|
this.video.title = this.streamId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof parentElement === "string") {
|
if (typeof parentElement === "string") {
|
||||||
|
@ -303,7 +301,7 @@ export class Stream {
|
||||||
|
|
||||||
let container = document.createElement('div');
|
let container = document.createElement('div');
|
||||||
container.className = "participant";
|
container.className = "participant";
|
||||||
container.id = this.getId();
|
container.id = this.streamId;
|
||||||
let thumbnail = document.getElementById(thumbnailId);
|
let thumbnail = document.getElementById(thumbnailId);
|
||||||
if (thumbnail) {
|
if (thumbnail) {
|
||||||
thumbnail.appendChild(container);
|
thumbnail.appendChild(container);
|
||||||
|
@ -313,32 +311,24 @@ export class Stream {
|
||||||
|
|
||||||
let name = document.createElement('div');
|
let name = document.createElement('div');
|
||||||
container.appendChild(name);
|
container.appendChild(name);
|
||||||
let userName = this.getId().replace('_webcam', '');
|
let userName = this.streamId.replace('_webcam', '');
|
||||||
if (userName.length >= 16) {
|
if (userName.length >= 16) {
|
||||||
userName = userName.substring(0, 16) + "...";
|
userName = userName.substring(0, 16) + "...";
|
||||||
}
|
}
|
||||||
name.appendChild(document.createTextNode(userName));
|
name.appendChild(document.createTextNode(userName));
|
||||||
name.id = "name-" + this.getId();
|
name.id = "name-" + this.streamId;
|
||||||
name.className = "name";
|
name.className = "name";
|
||||||
name.title = this.getId();
|
name.title = this.streamId;
|
||||||
|
|
||||||
this.showSpinner(thumbnailId);
|
this.showSpinner(thumbnailId);
|
||||||
|
|
||||||
return this.playOnlyVideo(container, thumbnailId);
|
return this.playOnlyVideo(container, thumbnailId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getIdInParticipant() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
getParticipant() {
|
getParticipant() {
|
||||||
return this.connection;
|
return this.connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
getId() {
|
|
||||||
return this.connection.connectionId + "_" + this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
getRTCPeerConnection() {
|
getRTCPeerConnection() {
|
||||||
return this.getWebRtcPeer().peerConnection;
|
return this.getWebRtcPeer().peerConnection;
|
||||||
}
|
}
|
||||||
|
@ -440,13 +430,14 @@ export class Stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.debug("Sending SDP offer to publish as "
|
console.debug("Sending SDP offer to publish as "
|
||||||
+ this.getId(), sdpOfferParam);
|
+ this.streamId, sdpOfferParam);
|
||||||
|
|
||||||
this.openVidu.sendRequest("publishVideo", {
|
this.openVidu.sendRequest("publishVideo", {
|
||||||
sdpOffer: sdpOfferParam,
|
sdpOffer: sdpOfferParam,
|
||||||
doLoopback: this.displayMyRemote() || false,
|
doLoopback: this.displayMyRemote() || false,
|
||||||
audioActive: this.sendAudio,
|
audioActive: this.sendAudio,
|
||||||
videoActive: this.sendVideo
|
videoActive: this.sendVideo,
|
||||||
|
typeOfVideo: ((this.sendVideo) ? ((this.isScreenRequested) ? 'SCREEN' :'CAMERA') : '')
|
||||||
}, (error, response) => {
|
}, (error, response) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error("Error on publishVideo: " + JSON.stringify(error));
|
console.error("Error on publishVideo: " + JSON.stringify(error));
|
||||||
|
@ -463,9 +454,9 @@ export class Stream {
|
||||||
+ JSON.stringify(error));
|
+ JSON.stringify(error));
|
||||||
}
|
}
|
||||||
console.debug("Sending SDP offer to subscribe to "
|
console.debug("Sending SDP offer to subscribe to "
|
||||||
+ this.getId(), sdpOfferParam);
|
+ this.streamId, sdpOfferParam);
|
||||||
this.openVidu.sendRequest("receiveVideoFrom", {
|
this.openVidu.sendRequest("receiveVideoFrom", {
|
||||||
sender: this.getId(),
|
sender: this.streamId,
|
||||||
sdpOffer: sdpOfferParam
|
sdpOffer: sdpOfferParam
|
||||||
}, (error, response) => {
|
}, (error, response) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -535,7 +526,7 @@ export class Stream {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.debug("Waiting for SDP offer to be generated ("
|
console.debug("Waiting for SDP offer to be generated ("
|
||||||
+ (this.local ? "local" : "remote") + " 'Stream': " + this.getId() + ")");
|
+ (this.local ? "local" : "remote") + " 'Stream': " + this.streamId + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
publish() {
|
publish() {
|
||||||
|
@ -570,9 +561,9 @@ export class Stream {
|
||||||
type: 'answer',
|
type: 'answer',
|
||||||
sdp: sdpAnswer,
|
sdp: sdpAnswer,
|
||||||
});
|
});
|
||||||
console.debug(this.getId() + ": set peer connection with recvd SDP answer",
|
console.debug(this.streamId + ": set peer connection with recvd SDP answer",
|
||||||
sdpAnswer);
|
sdpAnswer);
|
||||||
let participantId = this.getId();
|
let participantId = this.streamId;
|
||||||
let pc = this.wp.peerConnection;
|
let pc = this.wp.peerConnection;
|
||||||
pc.setRemoteDescription(answer, () => {
|
pc.setRemoteDescription(answer, () => {
|
||||||
// Avoids to subscribe to your own stream remotely
|
// Avoids to subscribe to your own stream remotely
|
||||||
|
@ -590,16 +581,18 @@ export class Stream {
|
||||||
this.speechEvent = kurentoUtils.WebRtcPeer.hark(this.wrStream, { threshold: this.room.thresholdSpeaker });
|
this.speechEvent = kurentoUtils.WebRtcPeer.hark(this.wrStream, { threshold: this.room.thresholdSpeaker });
|
||||||
|
|
||||||
this.speechEvent.on('speaking', () => {
|
this.speechEvent.on('speaking', () => {
|
||||||
this.room.addParticipantSpeaking(participantId);
|
//this.room.addParticipantSpeaking(participantId);
|
||||||
this.room.emitEvent('stream-speaking', [{
|
this.room.emitEvent('publisherStartSpeaking', [{
|
||||||
participantId: participantId
|
connection: this.connection,
|
||||||
|
streamId: this.streamId
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.speechEvent.on('stopped_speaking', () => {
|
this.speechEvent.on('stopped_speaking', () => {
|
||||||
this.room.removeParticipantSpeaking(participantId);
|
//this.room.removeParticipantSpeaking(participantId);
|
||||||
this.room.emitEvent('stream-stopped-speaking', [{
|
this.room.emitEvent('publisherStopSpeaking', [{
|
||||||
participantId: participantId
|
connection: this.connection,
|
||||||
|
streamId: this.streamId
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -611,18 +604,18 @@ export class Stream {
|
||||||
video.srcObject = this.wrStream;
|
video.srcObject = this.wrStream;
|
||||||
video.oncanplay = () => {
|
video.oncanplay = () => {
|
||||||
if (this.local && this.displayMyRemote()) {
|
if (this.local && this.displayMyRemote()) {
|
||||||
console.info("Your own remote 'Stream' with id [" + this.getId() + "] video is now playing");
|
console.info("Your own remote 'Stream' with id [" + this.streamId + "] video is now playing");
|
||||||
this.ee.emitEvent('remote-video-is-playing', [{
|
this.ee.emitEvent('remote-video-is-playing', [{
|
||||||
element: video
|
element: video
|
||||||
}]);
|
}]);
|
||||||
} else if (!this.local && !this.displayMyRemote()) {
|
} else if (!this.local && !this.displayMyRemote()) {
|
||||||
console.info("Remote 'Stream' with id [" + this.getId() + "] video is now playing");
|
console.info("Remote 'Stream' with id [" + this.streamId + "] video is now playing");
|
||||||
this.ee.emitEvent('video-is-playing', [{
|
this.ee.emitEvent('video-is-playing', [{
|
||||||
element: video
|
element: video
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
//show(thumbnailId);
|
//show(thumbnailId);
|
||||||
//this.hideSpinner(this.getId());
|
//this.hideSpinner(this.streamId);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.room.emitEvent('stream-subscribed', [{
|
this.room.emitEvent('stream-subscribed', [{
|
||||||
|
@ -630,7 +623,7 @@ export class Stream {
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
}, error => {
|
}, error => {
|
||||||
console.error(this.getId() + ": Error setting SDP to the peer connection: "
|
console.error(this.streamId + ": Error setting SDP to the peer connection: "
|
||||||
+ JSON.stringify(error));
|
+ JSON.stringify(error));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -653,7 +646,7 @@ export class Stream {
|
||||||
this.speechEvent.stop();
|
this.speechEvent.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info(this.getId() + ": Stream '" + this.id + "' unpublished");
|
console.info(this.streamId + ": Stream '" + this.streamId + "' unpublished");
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose() {
|
dispose() {
|
||||||
|
@ -668,7 +661,7 @@ export class Stream {
|
||||||
|
|
||||||
//this.videoElements.forEach(ve => disposeElement(ve.video));
|
//this.videoElements.forEach(ve => disposeElement(ve.video));
|
||||||
|
|
||||||
disposeElement("progress-" + this.getId());
|
disposeElement("progress-" + this.streamId);
|
||||||
|
|
||||||
if (this.wp) {
|
if (this.wp) {
|
||||||
this.wp.dispose();
|
this.wp.dispose();
|
||||||
|
@ -687,14 +680,14 @@ export class Stream {
|
||||||
this.speechEvent.stop();
|
this.speechEvent.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info((this.local ? "Local " : "Remote ") + "'Stream' with id [" + this.getId() + "]' has been succesfully disposed");
|
console.info((this.local ? "Local " : "Remote ") + "'Stream' with id [" + this.streamId + "]' has been succesfully disposed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private configureOptions(options) {
|
private configureOptions(options) {
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
this.id = options.id;
|
this.streamId = options.id;
|
||||||
} else {
|
} else {
|
||||||
this.id = "webcam";
|
this.streamId = "WEBCAM";
|
||||||
}
|
}
|
||||||
this.connection = options.connection;
|
this.connection = options.connection;
|
||||||
this.recvVideo = options.recvVideo || false;
|
this.recvVideo = options.recvVideo || false;
|
||||||
|
@ -705,13 +698,17 @@ export class Stream {
|
||||||
this.activeVideo = options.activeVideo;
|
this.activeVideo = options.activeVideo;
|
||||||
this.dataChannel = options.data || false;
|
this.dataChannel = options.data || false;
|
||||||
this.mediaConstraints = options.mediaConstraints;
|
this.mediaConstraints = options.mediaConstraints;
|
||||||
|
|
||||||
|
this.hasAudio = ((this.recvAudio || this.sendAudio) != undefined) ? (this.recvAudio || this.sendAudio) : false;
|
||||||
|
this.hasVideo = ((this.recvVideo || this.sendVideo) != undefined) ? (this.recvVideo || this.sendVideo) : false;
|
||||||
|
this.typeOfVideo = options.typeOfVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
configureScreenOptions(options) {
|
configureScreenOptions(options) {
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
this.id = options.id;
|
this.streamId = options.id;
|
||||||
} else {
|
} else {
|
||||||
this.id = "screen";
|
this.streamId = "SCREEN";
|
||||||
}
|
}
|
||||||
this.recvVideo = options.recvVideo || false;
|
this.recvVideo = options.recvVideo || false;
|
||||||
this.recvAudio = options.recvAudio || false;
|
this.recvAudio = options.recvAudio || false;
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class ProtocolElements {
|
||||||
public static final String JOINROOM_PEERSTREAMID_PARAM = "id";
|
public static final String JOINROOM_PEERSTREAMID_PARAM = "id";
|
||||||
public static final String JOINROOM_PEERSTREAMAUDIOACTIVE_PARAM = "audioActive";
|
public static final String JOINROOM_PEERSTREAMAUDIOACTIVE_PARAM = "audioActive";
|
||||||
public static final String JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM = "videoActive";
|
public static final String JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM = "videoActive";
|
||||||
|
public static final String JOINROOM_PEERSTREAMTYPEOFVIDEO_PARAM = "typeOfVideo";
|
||||||
|
|
||||||
public static final String PUBLISHVIDEO_METHOD = "publishVideo";
|
public static final String PUBLISHVIDEO_METHOD = "publishVideo";
|
||||||
public static final String PUBLISHVIDEO_SDPOFFER_PARAM = "sdpOffer";
|
public static final String PUBLISHVIDEO_SDPOFFER_PARAM = "sdpOffer";
|
||||||
|
@ -52,6 +53,7 @@ public class ProtocolElements {
|
||||||
public static final String PUBLISHVIDEO_SDPANSWER_PARAM = "sdpAnswer";
|
public static final String PUBLISHVIDEO_SDPANSWER_PARAM = "sdpAnswer";
|
||||||
public static final String PUBLISHVIDEO_AUDIOACTIVE_PARAM = "audioActive";
|
public static final String PUBLISHVIDEO_AUDIOACTIVE_PARAM = "audioActive";
|
||||||
public static final String PUBLISHVIDEO_VIDEOACTIVE_PARAM = "videoActive";
|
public static final String PUBLISHVIDEO_VIDEOACTIVE_PARAM = "videoActive";
|
||||||
|
public static final String PUBLISHVIDEO_TYPEOFVIDEO_PARAM = "typeOfVideo";
|
||||||
|
|
||||||
public static final String UNPUBLISHVIDEO_METHOD = "unpublishVideo";
|
public static final String UNPUBLISHVIDEO_METHOD = "unpublishVideo";
|
||||||
|
|
||||||
|
@ -88,6 +90,7 @@ public class ProtocolElements {
|
||||||
public static final String PARTICIPANTPUBLISHED_STREAMID_PARAM = "id";
|
public static final String PARTICIPANTPUBLISHED_STREAMID_PARAM = "id";
|
||||||
public static final String PARTICIPANTPUBLISHED_AUDIOACTIVE_PARAM = "audioActive";
|
public static final String PARTICIPANTPUBLISHED_AUDIOACTIVE_PARAM = "audioActive";
|
||||||
public static final String PARTICIPANTPUBLISHED_VIDEOACTIVE_PARAM = "videoActive";
|
public static final String PARTICIPANTPUBLISHED_VIDEOACTIVE_PARAM = "videoActive";
|
||||||
|
public static final String PARTICIPANTPUBLISHED_TYPEOFVIDEO_PARAM = "typeOfVideo";
|
||||||
|
|
||||||
public static final String PARTICIPANTUNPUBLISHED_METHOD = "participantUnpublished";
|
public static final String PARTICIPANTUNPUBLISHED_METHOD = "participantUnpublished";
|
||||||
public static final String PARTICIPANTUNPUBLISHED_NAME_PARAM = "name";
|
public static final String PARTICIPANTUNPUBLISHED_NAME_PARAM = "name";
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class NotificationRoomManager {
|
||||||
* MediaElement...)
|
* MediaElement...)
|
||||||
*/
|
*/
|
||||||
public void publishMedia(ParticipantRequest request, boolean isOffer, String sdp,
|
public void publishMedia(ParticipantRequest request, boolean isOffer, String sdp,
|
||||||
MediaElement loopbackAlternativeSrc, MediaType loopbackConnectionType, boolean audioActive, boolean videoActive, boolean doLoopback,
|
MediaElement loopbackAlternativeSrc, MediaType loopbackConnectionType, boolean audioActive, boolean videoActive, String typeOfVideo, boolean doLoopback,
|
||||||
MediaElement... mediaElements) {
|
MediaElement... mediaElements) {
|
||||||
String pid = request.getParticipantId();
|
String pid = request.getParticipantId();
|
||||||
String userName = null;
|
String userName = null;
|
||||||
|
@ -143,14 +143,14 @@ public class NotificationRoomManager {
|
||||||
sdpAnswer = internalManager
|
sdpAnswer = internalManager
|
||||||
.publishMedia(request.getParticipantId(), isOffer, sdp, loopbackAlternativeSrc,
|
.publishMedia(request.getParticipantId(), isOffer, sdp, loopbackAlternativeSrc,
|
||||||
loopbackConnectionType, doLoopback, mediaElements);
|
loopbackConnectionType, doLoopback, mediaElements);
|
||||||
internalManager.updateParticipantStreamsActive(pid, audioActive, videoActive);
|
internalManager.updateParticipantStreamsActive(pid, audioActive, videoActive, typeOfVideo);
|
||||||
participants = internalManager.getParticipants(internalManager.getRoomName(pid));
|
participants = internalManager.getParticipants(internalManager.getRoomName(pid));
|
||||||
} catch (OpenViduException e) {
|
} catch (OpenViduException e) {
|
||||||
log.warn("PARTICIPANT {}: Error publishing media", userName, e);
|
log.warn("PARTICIPANT {}: Error publishing media", userName, e);
|
||||||
notificationRoomHandler.onPublishMedia(request, null, null, true, true, null, e);
|
notificationRoomHandler.onPublishMedia(request, null, null, true, true, "", null, e);
|
||||||
}
|
}
|
||||||
if (sdpAnswer != null) {
|
if (sdpAnswer != null) {
|
||||||
notificationRoomHandler.onPublishMedia(request, userName, sdpAnswer, audioActive, videoActive, participants, null);
|
notificationRoomHandler.onPublishMedia(request, userName, sdpAnswer, audioActive, videoActive, typeOfVideo, participants, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,9 +158,9 @@ public class NotificationRoomManager {
|
||||||
* @param request instance of {@link ParticipantRequest} POJO
|
* @param request instance of {@link ParticipantRequest} POJO
|
||||||
* @see RoomManager#publishMedia(String, String, boolean, MediaElement...)
|
* @see RoomManager#publishMedia(String, String, boolean, MediaElement...)
|
||||||
*/
|
*/
|
||||||
public void publishMedia(ParticipantRequest request, String sdpOffer, boolean audioActive, boolean videoActive, boolean doLoopback,
|
public void publishMedia(ParticipantRequest request, String sdpOffer, boolean audioActive, boolean videoActive, String typeOfVideo, boolean doLoopback,
|
||||||
MediaElement... mediaElements) {
|
MediaElement... mediaElements) {
|
||||||
this.publishMedia(request, true, sdpOffer, null, null, audioActive, videoActive, doLoopback, mediaElements);
|
this.publishMedia(request, true, sdpOffer, null, null, audioActive, videoActive, typeOfVideo, doLoopback, mediaElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -682,7 +682,7 @@ public class RoomManager {
|
||||||
Set<UserParticipant> userParts = new HashSet<UserParticipant>();
|
Set<UserParticipant> userParts = new HashSet<UserParticipant>();
|
||||||
for (Participant p : participants) {
|
for (Participant p : participants) {
|
||||||
if (!p.isClosed()) {
|
if (!p.isClosed()) {
|
||||||
userParts.add(new UserParticipant(p.getId(), p.getName(), p.getClientMetadata(), p.getServerMetadata(), p.isStreaming(), p.isAudioActive(), p.isVideoActive()));
|
userParts.add(new UserParticipant(p.getId(), p.getName(), p.getClientMetadata(), p.getServerMetadata(), p.isStreaming(), p.isAudioActive(), p.isVideoActive(), p.getTypeOfVideo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return userParts;
|
return userParts;
|
||||||
|
@ -962,10 +962,11 @@ public class RoomManager {
|
||||||
"No participant with id '" + pid + "' was found");
|
"No participant with id '" + pid + "' was found");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateParticipantStreamsActive(String pid, boolean audioActive, boolean videoActive) {
|
public void updateParticipantStreamsActive(String pid, boolean audioActive, boolean videoActive, String typeOfVideo) {
|
||||||
Participant p = this.getParticipant(pid);
|
Participant p = this.getParticipant(pid);
|
||||||
p.setAudioActive(audioActive);
|
p.setAudioActive(audioActive);
|
||||||
p.setVideoActive(videoActive);
|
p.setVideoActive(videoActive);
|
||||||
|
p.setTypeOfVideo(typeOfVideo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFilter(String roomId, String filterId) {
|
public void updateFilter(String roomId, String filterId) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ public interface NotificationRoomHandler extends RoomHandler {
|
||||||
* accordingly.
|
* accordingly.
|
||||||
*/
|
*/
|
||||||
void onPublishMedia(ParticipantRequest request, String publisherName, String sdpAnswer,
|
void onPublishMedia(ParticipantRequest request, String publisherName, String sdpAnswer,
|
||||||
boolean audioActive, boolean videoActive, Set<UserParticipant> participants, OpenViduException error);
|
boolean audioActive, boolean videoActive, String typeOfVideo, Set<UserParticipant> participants, OpenViduException error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called as a result of {@link NotificationRoomManager#unpublishMedia(ParticipantRequest)}. The
|
* Called as a result of {@link NotificationRoomManager#unpublishMedia(ParticipantRequest)}. The
|
||||||
|
|
|
@ -32,6 +32,7 @@ public class UserParticipant {
|
||||||
|
|
||||||
private boolean audioActive = true;
|
private boolean audioActive = true;
|
||||||
private boolean videoActive = true;
|
private boolean videoActive = true;
|
||||||
|
private String typeOfVideo;
|
||||||
|
|
||||||
private final String METADATA_SEPARATOR = "%/%";
|
private final String METADATA_SEPARATOR = "%/%";
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ public class UserParticipant {
|
||||||
this.streaming = streaming;
|
this.streaming = streaming;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserParticipant(String participantId, String userName, String clientMetadata, String serverMetadata, boolean streaming, boolean audioActive, boolean videoActive) {
|
public UserParticipant(String participantId, String userName, String clientMetadata, String serverMetadata, boolean streaming, boolean audioActive, boolean videoActive, String typeOfVideo) {
|
||||||
super();
|
super();
|
||||||
this.participantId = participantId;
|
this.participantId = participantId;
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
|
@ -60,6 +61,7 @@ public class UserParticipant {
|
||||||
this.streaming = streaming;
|
this.streaming = streaming;
|
||||||
this.audioActive = audioActive;
|
this.audioActive = audioActive;
|
||||||
this.videoActive = videoActive;
|
this.videoActive = videoActive;
|
||||||
|
this.typeOfVideo = typeOfVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserParticipant(String participantId, String userName) {
|
public UserParticipant(String participantId, String userName) {
|
||||||
|
@ -112,7 +114,7 @@ public class UserParticipant {
|
||||||
return audioActive;
|
return audioActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAudioACtive(boolean active) {
|
public void setAudioActive(boolean active) {
|
||||||
this.audioActive = active;
|
this.audioActive = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,10 +122,18 @@ public class UserParticipant {
|
||||||
return videoActive;
|
return videoActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVideoACtive(boolean active) {
|
public void setVideoActive(boolean active) {
|
||||||
this.videoActive = active;
|
this.videoActive = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTypeOfVideo() {
|
||||||
|
return this.typeOfVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeOfVideo(String typeOfVideo) {
|
||||||
|
this.typeOfVideo = typeOfVideo;
|
||||||
|
}
|
||||||
|
|
||||||
public String getFullMetadata(){
|
public String getFullMetadata(){
|
||||||
String fullMetadata;
|
String fullMetadata;
|
||||||
if ((!this.clientMetadata.isEmpty()) && (!this.serverMetadata.isEmpty())){
|
if ((!this.clientMetadata.isEmpty()) && (!this.serverMetadata.isEmpty())){
|
||||||
|
|
|
@ -85,10 +85,22 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
|
||||||
.addProperty(ProtocolElements.JOINROOM_METADATA_PARAM, participant.getFullMetadata());
|
.addProperty(ProtocolElements.JOINROOM_METADATA_PARAM, participant.getFullMetadata());
|
||||||
|
|
||||||
if (participant.isStreaming()) {
|
if (participant.isStreaming()) {
|
||||||
|
|
||||||
|
String streamId = "";
|
||||||
|
if ("SCREEN".equals(participant.getTypeOfVideo())) {
|
||||||
|
streamId = "SCREEN";
|
||||||
|
} else if (participant.isVideoActive()) {
|
||||||
|
streamId = "CAMERA";
|
||||||
|
} else if (participant.isAudioActive()) {
|
||||||
|
streamId = "MICRO";
|
||||||
|
}
|
||||||
|
|
||||||
JsonObject stream = new JsonObject();
|
JsonObject stream = new JsonObject();
|
||||||
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMID_PARAM, "webcam");
|
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMID_PARAM, participant.getUserName() + "_" + streamId);
|
||||||
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMAUDIOACTIVE_PARAM, participant.isAudioActive());
|
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMAUDIOACTIVE_PARAM, participant.isAudioActive());
|
||||||
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM, participant.isVideoActive());
|
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM, participant.isVideoActive());
|
||||||
|
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMTYPEOFVIDEO_PARAM, participant.getTypeOfVideo());
|
||||||
|
|
||||||
JsonArray streamsArray = new JsonArray();
|
JsonArray streamsArray = new JsonArray();
|
||||||
streamsArray.add(stream);
|
streamsArray.add(stream);
|
||||||
participantJson.add(ProtocolElements.JOINROOM_PEERSTREAMS_PARAM, streamsArray);
|
participantJson.add(ProtocolElements.JOINROOM_PEERSTREAMS_PARAM, streamsArray);
|
||||||
|
@ -133,7 +145,7 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPublishMedia(ParticipantRequest request, String publisherName, String sdpAnswer,
|
public void onPublishMedia(ParticipantRequest request, String publisherName, String sdpAnswer,
|
||||||
boolean audioActive, boolean videoActive, Set<UserParticipant> participants, OpenViduException error) {
|
boolean audioActive, boolean videoActive, String typeOfVideo, Set<UserParticipant> participants, OpenViduException error) {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
notifService.sendErrorResponse(request, null, error);
|
notifService.sendErrorResponse(request, null, error);
|
||||||
return;
|
return;
|
||||||
|
@ -145,9 +157,21 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
|
||||||
JsonObject params = new JsonObject();
|
JsonObject params = new JsonObject();
|
||||||
params.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_USER_PARAM, publisherName);
|
params.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_USER_PARAM, publisherName);
|
||||||
JsonObject stream = new JsonObject();
|
JsonObject stream = new JsonObject();
|
||||||
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_STREAMID_PARAM, "webcam");
|
|
||||||
|
String streamId = "";
|
||||||
|
if ("SCREEN".equals(typeOfVideo)) {
|
||||||
|
streamId = "SCREEN";
|
||||||
|
} else if (videoActive) {
|
||||||
|
streamId = "CAMERA";
|
||||||
|
} else if (audioActive) {
|
||||||
|
streamId = "MICRO";
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_STREAMID_PARAM, publisherName + "_" + streamId);
|
||||||
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_AUDIOACTIVE_PARAM, audioActive);
|
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_AUDIOACTIVE_PARAM, audioActive);
|
||||||
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_VIDEOACTIVE_PARAM, videoActive);
|
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_VIDEOACTIVE_PARAM, videoActive);
|
||||||
|
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_TYPEOFVIDEO_PARAM, typeOfVideo);
|
||||||
|
|
||||||
JsonArray streamsArray = new JsonArray();
|
JsonArray streamsArray = new JsonArray();
|
||||||
streamsArray.add(stream);
|
streamsArray.add(stream);
|
||||||
params.add(ProtocolElements.PARTICIPANTPUBLISHED_STREAMS_PARAM, streamsArray);
|
params.add(ProtocolElements.PARTICIPANTPUBLISHED_STREAMS_PARAM, streamsArray);
|
||||||
|
|
|
@ -76,10 +76,12 @@ public class Participant {
|
||||||
private volatile boolean streaming = false;
|
private volatile boolean streaming = false;
|
||||||
private volatile boolean audioActive = true;
|
private volatile boolean audioActive = true;
|
||||||
private volatile boolean videoActive = true;
|
private volatile boolean videoActive = true;
|
||||||
|
private volatile String typeOfVideo;
|
||||||
private volatile boolean closed;
|
private volatile boolean closed;
|
||||||
|
|
||||||
private InfoHandler infoHandler;
|
private InfoHandler infoHandler;
|
||||||
|
|
||||||
|
|
||||||
public Participant(String id, String name, String clientMetadata, String serverMetadata, Room room, MediaPipeline pipeline,
|
public Participant(String id, String name, String clientMetadata, String serverMetadata, Room room, MediaPipeline pipeline,
|
||||||
boolean dataChannels, boolean web, InfoHandler infoHandler) {
|
boolean dataChannels, boolean web, InfoHandler infoHandler) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -231,6 +233,14 @@ public class Participant {
|
||||||
this.videoActive = active;
|
this.videoActive = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTypeOfVideo() {
|
||||||
|
return this.typeOfVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeOfVideo(String typeOfVideo) {
|
||||||
|
this.typeOfVideo = typeOfVideo;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSubscribed() {
|
public boolean isSubscribed() {
|
||||||
for (SubscriberEndpoint se : subscribers.values()) {
|
for (SubscriberEndpoint se : subscribers.values()) {
|
||||||
if (se.isConnectedToPublisher()) {
|
if (se.isConnectedToPublisher()) {
|
||||||
|
|
|
@ -111,9 +111,10 @@ public class JsonRpcUserControl {
|
||||||
String sdpOffer = getStringParam(request, ProtocolElements.PUBLISHVIDEO_SDPOFFER_PARAM);
|
String sdpOffer = getStringParam(request, ProtocolElements.PUBLISHVIDEO_SDPOFFER_PARAM);
|
||||||
boolean audioActive = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_AUDIOACTIVE_PARAM);
|
boolean audioActive = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_AUDIOACTIVE_PARAM);
|
||||||
boolean videoActive = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_VIDEOACTIVE_PARAM);
|
boolean videoActive = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_VIDEOACTIVE_PARAM);
|
||||||
|
String typeOfVideo = getStringParam(request, ProtocolElements.PUBLISHVIDEO_TYPEOFVIDEO_PARAM);
|
||||||
boolean doLoopback = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_DOLOOPBACK_PARAM);
|
boolean doLoopback = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_DOLOOPBACK_PARAM);
|
||||||
|
|
||||||
roomManager.publishMedia(participantRequest, sdpOffer, audioActive, videoActive, doLoopback);
|
roomManager.publishMedia(participantRequest, sdpOffer, audioActive, videoActive, typeOfVideo, doLoopback);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
System.out.println("Error: user is not a publisher");
|
System.out.println("Error: user is not a publisher");
|
||||||
|
|
|
@ -200,6 +200,16 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
this.updateEventList('signal', event.from.connectionId + '-' + event.data);
|
this.updateEventList('signal', event.from.connectionId + '-' + event.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*this.session.on('publisherStartSpeaking', (event) => {
|
||||||
|
console.log('Publisher start speaking');
|
||||||
|
console.log(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.session.on('publisherStopSpeaking', (event) => {
|
||||||
|
console.log('Publisher stop speaking');
|
||||||
|
console.log(event);
|
||||||
|
});*/
|
||||||
|
|
||||||
this.session.connect(token, this.clientData, (error) => {
|
this.session.connect(token, this.clientData, (error) => {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
if (this.publishTo) {
|
if (this.publishTo) {
|
||||||
|
|
Loading…
Reference in New Issue