Stream start speaking and stop speaking events

pull/20/head
pabloFuente 2017-12-12 14:36:43 +01:00
parent 06a2725da8
commit 7e47f19c3c
13 changed files with 150 additions and 87 deletions

View File

@ -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();
} }

View File

@ -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,

View File

@ -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
}]);
} }
} }

View File

@ -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;

View File

@ -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";

View File

@ -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);
} }
/** /**

View File

@ -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) {

View File

@ -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

View File

@ -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())){

View File

@ -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);

View File

@ -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()) {

View File

@ -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");

View File

@ -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) {