Audio-only devices supported (OpenVidu automatically adjusts the media streams)

pull/20/head
pabloFuente 2017-08-21 20:12:13 +02:00
parent 5806c9045c
commit ea78653374
15 changed files with 78 additions and 28 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,7 @@ export interface ConnectionOptions {
id: string; id: string;
metadata: string; metadata: string;
streams?: StreamOptions[]; streams?: StreamOptions[];
audioOnly: boolean;
} }
export class Connection { export class Connection {
@ -37,7 +38,8 @@ export class Connection {
audio: streamOptions.audio, audio: streamOptions.audio,
video: streamOptions.video, video: streamOptions.video,
data: streamOptions.data, data: streamOptions.data,
mediaConstraints: streamOptions.mediaConstraints mediaConstraints: streamOptions.mediaConstraints,
audioOnly: streamOptions.audioOnly
} }
let stream = new Stream( openVidu, false, room, streamOpts ); let stream = new Stream( openVidu, false, room, streamOpts );

View File

@ -40,6 +40,7 @@ export interface StreamOptions {
audio: boolean; audio: boolean;
data: boolean; data: boolean;
mediaConstraints: any; mediaConstraints: any;
audioOnly: boolean;
} }
export interface VideoOptions { export interface VideoOptions {
@ -70,6 +71,8 @@ export class Stream {
private dataChannel: boolean; private dataChannel: boolean;
private dataChannelOpened = false; private dataChannelOpened = false;
private audioOnly = false;
private videoSrc: string; private videoSrc: string;
private parentId: string; private parentId: string;
public isReady: boolean = false; public isReady: boolean = false;
@ -92,6 +95,7 @@ export class Stream {
this.sendVideo = options.video; this.sendVideo = options.video;
this.sendAudio = options.audio; this.sendAudio = options.audio;
this.mediaConstraints = options.mediaConstraints; this.mediaConstraints = options.mediaConstraints;
this.audioOnly = options.audioOnly || false;
this.addEventListener('src-added', (srcEvent) => { this.addEventListener('src-added', (srcEvent) => {
this.videoSrc = srcEvent.src; this.videoSrc = srcEvent.src;
@ -359,6 +363,7 @@ export class Stream {
if (!hasVideo) { if (!hasVideo) {
constraints.video = false; constraints.video = false;
this.sendVideo = false; this.sendVideo = false;
this.audioOnly = true;
this.requestCameraAccesAux(constraints, callback); this.requestCameraAccesAux(constraints, callback);
} else { } else {
this.requestCameraAccesAux(constraints, callback); this.requestCameraAccesAux(constraints, callback);
@ -416,7 +421,8 @@ export class Stream {
this.openVidu.sendRequest("publishVideo", { this.openVidu.sendRequest("publishVideo", {
sdpOffer: sdpOfferParam, sdpOffer: sdpOfferParam,
doLoopback: this.displayMyRemote() || false doLoopback: this.displayMyRemote() || false,
audioOnly: this.audioOnly
}, (error, response) => { }, (error, response) => {
if (error) { if (error) {
console.error("Error on publishVideo: " + JSON.stringify(error)); console.error("Error on publishVideo: " + JSON.stringify(error));
@ -488,16 +494,14 @@ export class Stream {
} }
} else { } else {
let offerConstraints = { let offerConstraints = {
mandatory: { audio: this.recvAudio,
OfferToReceiveVideo: this.recvVideo, video: !this.audioOnly
OfferToReceiveAudio: this.recvAudio
}
}; };
console.log("Constraints of generate SDP offer (subscribing)", console.log("Constraints of generate SDP offer (subscribing)",
offerConstraints); offerConstraints);
let options = { let options = {
onicecandidate: this.connection.sendIceCandidate.bind(this.connection), onicecandidate: this.connection.sendIceCandidate.bind(this.connection),
connectionConstraints: offerConstraints mediaConstraints: offerConstraints
} }
this.wp = new kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, error => { this.wp = new kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, error => {
if (error) { if (error) {

View File

@ -41,11 +41,13 @@ public class ProtocolElements {
public static final String JOINROOM_PEERID_PARAM = "id"; public static final String JOINROOM_PEERID_PARAM = "id";
public static final String JOINROOM_PEERSTREAMS_PARAM = "streams"; public static final String JOINROOM_PEERSTREAMS_PARAM = "streams";
public static final String JOINROOM_PEERSTREAMID_PARAM = "id"; public static final String JOINROOM_PEERSTREAMID_PARAM = "id";
public static final String JOINROOM_PEERSTREAMAUDIOONLY_PARAM = "audioOnly";
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";
public static final String PUBLISHVIDEO_DOLOOPBACK_PARAM = "doLoopback"; public static final String PUBLISHVIDEO_DOLOOPBACK_PARAM = "doLoopback";
public static final String PUBLISHVIDEO_SDPANSWER_PARAM = "sdpAnswer"; public static final String PUBLISHVIDEO_SDPANSWER_PARAM = "sdpAnswer";
public static final String PUBLISHVIDEO_AUDIOONLY_PARAM = "audioOnly";
public static final String UNPUBLISHVIDEO_METHOD = "unpublishVideo"; public static final String UNPUBLISHVIDEO_METHOD = "unpublishVideo";
@ -80,6 +82,7 @@ public class ProtocolElements {
public static final String PARTICIPANTPUBLISHED_USER_PARAM = "id"; public static final String PARTICIPANTPUBLISHED_USER_PARAM = "id";
public static final String PARTICIPANTPUBLISHED_STREAMS_PARAM = "streams"; public static final String PARTICIPANTPUBLISHED_STREAMS_PARAM = "streams";
public static final String PARTICIPANTPUBLISHED_STREAMID_PARAM = "id"; public static final String PARTICIPANTPUBLISHED_STREAMID_PARAM = "id";
public static final String PARTICIPANTPUBLISHED_AUDIOONLY_PARAM = "audioOnly";
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

@ -128,7 +128,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 doLoopback, MediaElement loopbackAlternativeSrc, MediaType loopbackConnectionType, boolean audioOnly, boolean doLoopback,
MediaElement... mediaElements) { MediaElement... mediaElements) {
String pid = request.getParticipantId(); String pid = request.getParticipantId();
String userName = null; String userName = null;
@ -139,13 +139,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.updateParticipantAudioOnly(pid, audioOnly);
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, null, e); notificationRoomHandler.onPublishMedia(request, null, null, false, null, e);
} }
if (sdpAnswer != null) { if (sdpAnswer != null) {
notificationRoomHandler.onPublishMedia(request, userName, sdpAnswer, participants, null); notificationRoomHandler.onPublishMedia(request, userName, sdpAnswer, audioOnly, participants, null);
} }
} }
@ -153,9 +154,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 doLoopback, public void publishMedia(ParticipantRequest request, String sdpOffer, boolean audioOnly, boolean doLoopback,
MediaElement... mediaElements) { MediaElement... mediaElements) {
this.publishMedia(request, true, sdpOffer, null, null, doLoopback, mediaElements); this.publishMedia(request, true, sdpOffer, null, null, audioOnly, doLoopback, mediaElements);
} }
/** /**

View File

@ -663,7 +663,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())); userParts.add(new UserParticipant(p.getId(), p.getName(), p.getClientMetadata(), p.getServerMetadata(), p.isStreaming(), p.isAudioOnly()));
} }
} }
return userParts; return userParts;
@ -942,6 +942,11 @@ public class RoomManager {
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE,
"No participant with id '" + pid + "' was found"); "No participant with id '" + pid + "' was found");
} }
public void updateParticipantAudioOnly(String pid, boolean audioOnly) {
Participant p = this.getParticipant(pid);
p.setAudioOnly(audioOnly);
}
public void updateFilter(String roomId, String filterId) { public void updateFilter(String roomId, String filterId) {
Room room = rooms.get(roomId); Room room = rooms.get(roomId);

View File

@ -117,7 +117,7 @@ public interface NotificationRoomHandler extends RoomHandler {
* accordingly. * accordingly.
*/ */
void onPublishMedia(ParticipantRequest request, String publisherName, String sdpAnswer, void onPublishMedia(ParticipantRequest request, String publisherName, String sdpAnswer,
Set<UserParticipant> participants, OpenViduException error); boolean audioOnly, 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

@ -30,6 +30,8 @@ public class UserParticipant {
private String serverMetadata = ""; private String serverMetadata = "";
private boolean streaming = false; private boolean streaming = false;
private boolean audioOnly = false;
private final String METADATA_SEPARATOR = "%/%"; private final String METADATA_SEPARATOR = "%/%";
public UserParticipant(String participantId, String userName, boolean streaming) { public UserParticipant(String participantId, String userName, boolean streaming) {
@ -47,7 +49,17 @@ public class UserParticipant {
this.serverMetadata = serverMetadata; this.serverMetadata = serverMetadata;
this.streaming = streaming; this.streaming = streaming;
} }
public UserParticipant(String participantId, String userName, String clientMetadata, String serverMetadata, boolean streaming, boolean audioOnly) {
super();
this.participantId = participantId;
this.userName = userName;
this.clientMetadata = clientMetadata;
this.serverMetadata = serverMetadata;
this.streaming = streaming;
this.audioOnly = audioOnly;
}
public UserParticipant(String participantId, String userName) { public UserParticipant(String participantId, String userName) {
super(); super();
this.participantId = participantId; this.participantId = participantId;
@ -94,6 +106,14 @@ public class UserParticipant {
this.streaming = streaming; this.streaming = streaming;
} }
public boolean isAudioOnly() {
return audioOnly;
}
public void setAudioOnly(boolean audioOnly) {
this.audioOnly = audioOnly;
}
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

@ -82,6 +82,7 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
if (participant.isStreaming()) { if (participant.isStreaming()) {
JsonObject stream = new JsonObject(); JsonObject stream = new JsonObject();
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMID_PARAM, "webcam"); stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMID_PARAM, "webcam");
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMAUDIOONLY_PARAM, participant.isAudioOnly());
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);
@ -126,7 +127,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,
Set<UserParticipant> participants, OpenViduException error) { boolean audioOnly, Set<UserParticipant> participants, OpenViduException error) {
if (error != null) { if (error != null) {
notifService.sendErrorResponse(request, null, error); notifService.sendErrorResponse(request, null, error);
return; return;
@ -139,6 +140,7 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
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"); stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_STREAMID_PARAM, "webcam");
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_AUDIOONLY_PARAM, audioOnly);
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

@ -74,6 +74,7 @@ public class Participant {
new ConcurrentHashMap<String, SubscriberEndpoint>(); new ConcurrentHashMap<String, SubscriberEndpoint>();
private volatile boolean streaming = false; private volatile boolean streaming = false;
private volatile boolean audioOnly = false;
private volatile boolean closed; private volatile boolean closed;
private InfoHandler infoHandler; private InfoHandler infoHandler;
@ -212,7 +213,15 @@ public class Participant {
public boolean isStreaming() { public boolean isStreaming() {
return streaming; return streaming;
} }
public boolean isAudioOnly() {
return this.audioOnly;
}
public void setAudioOnly(boolean audioOnly) {
this.audioOnly = audioOnly;
}
public boolean isSubscribed() { public boolean isSubscribed() {
for (SubscriberEndpoint se : subscribers.values()) { for (SubscriberEndpoint se : subscribers.values()) {
if (se.isConnectedToPublisher()) { if (se.isConnectedToPublisher()) {

View File

@ -98,9 +98,10 @@ public class JsonRpcUserControl {
if (roomManager.getRoomManager().isPublisherInRoom(participantName, roomName)) { if (roomManager.getRoomManager().isPublisherInRoom(participantName, roomName)) {
String sdpOffer = getStringParam(request, ProtocolElements.PUBLISHVIDEO_SDPOFFER_PARAM); String sdpOffer = getStringParam(request, ProtocolElements.PUBLISHVIDEO_SDPOFFER_PARAM);
boolean audioOnly = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_AUDIOONLY_PARAM);
boolean doLoopback = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_DOLOOPBACK_PARAM); boolean doLoopback = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_DOLOOPBACK_PARAM);
roomManager.publishMedia(participantRequest, sdpOffer, doLoopback); roomManager.publishMedia(participantRequest, sdpOffer, audioOnly, doLoopback);
} }
else { else {
System.out.println("Error: user is not a publisher"); System.out.println("Error: user is not a publisher");

View File

@ -973,7 +973,7 @@ public class NotificationRoomManagerWithDefaultHandlerTest {
}).when(notificationService).sendResponse(eq(participantRequest), }).when(notificationService).sendResponse(eq(participantRequest),
Matchers.isA(JsonObject.class)); Matchers.isA(JsonObject.class));
manager.publishMedia(participantRequest, SDP_OFFER, false); manager.publishMedia(participantRequest, SDP_OFFER, false, false);
} }
private void participantUnpublish(final ParticipantRequest participantRequest) { private void participantUnpublish(final ParticipantRequest participantRequest) {