예제 #1
0
 /**
  * Implements {@link ActiveSpeakerChangedListener#activeSpeakerChanged(long)}. Notifies this
  * <tt>RecorderRtpImpl</tt> that the audio <tt>ReceiveStream</tt> considered active has changed,
  * and that the new active stream has SSRC <tt>ssrc</tt>.
  *
  * @param ssrc the SSRC of the new active stream.
  */
 @Override
 public void activeSpeakerChanged(long ssrc) {
   if (eventHandler != null) {
     RecorderEvent e = new RecorderEvent();
     e.setAudioSsrc(ssrc);
     // TODO: how do we time this?
     e.setInstant(System.currentTimeMillis());
     e.setType(RecorderEvent.Type.SPEAKER_CHANGED);
     e.setMediaType(MediaType.VIDEO);
     eventHandler.handleEvent(e);
   }
 }
예제 #2
0
  private void audioRecordingStarted(long ssrc, long timestamp) {
    ReceiveStreamDesc desc = findReceiveStream(ssrc);
    if (desc == null) return;

    RecorderEvent event = new RecorderEvent();
    event.setType(RecorderEvent.Type.RECORDING_STARTED);
    event.setMediaType(MediaType.AUDIO);
    event.setSsrc(ssrc);
    event.setRtpTimestamp(timestamp);
    event.setFilename(desc.filename);

    if (eventHandler != null) eventHandler.handleEvent(event);
  }
  /**
   * Expires this <tt>Conference</tt>, its <tt>Content</tt>s and their respective <tt>Channel</tt>s.
   * Releases the resources acquired by this instance throughout its life time and prepares it to be
   * garbage collected.
   */
  public void expire() {
    synchronized (this) {
      if (expired) return;
      else expired = true;
    }

    EventAdmin eventAdmin = videobridge.getEventAdmin();
    if (eventAdmin != null) eventAdmin.sendEvent(EventFactory.conferenceExpired(this));

    setRecording(false);
    if (recorderEventHandler != null) {
      recorderEventHandler.close();
      recorderEventHandler = null;
    }

    Videobridge videobridge = getVideobridge();

    try {
      videobridge.expireConference(this);
    } finally {
      // Expire the Contents of this Conference.
      for (Content content : getContents()) {
        try {
          content.expire();
        } catch (Throwable t) {
          logger.warn(
              "Failed to expire content " + content.getName() + " of conference " + getID() + "!",
              t);
          if (t instanceof InterruptedException) Thread.currentThread().interrupt();
          else if (t instanceof ThreadDeath) throw (ThreadDeath) t;
        }
      }

      // Close the transportManagers of this Conference. Normally, there
      // will be no TransportManager left to close at this point because
      // all Channels have expired and the last Channel to be removed from
      // a TransportManager closes the TransportManager. However, a
      // Channel may have expired before it has learned of its
      // TransportManager and then the TransportManager will not close.
      closeTransportManagers();

      if (logger.isInfoEnabled()) {
        logger.info(
            "Expired conference " + getID() + ". " + videobridge.getConferenceCountString());
      }
    }
  }
  /**
   * Notifies this instance that {@link #speechActivity} has identified a speaker switch event in
   * this multipoint conference and there is now a new dominant speaker.
   */
  private void dominantSpeakerChanged() {
    Endpoint dominantSpeaker = speechActivity.getDominantEndpoint();

    if (logger.isTraceEnabled()) {
      logger.trace(
          "The dominant speaker in conference "
              + getID()
              + " is now the endpoint "
              + ((dominantSpeaker == null) ? "(null)" : dominantSpeaker.getID())
              + ".");
    }

    if (dominantSpeaker != null) {
      broadcastMessageOnDataChannels(createDominantSpeakerEndpointChangeEvent(dominantSpeaker));

      if (isRecording() && (recorderEventHandler != null))
        recorderEventHandler.dominantSpeakerChanged(dominantSpeaker);
    }
  }
  /**
   * 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;
  }
예제 #6
0
 private void handleRtcpPacket(RawPacket pkt) {
   getSynchronizer().addRTCPPacket(pkt);
   eventHandler.nudge();
 }