aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/service
diff options
context:
space:
mode:
authorLyubomir Marinov <lyubomir.marinov@jitsi.org>2010-08-11 18:45:17 +0000
committerLyubomir Marinov <lyubomir.marinov@jitsi.org>2010-08-11 18:45:17 +0000
commit347408cc5b84a6d8537f2a8b5fe76eb62056fcc8 (patch)
tree729b8e7d232462995cb35273654110b3e52f6c84 /src/net/java/sip/communicator/service
parent13dbadac72e35d87a7f0990389864acd40e72177 (diff)
downloadjitsi-347408cc5b84a6d8537f2a8b5fe76eb62056fcc8.zip
jitsi-347408cc5b84a6d8537f2a8b5fe76eb62056fcc8.tar.gz
jitsi-347408cc5b84a6d8537f2a8b5fe76eb62056fcc8.tar.bz2
Commits callRecording.patch and recordButton.png provided by Dmitri Melnikov on the dev mailing list in the thread "Call Recording".
Diffstat (limited to 'src/net/java/sip/communicator/service')
-rw-r--r--src/net/java/sip/communicator/service/neomedia/MediaService.java13
-rw-r--r--src/net/java/sip/communicator/service/neomedia/Recorder.java41
-rw-r--r--src/net/java/sip/communicator/service/protocol/ActiveCallsRepository.java34
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java20
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetBasicTelephony.java (renamed from src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicTelephony.java)41
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java38
6 files changed, 165 insertions, 22 deletions
diff --git a/src/net/java/sip/communicator/service/neomedia/MediaService.java b/src/net/java/sip/communicator/service/neomedia/MediaService.java
index 5a8c326..86a6ae5 100644
--- a/src/net/java/sip/communicator/service/neomedia/MediaService.java
+++ b/src/net/java/sip/communicator/service/neomedia/MediaService.java
@@ -152,6 +152,19 @@ public interface MediaService
public ScreenDevice getDefaultScreenDevice();
/**
+ * Creates a new <tt>Recorder</tt> instance that can be used to record a
+ * call which captures and plays back media using a specific
+ * <tt>MediaDevice</tt>.
+ *
+ * @param device the <tt>MediaDevice</tt> which is used for media capture
+ * and playback by the call to be recorded
+ * @return a new <tt>Recorder</tt> instance that can be used to record a
+ * call which captures and plays back media using the specified
+ * <tt>MediaDevice</tt>
+ */
+ public Recorder createRecorder(MediaDevice device);
+
+ /**
* Returns a {@link Map} that binds indicates whatever preferences the
* media service implementation may have for the RTP payload type numbers
* that get dynamically assigned to {@link MediaFormat}s with no static
diff --git a/src/net/java/sip/communicator/service/neomedia/Recorder.java b/src/net/java/sip/communicator/service/neomedia/Recorder.java
new file mode 100644
index 0000000..651dca9
--- /dev/null
+++ b/src/net/java/sip/communicator/service/neomedia/Recorder.java
@@ -0,0 +1,41 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.neomedia;
+
+
+/**
+ * The call recording interface.
+ * Provides the capability to start and stop call recording.
+ *
+ * @author Dmitri Melnikov
+ */
+public interface Recorder
+{
+ /**
+ * Configuration property for the full path to the directory with saved
+ * calls.
+ */
+ public static final String SAVED_CALLS_PATH =
+ "net.java.sip.communicator.impl.neomedia.SAVED_CALLS_PATH";
+ /**
+ * Configuration property format of the saved call.
+ */
+ public static final String CALL_FORMAT =
+ "net.java.sip.communicator.impl.neomedia.CALL_FORMAT";
+
+ /**
+ * Starts the call recording.
+ *
+ * @param callFilename call filename
+ */
+ public void startRecording(String callFilename);
+
+ /**
+ * Stops the call recording.
+ */
+ public void stopRecording();
+}
diff --git a/src/net/java/sip/communicator/service/protocol/ActiveCallsRepository.java b/src/net/java/sip/communicator/service/protocol/ActiveCallsRepository.java
index 11a1faf..a8a775d 100644
--- a/src/net/java/sip/communicator/service/protocol/ActiveCallsRepository.java
+++ b/src/net/java/sip/communicator/service/protocol/ActiveCallsRepository.java
@@ -19,28 +19,27 @@ import net.java.sip.communicator.util.*;
*
* @author Emil Ivov
*/
-public class ActiveCallsRepository<T extends Call,
- U extends AbstractOperationSetBasicTelephony>
+public abstract class ActiveCallsRepository<T extends Call,
+ U extends OperationSetBasicTelephony>
extends CallChangeAdapter
{
/**
* The <tt>Logger</tt> used by the <tt>ActiveCallsRepository</tt>
* class and its instances for logging output.
*/
- private static final Logger logger = Logger
- .getLogger(ActiveCallsRepository.class.getName());
+ private static final Logger logger
+ = Logger.getLogger(ActiveCallsRepository.class);
/**
* A table mapping call ids against call instances.
*/
- private Hashtable<String, T> activeCalls
- = new Hashtable<String, T>();
+ private final Hashtable<String, T> activeCalls = new Hashtable<String, T>();
/**
* The operation set that created us. Instance is mainly used for firing
* events when necessary.
*/
- private final U parentOperationSet;
+ protected final U parentOperationSet;
/**
* Creates a new instance of this repository.
@@ -72,7 +71,7 @@ public class ActiveCallsRepository<T extends Call,
public void callStateChanged(CallChangeEvent evt)
{
if(evt.getEventType().equals(CallChangeEvent.CALL_STATE_CHANGE)
- && evt.getNewValue().equals(CallState.CALL_ENDED))
+ && evt.getNewValue().equals(CallState.CALL_ENDED))
{
T sourceCall =
this.activeCalls.remove(evt.getSourceCall().getCallID());
@@ -81,8 +80,7 @@ public class ActiveCallsRepository<T extends Call,
logger.trace("Removing call " + sourceCall + " from the list of "
+ "active calls because it entered an ENDED state");
- this.parentOperationSet.fireCallEvent(
- CallEvent.CALL_ENDED, sourceCall);
+ fireCallEvent(CallEvent.CALL_ENDED, sourceCall);
}
}
@@ -112,4 +110,20 @@ public class ActiveCallsRepository<T extends Call,
}
}
+ /**
+ * Creates and dispatches a <tt>CallEvent</tt> notifying registered
+ * listeners that an event with id <tt>eventID</tt> has occurred on
+ * <tt>sourceCall</tt>.
+ * <p>
+ * TODO The method is ugly because it can be implemented if
+ * <tt>parentOperationSet</tt> is an
+ * <tt>AbstractOperationSetBasicTelephony</tt>. But after the move of the
+ * latter in the <tt>.service.protocol.media</tt> package, it is not visible
+ * here.
+ * </p>
+ *
+ * @param eventID the ID of the event to dispatch
+ * @param sourceCall the call on which the event has occurred.
+ */
+ protected abstract void fireCallEvent(int eventID, Call sourceCall);
}
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java b/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java
index 31dcb05..2b32c99 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java
@@ -6,9 +6,10 @@
*/
package net.java.sip.communicator.service.protocol;
-import net.java.sip.communicator.service.protocol.event.*;
-import java.util.*;
import java.text.*;
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.event.*;
/**
* An Operation Set defining all basic telephony operations such as conducting
@@ -159,4 +160,19 @@ public interface OperationSetBasicTelephony<T extends ProtocolProviderService>
* this operation set.
*/
public T getProtocolProvider();
+
+ /**
+ * Starts the recording of the <tt>Call</tt>.
+ *
+ * @param call the <tt>Call</tt> to start recording
+ * @param callFilename call filename
+ */
+ public void startRecording(Call call, String callFilename);
+
+ /**
+ * Stops the recording of the <tt>Call</tt>.
+ *
+ * @param call the <tt>Call</tt> to stop recording
+ */
+ public void stopRecording(Call call);
}
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicTelephony.java b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetBasicTelephony.java
index f56dd79..feaaf06 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicTelephony.java
+++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetBasicTelephony.java
@@ -4,10 +4,11 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-package net.java.sip.communicator.service.protocol;
+package net.java.sip.communicator.service.protocol.media;
import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
@@ -21,16 +22,19 @@ import net.java.sip.communicator.util.*;
*
* @author Lubomir Marinov
* @author Emil Ivov
+ * @author Dmitri Melnikov
*/
public abstract class AbstractOperationSetBasicTelephony
<T extends ProtocolProviderService>
implements OperationSetBasicTelephony<T>
{
/**
- * Our class logger
+ * The <tt>Logger</tt> used by the
+ * <tt>AbstractOperationSetBasicTelephony</tt> class and its instances for
+ * logging output.
*/
- private static final Logger logger =
- Logger.getLogger(AbstractOperationSetBasicTelephony.class);
+ private static final Logger logger
+ = Logger.getLogger(AbstractOperationSetBasicTelephony.class);
/**
* A list of listeners registered for call events.
@@ -74,11 +78,8 @@ public abstract class AbstractOperationSetBasicTelephony
logger.debug("Dispatching a CallEvent to " + listeners.size()
+ " listeners. event is: " + cEvent);
- for (Iterator<CallListener> listenerIter
- = listeners.iterator(); listenerIter.hasNext();)
+ for (CallListener listener : listeners)
{
- CallListener listener = listenerIter.next();
-
switch (eventID)
{
case CallEvent.CALL_INITIATED:
@@ -116,7 +117,7 @@ public abstract class AbstractOperationSetBasicTelephony
*
* @param call the <tt>Call</tt> whose mute state is to be set
* @param mute <tt>true</tt> to mute the call streams being sent to
- * <tt>peers</tt>; otherwise, <tt>false</tt>
+ * <tt>peers</tt>; otherwise, <tt>false</tt>
*/
public void setMute(Call call, boolean mute)
{
@@ -126,4 +127,26 @@ public abstract class AbstractOperationSetBasicTelephony
* this implementation takes inspiration from them.
*/
}
+
+ /**
+ * Starts the recording of the <tt>Call</tt>.
+ *
+ * @param call the <tt>Call</tt> to start recording
+ * @param callFilename call filename, when <tt>null</tt> a default filename
+ * is used
+ */
+ public void startRecording(Call call, String callFilename)
+ {
+ ((MediaAwareCall<?, ?, ?>) call).startRecording(callFilename);
+ }
+
+ /**
+ * Stops the recording of the <tt>Call</tt>.
+ *
+ * @param call the <tt>Call</tt> to stop recording
+ */
+ public void stopRecording(Call call)
+ {
+ ((MediaAwareCall<?, ?, ?>) call).stopRecording();
+ }
}
diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java
index 5dbb3b6..e16f631 100644
--- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java
+++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java
@@ -79,6 +79,11 @@ public abstract class MediaAwareCall<
private boolean mute = false;
/**
+ * The <tt>Recorder</tt> used to record this call.
+ */
+ private Recorder recorder;
+
+ /**
* Device used in call will be chosen according to <tt>MediaUseCase</tt>.
*/
protected MediaUseCase mediaUseCase = MediaUseCase.ANY;
@@ -330,7 +335,7 @@ public abstract class MediaAwareCall<
MediaDevice device = mediaService.getDefaultDevice(mediaType,
mediaUseCase);
- if (MediaType.AUDIO.equals(mediaType) && isConferenceFocus())
+ if (MediaType.AUDIO.equals(mediaType))
{
if (conferenceAudioMixer == null)
{
@@ -565,4 +570,35 @@ public abstract class MediaAwareCall<
peer.removeVideoPropertyChangeListener(listener);
}
}
+
+ /**
+ * Stops the recording of this call.
+ */
+ public void stopRecording()
+ {
+ recorder.stopRecording();
+ }
+
+ /**
+ * Starts the recording of this call.
+ * @param callFilename call filename
+ */
+ public void startRecording(String callFilename)
+ {
+ MediaService mediaService = ProtocolMediaActivator.getMediaService();
+ recorder =
+ mediaService.createRecorder(getDefaultDevice(MediaType.AUDIO));
+
+ recorder.startRecording(callFilename);
+ }
+
+ /**
+ * Returns the recorder used by this instance to record the call.
+ *
+ * @return call recorder
+ */
+ public Recorder getRecorder()
+ {
+ return recorder;
+ }
}