#30 - resolves logic issue that was preventing deletion of temporary stream recordings. Changes the streamable recording queue in the AudioBroadcaster to find the recording with the earliest start time to prevent situations where a long recording might close out and enter the broadcast queue after a shorter recording that started later, but would have been replayed first.

This commit is contained in:
Denny
2017-01-07 07:31:47 -05:00
parent bc430b255f
commit 648b12fd16
2 changed files with 34 additions and 15 deletions

View File

@@ -31,6 +31,9 @@ import sample.Listener;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -46,7 +49,7 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
private ScheduledFuture mScheduledTask;
private RecordingQueueProcessor mRecordingQueueProcessor = new RecordingQueueProcessor();
private LinkedTransferQueue<AudioRecording> mAudioRecordingQueue = new LinkedTransferQueue<>();
private List<AudioRecording> mAudioRecordingQueue = new CopyOnWriteArrayList<>();
private ISilenceGenerator mSilenceGenerator;
@@ -256,11 +259,10 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
if(!connected())
{
//Remove all pending audio recordings
AudioRecording recording = mAudioRecordingQueue.poll();
while(recording != null)
while(!mAudioRecordingQueue.isEmpty())
{
recording = mAudioRecordingQueue.poll();
AudioRecording recording = mAudioRecordingQueue.get(0);
recording.removePendingReplay();
}
}
}
@@ -390,24 +392,37 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
mInputStream = null;
AudioRecording nextRecording = mAudioRecordingQueue.peek();
AudioRecording nextRecording = null;
//Find the recording with the earliest start time
Iterator<AudioRecording> it = mAudioRecordingQueue.iterator();
while(it.hasNext())
{
AudioRecording recording = it.next();
if(nextRecording == null || (recording.getStartTime() < nextRecording.getStartTime()))
{
nextRecording = recording;
}
}
if(nextRecording != null && nextRecording.getStartTime() + mDelay <= System.currentTimeMillis())
{
AudioRecording recording = mAudioRecordingQueue.poll();
mAudioRecordingQueue.remove(nextRecording);
try
{
if(Files.exists(recording.getPath()))
if(Files.exists(nextRecording.getPath()))
{
byte[] audio = Files.readAllBytes(recording.getPath());
byte[] audio = Files.readAllBytes(nextRecording.getPath());
if(audio != null && audio.length > 0)
{
mInputStream = new ByteArrayInputStream(audio);
mFinalSilencePadding = PROCESSOR_RUN_INTERVAL_MS -
(recording.getRecordingLength() % PROCESSOR_RUN_INTERVAL_MS);
(nextRecording.getRecordingLength() % PROCESSOR_RUN_INTERVAL_MS);
while(mFinalSilencePadding >= PROCESSOR_RUN_INTERVAL_MS)
{
@@ -416,7 +431,7 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
if(connected())
{
broadcastMetadata(recording.getAudioMetadata());
broadcastMetadata(nextRecording.getAudioMetadata());
}
metadataUpdateRequired = false;
@@ -426,18 +441,18 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
catch(IOException ioe)
{
mLog.error("Stream [" + getBroadcastConfiguration().getName() + "] error reading temporary audio " +
"stream recording [" + recording.getPath().toString() + "] - skipping recording - ", ioe);
"stream recording [" + nextRecording.getPath().toString() + "] - skipping recording - ", ioe);
mInputStream = null;
metadataUpdateRequired = false;
}
recording.removePendingReplay();
nextRecording.removePendingReplay();
broadcast(new BroadcastEvent(AudioBroadcaster.this, BroadcastEvent.Event.BROADCASTER_QUEUE_CHANGE));
}
//If we closed out a recording and don't have anything new, send an empty metadata update
//If we closed out a recording and don't have a new/next recording, send an empty metadata update
if(metadataUpdateRequired && connected())
{
broadcastMetadata(null);

View File

@@ -19,12 +19,16 @@
package audio.broadcast;
import audio.metadata.AudioMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.util.concurrent.atomic.AtomicInteger;
public class AudioRecording implements Comparable<AudioRecording>
{
private final static Logger mLog = LoggerFactory.getLogger(StreamManager.class);
private Path mPath;
private AudioMetadata mAudioMetadata;
private long mStartTime;
@@ -110,6 +114,6 @@ public class AudioRecording implements Comparable<AudioRecording>
*/
public boolean hasPendingReplays()
{
return mPendingReplayCount.get() <= 0;
return mPendingReplayCount.get() > 0;
}
}