/** * Gets a <tt>Content</tt> of this <tt>Conference</tt> which has a specific name. If a * <tt>Content</tt> of this <tt>Conference</tt> with the specified <tt>name</tt> does not exist at * the time the method is invoked, the method initializes a new <tt>Content</tt> instance with the * specified <tt>name</tt> and adds it to the list of <tt>Content</tt>s of this * <tt>Conference</tt>. * * @param name the name of the <tt>Content</tt> which is to be returned * @return a <tt>Content</tt> of this <tt>Conference</tt> which has the specified <tt>name</tt> */ public Content getOrCreateContent(String name) { Content content; synchronized (contents) { for (Content aContent : contents) { if (aContent.getName().equals(name)) { aContent.touch(); // It seems the content is still active. return aContent; } } content = new Content(this, name); if (isRecording()) { content.setRecording(true, getRecordingPath()); } contents.add(content); } if (logger.isInfoEnabled()) { /* * The method Videobridge.getChannelCount() should better be * executed outside synchronized blocks in order to reduce the risks * of causing deadlocks. */ Videobridge videobridge = getVideobridge(); logger.info( "Created content " + name + " of conference " + getID() + ". " + videobridge.getConferenceCountString()); } return content; }
/** * Attempts to enable or disable media recording for this <tt>Conference</tt>. * * @param recording whether to enable or disable recording. * @return the state of the media recording for this <tt>Conference</tt> after the attempt to * enable (or disable). */ public boolean setRecording(boolean recording) { if (recording != this.recording) { if (recording) { // try enable recording if (logger.isDebugEnabled()) { logger.debug("Starting recording for conference with id=" + getID()); } String path = getRecordingPath(); boolean failedToStart = !checkRecordingDirectory(path); if (!failedToStart) { RecorderEventHandler handler = getRecorderEventHandler(); if (handler == null) failedToStart = true; } if (!failedToStart) { EndpointRecorder endpointRecorder = getEndpointRecorder(); if (endpointRecorder == null) { failedToStart = true; } else { for (Endpoint endpoint : getEndpoints()) endpointRecorder.updateEndpoint(endpoint); } } /* * The Recorders of the Contents need to share a single * Synchronizer, we take it from the first Recorder. */ boolean first = true; Synchronizer synchronizer = null; for (Content content : contents) { MediaType mediaType = content.getMediaType(); if (!MediaType.VIDEO.equals(mediaType) && !MediaType.AUDIO.equals(mediaType)) { continue; } if (!failedToStart) failedToStart = !content.setRecording(true, path); if (failedToStart) break; if (first) { first = false; synchronizer = content.getRecorder().getSynchronizer(); } else { Recorder recorder = content.getRecorder(); if (recorder != null) recorder.setSynchronizer(synchronizer); } content.feedKnownSsrcsToSynchronizer(); } if (failedToStart) { recording = false; logger.warn("Failed to start media recording for conference " + getID()); } } // either we were asked to disable recording, or we failed to // enable it if (!recording) { if (logger.isDebugEnabled()) { logger.debug("Stopping recording for conference with id=" + getID()); } for (Content content : contents) { MediaType mediaType = content.getMediaType(); if (MediaType.AUDIO.equals(mediaType) || MediaType.VIDEO.equals(mediaType)) { content.setRecording(false, null); } } if (recorderEventHandler != null) recorderEventHandler.close(); recorderEventHandler = null; recordingPath = null; recordingDirectory = null; if (endpointRecorder != null) endpointRecorder.close(); endpointRecorder = null; } this.recording = recording; } return this.recording; }