From 91881f33f47747cd7b377e780a0860f46739c7d3 Mon Sep 17 00:00:00 2001 From: Nik Date: Fri, 24 Aug 2018 17:53:08 +0200 Subject: [PATCH] make transcriber leave a conference based on participants presence (#129) * make transcriber leave a conference based on participants presence * remove TranscriptionStatus from Jigasi * change leave logic of Transcriber to use TranscriptionRequestExtension * update jitsi-desk --- pom.xml | 2 +- .../jigasi/TranscriptionGatewaySession.java | 28 ++++- .../jigasi/transcription/Participant.java | 53 ++++++++- .../jigasi/transcription/Transcriber.java | 27 ++++- .../xmpp/TranscriptionStatusExtension.java | 106 ------------------ 5 files changed, 104 insertions(+), 112 deletions(-) delete mode 100644 src/main/java/org/jitsi/jigasi/xmpp/TranscriptionStatusExtension.java diff --git a/pom.xml b/pom.xml index 81368bb82..9ec840938 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ true 4.2.1 - 2.13.812e3ed + 2.13.5160aa9 diff --git a/src/main/java/org/jitsi/jigasi/TranscriptionGatewaySession.java b/src/main/java/org/jitsi/jigasi/TranscriptionGatewaySession.java index 7b08a1b53..c73927fee 100644 --- a/src/main/java/org/jitsi/jigasi/TranscriptionGatewaySession.java +++ b/src/main/java/org/jitsi/jigasi/TranscriptionGatewaySession.java @@ -23,7 +23,6 @@ import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import org.jitsi.jigasi.transcription.*; -import org.jitsi.jigasi.xmpp.*; import org.jitsi.service.neomedia.*; import org.jitsi.service.neomedia.device.*; import org.jitsi.util.*; @@ -58,6 +57,12 @@ public class TranscriptionGatewaySession */ public final static String DISPLAY_NAME = "Transcriber"; + /** + * How long the transcriber should wait until really leaving the conference + * when no participant is requesting transcription anymore. + */ + public final static int PRESENCE_UPDATE_WAIT_UNTIL_LEAVE_DURATION = 2500; + /** * The TranscriptionService used by this session */ @@ -296,6 +301,27 @@ void notifyChatRoomMemberUpdated(ChatRoomMember chatMember, Presence presence) { this.transcriber.updateParticipantTargetLanguage(identifier, null); } + + if(transcriber.isTranscribing() && + !transcriber.isAnyParticipantRequestingTranscription()) + { + new Thread(() -> + { + try + { + Thread.sleep(PRESENCE_UPDATE_WAIT_UNTIL_LEAVE_DURATION); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + if(!transcriber.isAnyParticipantRequestingTranscription()) + { + jvbConference.stop(); + } + }).start(); + } } @Override diff --git a/src/main/java/org/jitsi/jigasi/transcription/Participant.java b/src/main/java/org/jitsi/jigasi/transcription/Participant.java index 28bdf2f67..d2c8e20fb 100644 --- a/src/main/java/org/jitsi/jigasi/transcription/Participant.java +++ b/src/main/java/org/jitsi/jigasi/transcription/Participant.java @@ -342,6 +342,13 @@ private AvatarIdPacketExtension getAvatarIdExtensionOrNull(Presence p) AvatarIdPacketExtension.NAME_SPACE); } + private TranscriptionRequestExtension + getTranscriptionRequestExtensionOrNull(Presence p) + { + return p.getExtension(TranscriptionRequestExtension.ELEMENT_NAME, + TranscriptionRequestExtension.NAMESPACE); + } + /** * Get the ssrc of the audio of this participant * @@ -364,7 +371,9 @@ public long getSSRC() */ public String getSourceLanguage() { - return sourceLanguageLocale.getLanguage(); + return sourceLanguageLocale == null ? + null : + sourceLanguageLocale.getLanguage(); } /** @@ -384,7 +393,14 @@ public String getTranslationLanguage() */ public void setSourceLanguage(String language) { - sourceLanguageLocale = Locale.forLanguageTag(language); + if (language == null) + { + sourceLanguageLocale = null; + } + else + { + sourceLanguageLocale = Locale.forLanguageTag(language); + } } /** @@ -617,4 +633,37 @@ private static long getConferenceMemberAudioSSRC( // bitwise AND to fix signed int casted to long return confMember.getAudioSsrc() & 0xffffffffL; } + + /** + * Check whether this Participant is requesting a source language + * + * @return true when the source language is set and non-empty, false + * otherwise. + */ + public boolean hasValidSourceLanguage() + { + String lang = this.getSourceLanguage(); + + return lang != null && !lang.isEmpty(); + } + + /** + * Get whether this {@link Participant} is requesting transcription by + * checking the {@link TranscriptionRequestExtension} in the + * {@link Presence} + * + * @return true when the {@link Participant} is requesting transcription, + * false otherwise + */ + public boolean isRequestingTranscription() + { + ChatRoomMemberJabberImpl memberJabber + = ((ChatRoomMemberJabberImpl) this.chatMember); + + TranscriptionRequestExtension ext + = getTranscriptionRequestExtensionOrNull( + memberJabber.getLastPresence()); + + return ext != null && Boolean.valueOf(ext.getText()); + } } diff --git a/src/main/java/org/jitsi/jigasi/transcription/Transcriber.java b/src/main/java/org/jitsi/jigasi/transcription/Transcriber.java index c0ffc9cb8..9ba430050 100644 --- a/src/main/java/org/jitsi/jigasi/transcription/Transcriber.java +++ b/src/main/java/org/jitsi/jigasi/transcription/Transcriber.java @@ -611,10 +611,14 @@ public void bufferReceived(ReceiveStream receiveStream, Buffer buffer) long ssrc = receiveStream.getSSRC() & 0xffffffffL; Participant p = findParticipant(ssrc); + if (p != null) { - logger.trace("Gave audio to buffer"); - p.giveBuffer(buffer); + if (p.hasValidSourceLanguage()) + { + logger.trace("Gave audio to buffer"); + p.giveBuffer(buffer); + } } else { @@ -660,6 +664,25 @@ private Participant getParticipant(String identifier) } } + /** + * Check whether any {@link Participant} are requesting transcription + * + * @return true when at least one {@link Participant} is requesting + * transcription, false otherwise + */ + public boolean isAnyParticipantRequestingTranscription() + { + List participantsCopy; + synchronized (this.participants) + { + participantsCopy = new ArrayList<>(this.participants.values()); + } + + return participantsCopy + .stream() + .anyMatch(Participant::isRequestingTranscription); + } + /** * Get the MediaDevice this transcriber is listening to for audio * diff --git a/src/main/java/org/jitsi/jigasi/xmpp/TranscriptionStatusExtension.java b/src/main/java/org/jitsi/jigasi/xmpp/TranscriptionStatusExtension.java deleted file mode 100644 index e7df85460..000000000 --- a/src/main/java/org/jitsi/jigasi/xmpp/TranscriptionStatusExtension.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Jigasi, the JItsi GAteway to SIP. - * - * Copyright @ 2015 Atlassian Pty Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jitsi.jigasi.xmpp; - -import net.java.sip.communicator.impl.protocol.jabber.extensions.*; - -/** - * The packet extension added to the MUC presence to broadcast current - * transcription status to all conference participants. - * - * Status meaning: - * {@link Status#OFF} - transcription stopped(available to start) - * {@link Status#ON} - transcription in progress - */ -public class TranscriptionStatusExtension - extends AbstractPacketExtension -{ - /** - * XML element name of this packet extension. - */ - public static final String ELEMENT_NAME = "transcription-status"; - - /** - * The namespace of this packet extension. - */ - public static final String NAMESPACE = "jabber:client"; - - /** - * The name of XML attribute which holds the transcription status. - */ - private static final String STATUS_ATTRIBUTE = "status"; - - /** - * Constructs new TranscriptionStatusExtension. - */ - public TranscriptionStatusExtension() - { - super(NAMESPACE, ELEMENT_NAME); - } - - /** - * Sets new value for the transcription status. - * @param status one of {@link Status} - */ - public void setStatus(Status status) - { - setAttribute(STATUS_ATTRIBUTE, String.valueOf(status)); - } - - /** - * The enumeration of recording status values. - */ - public enum Status - { - /** - * Transcription is in progress. - */ - ON("on"), - - /** - * Transcription stopped. - */ - OFF("off"); - - - /** - * Status name holder. - */ - private String name; - - /** - * Creates new {@link Status} instance. - * @param name a string corresponding to one of {@link Status} values. - */ - Status(String name) - { - this.name = name; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() - { - return name; - } - - } -} -