//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET: //ORIGINAL LINE: private void handleTrackFrameData(TrackFrameDataMessage message) throws Exception private void handleTrackFrameData(TrackFrameDataMessage message) { RemoteAudioTrackExecutor executor = playingTracks.get(message.executorId); if (executor != null) { if (message.seekedPosition >= 0) { executor.clearSeek(message.seekedPosition); } AudioFrameBuffer buffer = executor.AudioBuffer; executor.receivedData(); AudioDataFormat format = executor.Configuration.OutputFormat; foreach (AudioFrame frame in message.frames) { buffer.consume(new AudioFrame(frame.timecode, frame.data, frame.volume, format)); } if (message.finished) { buffer.setTerminateOnEmpty(); trackEnded(executor, false); } } }
/// <summary> /// Check if there are any playing tracks on a node that has not shown signs of life in too long. In that case its /// playing tracks will also be marked dead. /// </summary> /// <param name="terminate"> Whether to terminate without checking the threshold </param> public virtual void processHealthCheck(bool terminate) { lock (this) { if (playingTracks.Empty || (!terminate && lastAliveTime >= DateTimeHelperClass.CurrentUnixTimeMillis() - TRACK_KILL_THRESHOLD)) { return; } connectionState.set(ConnectionState.OFFLINE.id()); if (!terminate) { log.LogWarning("Bringing node {} offline since last response from it was {}ms ago.", nodeAddress, DateTimeHelperClass.CurrentUnixTimeMillis() - lastAliveTime); } // There may be some racing that manages to add a track after this, it will be dealt with on the next iteration foreach (long?executorId in new IList <RemoteAudioTrackExecutor>(playingTracks.Keys)) { RemoteAudioTrackExecutor executor = playingTracks.remove(executorId); if (executor != null) { abandonedTrackManager.add(executor); } } } }
private void handleTrackException(TrackExceptionMessage message) { RemoteAudioTrackExecutor executor = playingTracks.get(message.executorId); if (executor != null) { executor.dispatchException(message.exception); } }
/// <summary> /// Start playing a track through this remote node. </summary> /// <param name="executor"> The executor of the track </param> public virtual void startPlaying(RemoteAudioTrackExecutor executor) { AudioTrack track = executor.Track; if (playingTracks.PutIfAbsent(executor.ExecutorId, executor) == null) { long position = executor.NextInputTimecode; log.LogInformation("Sending request to play {} {} from position {}", track.Identifier, executor.ExecutorId, position); queuedMessages.add(new TrackStartRequestMessage(executor.ExecutorId, track.Info, playerManager.encodeTrackDetails(track), executor.Volume, executor.Configuration, position)); } }
/// <summary> /// Adds a track executor to abandoned tracks. The abandoned track manager will take over managing its lifecycle and /// the caller should not use it any further. /// </summary> /// <param name="executor"> The executor to register as an abandoned track. </param> public virtual void add(RemoteAudioTrackExecutor executor) { if (abandonedExecutors.offer(new AbandonedExecutor(DateTimeHelperClass.CurrentUnixTimeMillis(), executor))) { log.debug("{} has been put up for adoption.", executor); } else { log.debug("{} has been discarded, adoption queue is full.", executor); executor.dispatchException(new FriendlyException("Cannot find a node to play the track on.", Severity.COMMON, null)); executor.stop(); } }
/// <summary> /// Clear the track from this node. </summary> /// <param name="executor"> Executor of the track </param> /// <param name="notifyNode"> Whether it is necessary to notify the node </param> public virtual void trackEnded(RemoteAudioTrackExecutor executor, bool notifyNode) { if (playingTracks.remove(executor.ExecutorId) != null) { log.LogInformation("Track {} removed from node {} (context {})", executor.Track.Identifier, nodeAddress, executor.ExecutorId); if (notifyNode) { log.LogInformation("Notifying node {} of track stop for {} (context {})", nodeAddress, executor.Track.Identifier, executor.ExecutorId); queuedMessages.add(new TrackStoppedMessage(executor.ExecutorId)); } executor.detach(); } }
private void handleTrackStartResponse(TrackStartResponseMessage message) { if (message.success) { log.LogDebug("Successful start confirmation from node {} for executor {}.", nodeAddress, message.executorId); } else { RemoteAudioTrackExecutor executor = playingTracks.Get(message.executorId); if (executor != null) { executor.dispatchException(new FriendlyException("Remote machine failed to start track: " + message.failureReason, Severity.SUSPICIOUS, null)); executor.stop(); } else { log.LogDebug("Received failed track start for an already stopped executor {} from node {}.", message.executorId, nodeAddress); } } }