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

View File

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

View File

@ -128,7 +128,7 @@ public class NotificationRoomManager {
* MediaElement...)
*/
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) {
String pid = request.getParticipantId();
String userName = null;
@ -139,13 +139,14 @@ public class NotificationRoomManager {
sdpAnswer = internalManager
.publishMedia(request.getParticipantId(), isOffer, sdp, loopbackAlternativeSrc,
loopbackConnectionType, doLoopback, mediaElements);
internalManager.updateParticipantAudioOnly(pid, audioOnly);
participants = internalManager.getParticipants(internalManager.getRoomName(pid));
} catch (OpenViduException 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) {
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
* @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) {
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>();
for (Participant p : participants) {
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;
@ -942,6 +942,11 @@ public class RoomManager {
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE,
"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) {
Room room = rooms.get(roomId);

View File

@ -117,7 +117,7 @@ public interface NotificationRoomHandler extends RoomHandler {
* accordingly.
*/
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

View File

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

View File

@ -82,6 +82,7 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
if (participant.isStreaming()) {
JsonObject stream = new JsonObject();
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMID_PARAM, "webcam");
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMAUDIOONLY_PARAM, participant.isAudioOnly());
JsonArray streamsArray = new JsonArray();
streamsArray.add(stream);
participantJson.add(ProtocolElements.JOINROOM_PEERSTREAMS_PARAM, streamsArray);
@ -126,7 +127,7 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
@Override
public void onPublishMedia(ParticipantRequest request, String publisherName, String sdpAnswer,
Set<UserParticipant> participants, OpenViduException error) {
boolean audioOnly, Set<UserParticipant> participants, OpenViduException error) {
if (error != null) {
notifService.sendErrorResponse(request, null, error);
return;
@ -139,6 +140,7 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
params.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_USER_PARAM, publisherName);
JsonObject stream = new JsonObject();
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_STREAMID_PARAM, "webcam");
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_AUDIOONLY_PARAM, audioOnly);
JsonArray streamsArray = new JsonArray();
streamsArray.add(stream);
params.add(ProtocolElements.PARTICIPANTPUBLISHED_STREAMS_PARAM, streamsArray);

View File

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

View File

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

View File

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