diff --git a/src/audio/broadcast/AudioBroadcaster.java b/src/audio/broadcast/AudioBroadcaster.java index b90c1684..3cb4c309 100644 --- a/src/audio/broadcast/AudioBroadcaster.java +++ b/src/audio/broadcast/AudioBroadcaster.java @@ -51,8 +51,10 @@ public abstract class AudioBroadcaster implements Listener private BroadcastState mBroadcastState = BroadcastState.READY; private int mStreamedAudioCount = 0; + private int mAgedOffAudioCount = 0; private BroadcastConfiguration mBroadcastConfiguration; private long mDelay; + private long mMaximumRecordingAge; private AtomicBoolean mStreaming = new AtomicBoolean(); /** @@ -80,6 +82,7 @@ public abstract class AudioBroadcaster implements Listener { mBroadcastConfiguration = broadcastConfiguration; mDelay = mBroadcastConfiguration.getDelay(); + mMaximumRecordingAge = mBroadcastConfiguration.getMaximumRecordingAge(); mSilenceGenerator = BroadcastFactory.getSilenceGenerator(broadcastConfiguration.getBroadcastFormat()); } @@ -178,6 +181,14 @@ public abstract class AudioBroadcaster implements Listener return mStreamedAudioCount; } + /** + * Number of audio recordings that were removed for exceeding age limit + */ + public int getAgedOffAudioCount() + { + return mAgedOffAudioCount; + } + /** * Primary insert method for the stream manager to nominate completed audio recordings for broadcast. * @@ -387,9 +398,22 @@ public abstract class AudioBroadcaster implements Listener mInputStream = null; - //Peek at the next recording but don't remove it from the queue yet, so we can inspect the delay time + //Peek at the next recording but don't remove it from the queue yet, so we can inspect the start time for + //age limits and/or delay elapsed AudioRecording nextRecording = mAudioRecordingQueue.peek(); + //Purge any recordings that have exceeded maximum recording age limit + while(nextRecording != null && + (nextRecording.getStartTime() + mDelay + mMaximumRecordingAge) < java.lang.System.currentTimeMillis()) + { + nextRecording = mAudioRecordingQueue.remove(); + nextRecording.removePendingReplay(); + mAgedOffAudioCount++; + broadcast(new BroadcastEvent(AudioBroadcaster.this, + BroadcastEvent.Event.BROADCASTER_AGED_OFF_COUNT_CHANGE)); + nextRecording = mAudioRecordingQueue.peek(); + } + if(nextRecording != null && nextRecording.getStartTime() + mDelay <= System.currentTimeMillis()) { nextRecording = mAudioRecordingQueue.remove(); diff --git a/src/audio/broadcast/BroadcastConfiguration.java b/src/audio/broadcast/BroadcastConfiguration.java index 312dca96..2a2ee63b 100644 --- a/src/audio/broadcast/BroadcastConfiguration.java +++ b/src/audio/broadcast/BroadcastConfiguration.java @@ -45,6 +45,7 @@ public abstract class BroadcastConfiguration private int mPort; private String mPassword; private long mDelay; + private long mMaximumRecordingAge = 10 * 60 * 1000; //10 minutes default private boolean mEnabled = true; public BroadcastConfiguration() @@ -216,6 +217,27 @@ public abstract class BroadcastConfiguration mDelay = delay; } + /** + * Gets maximum recording age which determines the maximum amount of elapsed time that a recording can set in the + * queue awaiting streaming before it is purged from the queue. This value is in addition to the delay setting. + * @return age in milliseconds + */ + @XmlAttribute(name = "maximum_recording_age") + public long getMaximumRecordingAge() + { + return mMaximumRecordingAge; + } + + /** + * Sets maximum recording age which determines the maximum amount of elapsed time that a recording can set in the + * queue awaiting streaming before it is purged from the queue. This value is in addition to the delay setting. + * @param age in milliseconds + */ + public void setMaximumRecordingAge(long age) + { + mMaximumRecordingAge = age; + } + /** * Indicates if this broadcaster is enable, meaning that it will automatically connect on startup. */ diff --git a/src/audio/broadcast/BroadcastEvent.java b/src/audio/broadcast/BroadcastEvent.java index 6a48bd5e..f7fc4cff 100644 --- a/src/audio/broadcast/BroadcastEvent.java +++ b/src/audio/broadcast/BroadcastEvent.java @@ -20,71 +20,73 @@ package audio.broadcast; public class BroadcastEvent { - private BroadcastConfiguration mBroadcastConfiguration; - private AudioBroadcaster mAudioBroadcaster; - private Event mEvent; + private BroadcastConfiguration mBroadcastConfiguration; + private AudioBroadcaster mAudioBroadcaster; + private Event mEvent; - /** - * AliasEvent - event describing any changes to an alias - * @param configuration - alias that changed - * @param event - change event - */ - public BroadcastEvent(BroadcastConfiguration configuration, Event event ) - { - mBroadcastConfiguration = configuration; - mEvent = event; - } + /** + * AliasEvent - event describing any changes to an alias + * + * @param configuration - alias that changed + * @param event - change event + */ + public BroadcastEvent(BroadcastConfiguration configuration, Event event) + { + mBroadcastConfiguration = configuration; + mEvent = event; + } - public BroadcastEvent(AudioBroadcaster audioBroadcaster, Event event ) - { - mAudioBroadcaster = audioBroadcaster; - mEvent = event; - } + public BroadcastEvent(AudioBroadcaster audioBroadcaster, Event event) + { + mAudioBroadcaster = audioBroadcaster; + mEvent = event; + } - public BroadcastConfiguration getBroadcastConfiguration() - { - return mBroadcastConfiguration; - } + public BroadcastConfiguration getBroadcastConfiguration() + { + return mBroadcastConfiguration; + } - public AudioBroadcaster getAudioBroadcaster() - { - return mAudioBroadcaster; - } + public AudioBroadcaster getAudioBroadcaster() + { + return mAudioBroadcaster; + } - /** - * Indicates if this event pertains to an audio broadcaster - */ - public boolean isAudioBroadcasterEvent() - { - return mAudioBroadcaster != null; - } + /** + * Indicates if this event pertains to an audio broadcaster + */ + public boolean isAudioBroadcasterEvent() + { + return mAudioBroadcaster != null; + } - /** - * Indicates if this event pertains to a broadcast configuration - */ - public boolean isBroadcastConfigurationEvent() - { - return mBroadcastConfiguration != null; - } + /** + * Indicates if this event pertains to a broadcast configuration + */ + public boolean isBroadcastConfigurationEvent() + { + return mBroadcastConfiguration != null; + } - public Event getEvent() - { - return mEvent; - } - - /** - * Channel events to describe the specific event - */ - public enum Event - { - BROADCASTER_ADD, - BROADCASTER_QUEUE_CHANGE, + public Event getEvent() + { + return mEvent; + } + + /** + * Channel events to describe the specific event + */ + public enum Event + { + BROADCASTER_ADD, + BROADCASTER_QUEUE_CHANGE, BROADCASTER_STATE_CHANGE, BROADCASTER_STREAMED_COUNT_CHANGE, - BROADCASTER_DELETE, + BROADCASTER_AGED_OFF_COUNT_CHANGE, + BROADCASTER_DELETE, - CONFIGURATION_ADD, - CONFIGURATION_CHANGE, - CONFIGURATION_DELETE; - } + CONFIGURATION_ADD, + CONFIGURATION_CHANGE, + CONFIGURATION_DELETE; + } } diff --git a/src/audio/broadcast/BroadcastModel.java b/src/audio/broadcast/BroadcastModel.java index 851a9472..04f64f76 100644 --- a/src/audio/broadcast/BroadcastModel.java +++ b/src/audio/broadcast/BroadcastModel.java @@ -60,6 +60,10 @@ public class BroadcastModel extends AbstractTableModel implements Listener