From fb74074d9ec5b7536feefeef2e478d1229f8f4b0 Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Wed, 30 Oct 2019 19:34:54 +0100 Subject: [PATCH] openvidu-server: fix NullPointer on KurentoParticipant#releaseSubscriberEndpoint --- .../kurento/core/KurentoMediaOptions.java | 12 ++++ .../kurento/core/KurentoParticipant.java | 59 +++++++++++-------- .../server/kurento/core/KurentoSession.java | 6 +- .../kurento/core/KurentoSessionManager.java | 8 +-- 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java index 52b80daa..233eee09 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java @@ -55,6 +55,18 @@ public class KurentoMediaOptions extends MediaOptions { this.onlyPlayWithSubscribers = onlyPlayWithSubscribers; } + public KurentoMediaOptions(Boolean hasAudio, Boolean hasVideo, Boolean audioActive, Boolean videoActive, + String typeOfVideo, Integer frameRate, String videoDimensions, KurentoFilter filter, + KurentoMediaOptions streamProperties) { + super(hasAudio, hasVideo, audioActive, videoActive, typeOfVideo, frameRate, videoDimensions, filter); + this.isOffer = streamProperties.isOffer; + this.sdpOffer = streamProperties.sdpOffer; + this.doLoopback = streamProperties.doLoopback; + this.rtspUri = streamProperties.rtspUri; + this.adaptativeBitrate = streamProperties.adaptativeBitrate; + this.onlyPlayWithSubscribers = streamProperties.onlyPlayWithSubscribers; + } + @Override public JsonObject toJson() { JsonObject json = super.toJson(); diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java index 78e559c4..b671b759 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java @@ -196,9 +196,9 @@ public class KurentoParticipant extends Participant { public void unpublishMedia(EndReason reason, long kmsDisconnectionTime) { log.info("PARTICIPANT {}: unpublishing media stream from room {}", this.getParticipantPublicId(), this.session.getSessionId()); + final MediaOptions mediaOptions = this.getPublisher().getMediaOptions(); releasePublisherEndpoint(reason, kmsDisconnectionTime); - this.publisher = new PublisherEndpoint(endpointType, this, this.getParticipantPublicId(), this.getPipeline(), - this.openviduConfig); + resetPublisherEndpoint(mediaOptions); log.info("PARTICIPANT {}: released publisher endpoint and left it initialized (ready for future streaming)", this.getParticipantPublicId()); } @@ -286,19 +286,21 @@ public class KurentoParticipant extends Participant { log.error("Exception connecting subscriber endpoint " + "to publisher endpoint", e); } this.subscribers.remove(senderName); - releaseSubscriberEndpoint(senderName, subscriber, null); + releaseSubscriberEndpoint((KurentoParticipant) sender, subscriber, null); } return null; } - public void cancelReceivingMedia(String senderName, EndReason reason) { + public void cancelReceivingMedia(KurentoParticipant senderKurentoParticipant, EndReason reason) { + final String senderName = senderKurentoParticipant.getParticipantPublicId(); + log.info("PARTICIPANT {}: cancel receiving media from {}", this.getParticipantPublicId(), senderName); SubscriberEndpoint subscriberEndpoint = subscribers.remove(senderName); if (subscriberEndpoint == null || subscriberEndpoint.getEndpoint() == null) { log.warn("PARTICIPANT {}: Trying to cancel receiving video from user {}. " + "But there is no such subscriber endpoint.", this.getParticipantPublicId(), senderName); } else { - releaseSubscriberEndpoint(senderName, subscriberEndpoint, reason); + releaseSubscriberEndpoint(senderKurentoParticipant, subscriberEndpoint, reason); log.info("PARTICIPANT {}: stopped receiving media from {} in room {}", this.getParticipantPublicId(), senderName, this.session.getSessionId()); } @@ -318,7 +320,9 @@ public class KurentoParticipant extends Participant { final SubscriberEndpoint subscriber = entry.getValue(); it.remove(); if (subscriber != null && subscriber.getEndpoint() != null) { - releaseSubscriberEndpoint(remoteParticipantName, subscriber, reason); + releaseSubscriberEndpoint( + (KurentoParticipant) this.session.getParticipantByPublicId(remoteParticipantName), subscriber, + reason); log.debug("PARTICIPANT {}: Released subscriber endpoint to {}", this.getParticipantPublicId(), remoteParticipantName); } else { @@ -405,7 +409,9 @@ public class KurentoParticipant extends Participant { } } - private void releaseSubscriberEndpoint(String senderName, SubscriberEndpoint subscriber, EndReason reason) { + private void releaseSubscriberEndpoint(KurentoParticipant senderKurentoParticipant, SubscriberEndpoint subscriber, + EndReason reason) { + final String senderName = senderKurentoParticipant.getParticipantPublicId(); if (subscriber != null) { subscriber.unregisterErrorListeners(); @@ -416,21 +422,19 @@ public class KurentoParticipant extends Participant { releaseElement(senderName, subscriber.getEndpoint()); // Stop PlayerEndpoint of IP CAM if last subscriber disconnected - final KurentoParticipant sender = (KurentoParticipant) this.session.getParticipantByPublicId(senderName); - if (sender != null && ((KurentoMediaOptions) sender.getPublisherMediaOptions()).onlyPlayWithSubscribers) { - final PublisherEndpoint publisher = sender.publisher; - if (publisher != null) { - synchronized (publisher) { - publisher.numberOfSubscribers--; - if (publisher.isPlayerEndpoint() && publisher.numberOfSubscribers == 0) { - try { - publisher.getPlayerEndpoint().stop(); - log.info("IP Camera stream {} feed is now disabled because there are no subscribers", - publisher.getStreamId()); - } catch (Exception e) { - log.info("Error while disabling feed for IP camera {}: {}", publisher.getStreamId(), - e.getMessage()); - } + final PublisherEndpoint senderPublisher = senderKurentoParticipant.publisher; + final KurentoMediaOptions options = (KurentoMediaOptions) senderPublisher.getMediaOptions(); + if (options.onlyPlayWithSubscribers != null && options.onlyPlayWithSubscribers) { + synchronized (senderPublisher) { + senderPublisher.numberOfSubscribers--; + if (senderPublisher.isPlayerEndpoint() && senderPublisher.numberOfSubscribers == 0) { + try { + senderPublisher.getPlayerEndpoint().stop(); + log.info("IP Camera stream {} feed is now disabled because there are no subscribers", + senderPublisher.getStreamId()); + } catch (Exception e) { + log.info("Error while disabling feed for IP camera {}: {}", senderPublisher.getStreamId(), + e.getMessage()); } } } @@ -478,10 +482,19 @@ public class KurentoParticipant extends Participant { return this.publisher.getStreamId(); } - public void resetPublisherEndpoint() { + public void resetPublisherEndpoint(MediaOptions mediaOptions) { log.info("Reseting publisher endpoint for participant {}", this.getParticipantPublicId()); this.publisher = new PublisherEndpoint(endpointType, this, this.getParticipantPublicId(), this.session.getPipeline(), this.openviduConfig); + this.publisher.setMediaOptions(mediaOptions); + } + + public void resetPublisherEndpoint() { + MediaOptions mediaOptions = null; + if (this.getPublisher() != null) { + mediaOptions = this.getPublisher().getMediaOptions(); + } + this.resetPublisherEndpoint(mediaOptions); } @Override diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java index 8cd0704a..c349d451 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java @@ -105,7 +105,7 @@ public class KurentoSession extends Session { if (participant.equals(subscriber)) { continue; } - ((KurentoParticipant) subscriber).cancelReceivingMedia(participant.getParticipantPublicId(), reason); + ((KurentoParticipant) subscriber).cancelReceivingMedia((KurentoParticipant) participant, reason); } log.debug("SESSION {}: Unsubscribed other participants {} from the publisher {}", sessionId, @@ -176,12 +176,12 @@ public class KurentoSession extends Session { checkClosed(); - participants.remove(participant.getParticipantPrivateId()); + KurentoParticipant removedParticipant = (KurentoParticipant) participants.remove(participant.getParticipantPrivateId()); log.debug("SESSION {}: Cancel receiving media from participant '{}' for other participant", this.sessionId, participant.getParticipantPublicId()); for (Participant other : participants.values()) { - ((KurentoParticipant) other).cancelReceivingMedia(participant.getParticipantPublicId(), reason); + ((KurentoParticipant) other).cancelReceivingMedia(removedParticipant, reason); } } diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java index 2d9c7c0e..cbda9245 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java @@ -436,7 +436,7 @@ public class KurentoSessionManager extends SessionManager { "User " + senderName + " not found in session " + session.getSessionId()); } - kParticipant.cancelReceivingMedia(senderName, EndReason.unsubscribe); + kParticipant.cancelReceivingMedia((KurentoParticipant) sender, EndReason.unsubscribe); sessionEventsHandler.onUnsubscribe(participant, transactionId, null); } @@ -446,7 +446,7 @@ public class KurentoSessionManager extends SessionManager { JsonElement newValue, String reason) { KurentoParticipant kParticipant = (KurentoParticipant) participant; streamId = kParticipant.getPublisherStreamId(); - MediaOptions streamProperties = kParticipant.getPublisherMediaOptions(); + KurentoMediaOptions streamProperties = (KurentoMediaOptions) kParticipant.getPublisherMediaOptions(); Boolean hasAudio = streamProperties.hasAudio(); Boolean hasVideo = streamProperties.hasVideo(); @@ -469,8 +469,8 @@ public class KurentoSessionManager extends SessionManager { break; } - kParticipant.setPublisherMediaOptions(new MediaOptions(hasAudio, hasVideo, audioActive, videoActive, - typeOfVideo, frameRate, videoDimensions, filter)); + kParticipant.setPublisherMediaOptions(new KurentoMediaOptions(hasAudio, hasVideo, audioActive, videoActive, + typeOfVideo, frameRate, videoDimensions, filter, streamProperties)); sessionEventsHandler.onStreamPropertyChanged(participant, transactionId, kParticipant.getSession().getParticipants(), streamId, property, newValue, reason);