mirror of https://github.com/OpenVidu/openvidu.git
Audio-only devices supported (OpenVidu automatically adjusts the media streams)
parent
5806c9045c
commit
ea78653374
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())){
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue