Merge pull request #148 from DSheirer/111-broadcaster-queue-management

Resolves #111 - adds 'Maximum Age Limit' setting to streaming queues
This commit is contained in:
Denny Sheirer
2017-01-28 16:08:39 -05:00
committed by GitHub
9 changed files with 267 additions and 75 deletions

View File

@@ -51,8 +51,10 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
private BroadcastState mBroadcastState = BroadcastState.READY; private BroadcastState mBroadcastState = BroadcastState.READY;
private int mStreamedAudioCount = 0; private int mStreamedAudioCount = 0;
private int mAgedOffAudioCount = 0;
private BroadcastConfiguration mBroadcastConfiguration; private BroadcastConfiguration mBroadcastConfiguration;
private long mDelay; private long mDelay;
private long mMaximumRecordingAge;
private AtomicBoolean mStreaming = new AtomicBoolean(); private AtomicBoolean mStreaming = new AtomicBoolean();
/** /**
@@ -80,6 +82,7 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
{ {
mBroadcastConfiguration = broadcastConfiguration; mBroadcastConfiguration = broadcastConfiguration;
mDelay = mBroadcastConfiguration.getDelay(); mDelay = mBroadcastConfiguration.getDelay();
mMaximumRecordingAge = mBroadcastConfiguration.getMaximumRecordingAge();
mSilenceGenerator = BroadcastFactory.getSilenceGenerator(broadcastConfiguration.getBroadcastFormat()); mSilenceGenerator = BroadcastFactory.getSilenceGenerator(broadcastConfiguration.getBroadcastFormat());
} }
@@ -178,6 +181,14 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
return mStreamedAudioCount; 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. * Primary insert method for the stream manager to nominate completed audio recordings for broadcast.
* *
@@ -387,9 +398,22 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
mInputStream = null; 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(); 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()) if(nextRecording != null && nextRecording.getStartTime() + mDelay <= System.currentTimeMillis())
{ {
nextRecording = mAudioRecordingQueue.remove(); nextRecording = mAudioRecordingQueue.remove();

View File

@@ -45,6 +45,7 @@ public abstract class BroadcastConfiguration
private int mPort; private int mPort;
private String mPassword; private String mPassword;
private long mDelay; private long mDelay;
private long mMaximumRecordingAge = 10 * 60 * 1000; //10 minutes default
private boolean mEnabled = true; private boolean mEnabled = true;
public BroadcastConfiguration() public BroadcastConfiguration()
@@ -216,6 +217,27 @@ public abstract class BroadcastConfiguration
mDelay = delay; 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. * Indicates if this broadcaster is enable, meaning that it will automatically connect on startup.
*/ */

View File

@@ -20,71 +20,73 @@ package audio.broadcast;
public class BroadcastEvent public class BroadcastEvent
{ {
private BroadcastConfiguration mBroadcastConfiguration; private BroadcastConfiguration mBroadcastConfiguration;
private AudioBroadcaster mAudioBroadcaster; private AudioBroadcaster mAudioBroadcaster;
private Event mEvent; private Event mEvent;
/** /**
* AliasEvent - event describing any changes to an alias * AliasEvent - event describing any changes to an alias
* @param configuration - alias that changed *
* @param event - change event * @param configuration - alias that changed
*/ * @param event - change event
public BroadcastEvent(BroadcastConfiguration configuration, Event event ) */
{ public BroadcastEvent(BroadcastConfiguration configuration, Event event)
mBroadcastConfiguration = configuration; {
mEvent = event; mBroadcastConfiguration = configuration;
} mEvent = event;
}
public BroadcastEvent(AudioBroadcaster audioBroadcaster, Event event ) public BroadcastEvent(AudioBroadcaster audioBroadcaster, Event event)
{ {
mAudioBroadcaster = audioBroadcaster; mAudioBroadcaster = audioBroadcaster;
mEvent = event; mEvent = event;
} }
public BroadcastConfiguration getBroadcastConfiguration() public BroadcastConfiguration getBroadcastConfiguration()
{ {
return mBroadcastConfiguration; return mBroadcastConfiguration;
} }
public AudioBroadcaster getAudioBroadcaster() public AudioBroadcaster getAudioBroadcaster()
{ {
return mAudioBroadcaster; return mAudioBroadcaster;
} }
/** /**
* Indicates if this event pertains to an audio broadcaster * Indicates if this event pertains to an audio broadcaster
*/ */
public boolean isAudioBroadcasterEvent() public boolean isAudioBroadcasterEvent()
{ {
return mAudioBroadcaster != null; return mAudioBroadcaster != null;
} }
/** /**
* Indicates if this event pertains to a broadcast configuration * Indicates if this event pertains to a broadcast configuration
*/ */
public boolean isBroadcastConfigurationEvent() public boolean isBroadcastConfigurationEvent()
{ {
return mBroadcastConfiguration != null; return mBroadcastConfiguration != null;
} }
public Event getEvent() public Event getEvent()
{ {
return mEvent; return mEvent;
} }
/** /**
* Channel events to describe the specific event * Channel events to describe the specific event
*/ */
public enum Event public enum Event
{ {
BROADCASTER_ADD, BROADCASTER_ADD,
BROADCASTER_QUEUE_CHANGE, BROADCASTER_QUEUE_CHANGE,
BROADCASTER_STATE_CHANGE, BROADCASTER_STATE_CHANGE,
BROADCASTER_STREAMED_COUNT_CHANGE, BROADCASTER_STREAMED_COUNT_CHANGE,
BROADCASTER_DELETE, BROADCASTER_AGED_OFF_COUNT_CHANGE,
BROADCASTER_DELETE,
CONFIGURATION_ADD, CONFIGURATION_ADD,
CONFIGURATION_CHANGE, CONFIGURATION_CHANGE,
CONFIGURATION_DELETE; CONFIGURATION_DELETE;
} }
} }

View File

@@ -60,6 +60,10 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
public static final int COLUMN_BROADCASTER_STATUS = 2; public static final int COLUMN_BROADCASTER_STATUS = 2;
public static final int COLUMN_BROADCASTER_QUEUE_SIZE = 3; public static final int COLUMN_BROADCASTER_QUEUE_SIZE = 3;
public static final int COLUMN_BROADCASTER_STREAMED_COUNT = 4; public static final int COLUMN_BROADCASTER_STREAMED_COUNT = 4;
public static final int COLUMN_BROADCASTER_AGED_OFF_COUNT = 5;
public static final String[] COLUMN_NAMES = new String[]
{"Streaming", "Name", "Status", "Queued", "Streamed", "Aged Off"};
private List<BroadcastConfiguration> mBroadcastConfigurations = new CopyOnWriteArrayList<>(); private List<BroadcastConfiguration> mBroadcastConfigurations = new CopyOnWriteArrayList<>();
private List<AudioRecording> mRecordingQueue = new CopyOnWriteArrayList<>(); private List<AudioRecording> mRecordingQueue = new CopyOnWriteArrayList<>();
@@ -441,6 +445,12 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
fireTableCellUpdated(row, COLUMN_BROADCASTER_STREAMED_COUNT); fireTableCellUpdated(row, COLUMN_BROADCASTER_STREAMED_COUNT);
} }
break; break;
case BROADCASTER_AGED_OFF_COUNT_CHANGE:
if(row >= 0)
{
fireTableCellUpdated(row, COLUMN_BROADCASTER_AGED_OFF_COUNT);
}
break;
} }
} }
@@ -488,7 +498,7 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
@Override @Override
public int getColumnCount() public int getColumnCount()
{ {
return 5; return COLUMN_NAMES.length;
} }
@Override @Override
@@ -545,6 +555,14 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
return audioBroadcasterC.getStreamedAudioCount(); return audioBroadcasterC.getStreamedAudioCount();
} }
break; break;
case COLUMN_BROADCASTER_AGED_OFF_COUNT:
AudioBroadcaster audioBroadcasterD = mBroadcasterMap.get(configuration.getName());
if(audioBroadcasterD != null)
{
return audioBroadcasterD.getAgedOffAudioCount();
}
break;
default: default:
break; break;
} }
@@ -589,18 +607,9 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
@Override @Override
public String getColumnName(int column) public String getColumnName(int column)
{ {
switch(column) if(0 <= column && column < COLUMN_NAMES.length)
{ {
case COLUMN_SERVER_ICON: return COLUMN_NAMES[column];
return "Streaming";
case COLUMN_STREAM_NAME:
return "Name";
case COLUMN_BROADCASTER_STATUS:
return "Status";
case COLUMN_BROADCASTER_QUEUE_SIZE:
return "Queued";
case COLUMN_BROADCASTER_STREAMED_COUNT:
return "Streamed";
} }
return null; return null;

View File

@@ -52,6 +52,8 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
private JTextField mFeedID; private JTextField mFeedID;
private JSlider mDelay; private JSlider mDelay;
private JLabel mDelayValue; private JLabel mDelayValue;
private JSlider mMaximumRecordingAge;
private JLabel mMaximumRecordingAgeValue;
private JCheckBox mEnabled; private JCheckBox mEnabled;
private JButton mSaveButton; private JButton mSaveButton;
private JButton mResetButton; private JButton mResetButton;
@@ -66,7 +68,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
private void init() private void init()
{ {
setLayout(new MigLayout("fill,wrap 2", "[align right][grow,fill]", setLayout(new MigLayout("fill,wrap 2", "[align right][grow,fill]",
"[][][][][][][][][][][][][grow,fill]")); "[][][][][][][][][][][][][][][grow,fill]"));
setPreferredSize(new Dimension(150, 400)); setPreferredSize(new Dimension(150, 400));
@@ -157,6 +159,28 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
mDelay.setToolTipText("Audio broadcast delay in minutes"); mDelay.setToolTipText("Audio broadcast delay in minutes");
add(mDelay); add(mDelay);
add(new JLabel());
mMaximumRecordingAgeValue = new JLabel("1 Minute");
add(mMaximumRecordingAgeValue);
add(new JLabel("Age Limit:"));
mMaximumRecordingAge = new JSlider(1,60,5);
mMaximumRecordingAge.setMajorTickSpacing(10);
mMaximumRecordingAge.setMinorTickSpacing(5);
mMaximumRecordingAge.addChangeListener(new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent e)
{
int value = mMaximumRecordingAge.getValue();
mMaximumRecordingAgeValue.setText(value + " Minute" + (value > 1 ? "s" : ""));
setModified(true);
}
});
mMaximumRecordingAge.setToolTipText("Maximum recording age (in addition to delay) to stream");
add(mMaximumRecordingAge);
mEnabled = new JCheckBox("Enabled"); mEnabled = new JCheckBox("Enabled");
mEnabled.setToolTipText("Enable (checked) or disable this stream"); mEnabled.setToolTipText("Enable (checked) or disable this stream");
mEnabled.addActionListener(new ActionListener() mEnabled.addActionListener(new ActionListener()
@@ -223,6 +247,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
mPassword.setText(config.getPassword()); mPassword.setText(config.getPassword());
mFeedID.setText(String.valueOf(config.getFeedID())); mFeedID.setText(String.valueOf(config.getFeedID()));
mDelay.setValue((int) (config.getDelay() / ONE_MINUTE_MS)); mDelay.setValue((int) (config.getDelay() / ONE_MINUTE_MS));
mMaximumRecordingAge.setValue((int)config.getMaximumRecordingAge() / ONE_MINUTE_MS);
mEnabled.setSelected(config.isEnabled()); mEnabled.setSelected(config.isEnabled());
} }
else else
@@ -234,6 +259,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
mPassword.setText(null); mPassword.setText(null);
mFeedID.setText(null); mFeedID.setText(null);
mDelay.setValue(0); mDelay.setValue(0);
mMaximumRecordingAge.setValue(1);
mEnabled.setSelected(false); mEnabled.setSelected(false);
} }
@@ -254,6 +280,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
config.setPassword(mPassword.getText()); config.setPassword(mPassword.getText());
config.setFeedID(getFeedID()); config.setFeedID(getFeedID());
config.setDelay(mDelay.getValue() * ONE_MINUTE_MS); config.setDelay(mDelay.getValue() * ONE_MINUTE_MS);
config.setMaximumRecordingAge(mMaximumRecordingAge.getValue() * ONE_MINUTE_MS);
config.setEnabled(mEnabled.isSelected()); config.setEnabled(mEnabled.isSelected());
setModified(false); setModified(false);

View File

@@ -54,6 +54,8 @@ public class IcecastHTTPConfigurationEditor extends BroadcastConfigurationEditor
private JCheckBox mPublic; private JCheckBox mPublic;
private JSlider mDelay; private JSlider mDelay;
private JLabel mDelayValue; private JLabel mDelayValue;
private JSlider mMaximumRecordingAge;
private JLabel mMaximumRecordingAgeValue;
private JCheckBox mEnabled; private JCheckBox mEnabled;
private JButton mSaveButton; private JButton mSaveButton;
private JButton mResetButton; private JButton mResetButton;
@@ -67,7 +69,7 @@ public class IcecastHTTPConfigurationEditor extends BroadcastConfigurationEditor
private void init() private void init()
{ {
setLayout( new MigLayout( "fill,wrap 2", "[align right][grow,fill]", setLayout( new MigLayout( "fill,wrap 2", "[align right][grow,fill]",
"[][][][][][][][][][][][][][][grow,fill]" ) ); "[][][][][][][][][][][][][][][][][grow,fill]" ) );
setPreferredSize(new Dimension(150,400)); setPreferredSize(new Dimension(150,400));
JLabel channelLabel = new JLabel("Icecast 2 (v2.4+) Stream"); JLabel channelLabel = new JLabel("Icecast 2 (v2.4+) Stream");
@@ -158,6 +160,28 @@ public class IcecastHTTPConfigurationEditor extends BroadcastConfigurationEditor
mDelay.setToolTipText("Audio broadcast delay in minutes"); mDelay.setToolTipText("Audio broadcast delay in minutes");
add(mDelay); add(mDelay);
add(new JLabel());
mMaximumRecordingAgeValue = new JLabel("1 Minute");
add(mMaximumRecordingAgeValue);
add(new JLabel("Age Limit:"));
mMaximumRecordingAge = new JSlider(1,60,5);
mMaximumRecordingAge.setMajorTickSpacing(10);
mMaximumRecordingAge.setMinorTickSpacing(5);
mMaximumRecordingAge.addChangeListener(new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent e)
{
int value = mMaximumRecordingAge.getValue();
mMaximumRecordingAgeValue.setText(value + " Minute" + (value > 1 ? "s" : ""));
setModified(true);
}
});
mMaximumRecordingAge.setToolTipText("Maximum recording age (in addition to delay) to stream");
add(mMaximumRecordingAge);
add(new JLabel("Enabled:")); add(new JLabel("Enabled:"));
mEnabled = new JCheckBox(); mEnabled = new JCheckBox();
mEnabled.setToolTipText("Enable (checked) or disable this stream"); mEnabled.setToolTipText("Enable (checked) or disable this stream");
@@ -227,6 +251,7 @@ public class IcecastHTTPConfigurationEditor extends BroadcastConfigurationEditor
mGenre.setText(config.getGenre()); mGenre.setText(config.getGenre());
mPublic.setSelected(config.isPublic()); mPublic.setSelected(config.isPublic());
mDelay.setValue((int)(config.getDelay() / ONE_MINUTE_MS)); mDelay.setValue((int)(config.getDelay() / ONE_MINUTE_MS));
mMaximumRecordingAge.setValue((int)config.getMaximumRecordingAge() / ONE_MINUTE_MS);
mEnabled.setSelected(config.isEnabled()); mEnabled.setSelected(config.isEnabled());
} }
else else
@@ -241,6 +266,7 @@ public class IcecastHTTPConfigurationEditor extends BroadcastConfigurationEditor
mGenre.setText(null); mGenre.setText(null);
mPublic.setSelected(true); mPublic.setSelected(true);
mDelay.setValue(0); mDelay.setValue(0);
mMaximumRecordingAge.setValue(1);
mEnabled.setSelected(false); mEnabled.setSelected(false);
} }
@@ -264,6 +290,7 @@ public class IcecastHTTPConfigurationEditor extends BroadcastConfigurationEditor
config.setGenre(mGenre.getText()); config.setGenre(mGenre.getText());
config.setPublic(mPublic.isSelected()); config.setPublic(mPublic.isSelected());
config.setDelay(mDelay.getValue() * ONE_MINUTE_MS); config.setDelay(mDelay.getValue() * ONE_MINUTE_MS);
config.setMaximumRecordingAge(mMaximumRecordingAge.getValue() * ONE_MINUTE_MS);
config.setEnabled(mEnabled.isSelected()); config.setEnabled(mEnabled.isSelected());
setModified(false); setModified(false);

View File

@@ -53,6 +53,8 @@ public class IcecastTCPConfigurationEditor extends BroadcastConfigurationEditor
private JCheckBox mPublic; private JCheckBox mPublic;
private JSlider mDelay; private JSlider mDelay;
private JLabel mDelayValue; private JLabel mDelayValue;
private JSlider mMaximumRecordingAge;
private JLabel mMaximumRecordingAgeValue;
private JCheckBox mEnabled; private JCheckBox mEnabled;
private JButton mSaveButton; private JButton mSaveButton;
private JButton mResetButton; private JButton mResetButton;
@@ -66,7 +68,7 @@ public class IcecastTCPConfigurationEditor extends BroadcastConfigurationEditor
private void init() private void init()
{ {
setLayout( new MigLayout( "fill,wrap 2", "[align right][grow,fill]", setLayout( new MigLayout( "fill,wrap 2", "[align right][grow,fill]",
"[][][][][][][][][][][][][][grow,fill]" ) ); "[][][][][][][][][][][][][][][][grow,fill]" ) );
setPreferredSize(new Dimension(150,400)); setPreferredSize(new Dimension(150,400));
JLabel channelLabel = new JLabel("Icecast (v2.3) Stream"); JLabel channelLabel = new JLabel("Icecast (v2.3) Stream");
@@ -151,6 +153,28 @@ public class IcecastTCPConfigurationEditor extends BroadcastConfigurationEditor
mDelay.setToolTipText("Audio broadcast delay in minutes"); mDelay.setToolTipText("Audio broadcast delay in minutes");
add(mDelay); add(mDelay);
add(new JLabel());
mMaximumRecordingAgeValue = new JLabel("1 Minute");
add(mMaximumRecordingAgeValue);
add(new JLabel("Age Limit:"));
mMaximumRecordingAge = new JSlider(1,60,5);
mMaximumRecordingAge.setMajorTickSpacing(10);
mMaximumRecordingAge.setMinorTickSpacing(5);
mMaximumRecordingAge.addChangeListener(new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent e)
{
int value = mMaximumRecordingAge.getValue();
mMaximumRecordingAgeValue.setText(value + " Minute" + (value > 1 ? "s" : ""));
setModified(true);
}
});
mMaximumRecordingAge.setToolTipText("Maximum recording age (in addition to delay) to stream");
add(mMaximumRecordingAge);
add(new JLabel("Enabled:")); //Empty add(new JLabel("Enabled:")); //Empty
mEnabled = new JCheckBox(); mEnabled = new JCheckBox();
mEnabled.setToolTipText("Enable (checked) or disable this stream"); mEnabled.setToolTipText("Enable (checked) or disable this stream");
@@ -219,6 +243,7 @@ public class IcecastTCPConfigurationEditor extends BroadcastConfigurationEditor
mGenre.setText(config.getGenre()); mGenre.setText(config.getGenre());
mPublic.setSelected(config.isPublic()); mPublic.setSelected(config.isPublic());
mDelay.setValue((int)(config.getDelay() / ONE_MINUTE_MS)); mDelay.setValue((int)(config.getDelay() / ONE_MINUTE_MS));
mMaximumRecordingAge.setValue((int)config.getMaximumRecordingAge() / ONE_MINUTE_MS);
mEnabled.setSelected(config.isEnabled()); mEnabled.setSelected(config.isEnabled());
} }
else else
@@ -232,6 +257,7 @@ public class IcecastTCPConfigurationEditor extends BroadcastConfigurationEditor
mGenre.setText(null); mGenre.setText(null);
mPublic.setSelected(true); mPublic.setSelected(true);
mDelay.setValue(0); mDelay.setValue(0);
mMaximumRecordingAge.setValue(1);
mEnabled.setSelected(false); mEnabled.setSelected(false);
} }
@@ -254,6 +280,7 @@ public class IcecastTCPConfigurationEditor extends BroadcastConfigurationEditor
config.setGenre(mGenre.getText()); config.setGenre(mGenre.getText());
config.setPublic(mPublic.isSelected()); config.setPublic(mPublic.isSelected());
config.setDelay(mDelay.getValue() * ONE_MINUTE_MS); config.setDelay(mDelay.getValue() * ONE_MINUTE_MS);
config.setMaximumRecordingAge(mMaximumRecordingAge.getValue() * ONE_MINUTE_MS);
config.setEnabled(mEnabled.isSelected()); config.setEnabled(mEnabled.isSelected());
setModified(false); setModified(false);

View File

@@ -51,6 +51,8 @@ public class ShoutcastV1ConfigurationEditor extends BroadcastConfigurationEditor
private JCheckBox mPublic; private JCheckBox mPublic;
private JSlider mDelay; private JSlider mDelay;
private JLabel mDelayValue; private JLabel mDelayValue;
private JSlider mMaximumRecordingAge;
private JLabel mMaximumRecordingAgeValue;
private JCheckBox mEnabled; private JCheckBox mEnabled;
private JButton mSaveButton; private JButton mSaveButton;
private JButton mResetButton; private JButton mResetButton;
@@ -64,7 +66,7 @@ public class ShoutcastV1ConfigurationEditor extends BroadcastConfigurationEditor
private void init() private void init()
{ {
setLayout(new MigLayout("fill,wrap 2", "[align right][grow,fill]", setLayout(new MigLayout("fill,wrap 2", "[align right][grow,fill]",
"[][][][][][][][][][][][][][grow,fill]")); "[][][][][][][][][][][][][][][][grow,fill]"));
setPreferredSize(new Dimension(150, 400)); setPreferredSize(new Dimension(150, 400));
JLabel channelLabel = new JLabel("Shoutcast (v1.x) Stream"); JLabel channelLabel = new JLabel("Shoutcast (v1.x) Stream");
@@ -143,6 +145,28 @@ public class ShoutcastV1ConfigurationEditor extends BroadcastConfigurationEditor
mDelay.setToolTipText("Audio broadcast delay in minutes"); mDelay.setToolTipText("Audio broadcast delay in minutes");
add(mDelay); add(mDelay);
add(new JLabel());
mMaximumRecordingAgeValue = new JLabel("1 Minute");
add(mMaximumRecordingAgeValue);
add(new JLabel("Age Limit:"));
mMaximumRecordingAge = new JSlider(1,60,5);
mMaximumRecordingAge.setMajorTickSpacing(10);
mMaximumRecordingAge.setMinorTickSpacing(5);
mMaximumRecordingAge.addChangeListener(new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent e)
{
int value = mMaximumRecordingAge.getValue();
mMaximumRecordingAgeValue.setText(value + " Minute" + (value > 1 ? "s" : ""));
setModified(true);
}
});
mMaximumRecordingAge.setToolTipText("Maximum recording age (in addition to delay) to stream");
add(mMaximumRecordingAge);
add(new JLabel("Enabled:")); //Empty add(new JLabel("Enabled:")); //Empty
mEnabled = new JCheckBox(); mEnabled = new JCheckBox();
mEnabled.setToolTipText("Enable (checked) or disable this stream"); mEnabled.setToolTipText("Enable (checked) or disable this stream");
@@ -210,6 +234,7 @@ public class ShoutcastV1ConfigurationEditor extends BroadcastConfigurationEditor
mDescription.setText(config.getDescription()); mDescription.setText(config.getDescription());
mPublic.setSelected(config.isPublic()); mPublic.setSelected(config.isPublic());
mDelay.setValue((int) (config.getDelay() / ONE_MINUTE_MS)); mDelay.setValue((int) (config.getDelay() / ONE_MINUTE_MS));
mMaximumRecordingAge.setValue((int)config.getMaximumRecordingAge() / ONE_MINUTE_MS);
mEnabled.setSelected(config.isEnabled()); mEnabled.setSelected(config.isEnabled());
} }
else else
@@ -222,6 +247,7 @@ public class ShoutcastV1ConfigurationEditor extends BroadcastConfigurationEditor
mDescription.setText(null); mDescription.setText(null);
mPublic.setSelected(true); mPublic.setSelected(true);
mDelay.setValue(0); mDelay.setValue(0);
mMaximumRecordingAge.setValue(1);
mEnabled.setSelected(false); mEnabled.setSelected(false);
} }
@@ -243,6 +269,7 @@ public class ShoutcastV1ConfigurationEditor extends BroadcastConfigurationEditor
config.setGenre(mGenre.getText()); config.setGenre(mGenre.getText());
config.setPublic(mPublic.isSelected()); config.setPublic(mPublic.isSelected());
config.setDelay(mDelay.getValue() * ONE_MINUTE_MS); config.setDelay(mDelay.getValue() * ONE_MINUTE_MS);
config.setMaximumRecordingAge(mMaximumRecordingAge.getValue() * ONE_MINUTE_MS);
config.setEnabled(mEnabled.isSelected()); config.setEnabled(mEnabled.isSelected());
setModified(false); setModified(false);

View File

@@ -52,6 +52,8 @@ public class ShoutcastV2ConfigurationEditor extends BroadcastConfigurationEditor
private JCheckBox mPublic; private JCheckBox mPublic;
private JSlider mDelay; private JSlider mDelay;
private JLabel mDelayValue; private JLabel mDelayValue;
private JSlider mMaximumRecordingAge;
private JLabel mMaximumRecordingAgeValue;
private JCheckBox mEnabled; private JCheckBox mEnabled;
private JButton mSaveButton; private JButton mSaveButton;
private JButton mResetButton; private JButton mResetButton;
@@ -65,7 +67,7 @@ public class ShoutcastV2ConfigurationEditor extends BroadcastConfigurationEditor
private void init() private void init()
{ {
setLayout(new MigLayout("fill,wrap 2", "[align right][grow,fill]", setLayout(new MigLayout("fill,wrap 2", "[align right][grow,fill]",
"[][][][][][][][][][][][][][grow,fill]")); "[][][][][][][][][][][][][][][][grow,fill]"));
setPreferredSize(new Dimension(150, 400)); setPreferredSize(new Dimension(150, 400));
JLabel channelLabel = new JLabel("Shoutcast (v2) Stream"); JLabel channelLabel = new JLabel("Shoutcast (v2) Stream");
@@ -150,6 +152,28 @@ public class ShoutcastV2ConfigurationEditor extends BroadcastConfigurationEditor
mDelay.setToolTipText("Audio broadcast delay in minutes"); mDelay.setToolTipText("Audio broadcast delay in minutes");
add(mDelay); add(mDelay);
add(new JLabel());
mMaximumRecordingAgeValue = new JLabel("1 Minute");
add(mMaximumRecordingAgeValue);
add(new JLabel("Age Limit:"));
mMaximumRecordingAge = new JSlider(1,60,5);
mMaximumRecordingAge.setMajorTickSpacing(10);
mMaximumRecordingAge.setMinorTickSpacing(5);
mMaximumRecordingAge.addChangeListener(new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent e)
{
int value = mMaximumRecordingAge.getValue();
mMaximumRecordingAgeValue.setText(value + " Minute" + (value > 1 ? "s" : ""));
setModified(true);
}
});
mMaximumRecordingAge.setToolTipText("Maximum recording age (in addition to delay) to stream");
add(mMaximumRecordingAge);
add(new JLabel("Enabled:")); //Empty add(new JLabel("Enabled:")); //Empty
mEnabled = new JCheckBox(); mEnabled = new JCheckBox();
mEnabled.setToolTipText("Enable (checked) or disable this stream"); mEnabled.setToolTipText("Enable (checked) or disable this stream");
@@ -218,6 +242,7 @@ public class ShoutcastV2ConfigurationEditor extends BroadcastConfigurationEditor
mGenre.setText(config.getGenre()); mGenre.setText(config.getGenre());
mPublic.setSelected(config.isPublic()); mPublic.setSelected(config.isPublic());
mDelay.setValue((int) (config.getDelay() / ONE_MINUTE_MS)); mDelay.setValue((int) (config.getDelay() / ONE_MINUTE_MS));
mMaximumRecordingAge.setValue((int)config.getMaximumRecordingAge() / ONE_MINUTE_MS);
mEnabled.setSelected(config.isEnabled()); mEnabled.setSelected(config.isEnabled());
} }
else else
@@ -231,6 +256,7 @@ public class ShoutcastV2ConfigurationEditor extends BroadcastConfigurationEditor
mGenre.setText(null); mGenre.setText(null);
mPublic.setSelected(true); mPublic.setSelected(true);
mDelay.setValue(0); mDelay.setValue(0);
mMaximumRecordingAge.setValue(1);
mEnabled.setSelected(false); mEnabled.setSelected(false);
} }
@@ -253,6 +279,7 @@ public class ShoutcastV2ConfigurationEditor extends BroadcastConfigurationEditor
config.setGenre(mGenre.getText()); config.setGenre(mGenre.getText());
config.setPublic(mPublic.isSelected()); config.setPublic(mPublic.isSelected());
config.setDelay(mDelay.getValue() * ONE_MINUTE_MS); config.setDelay(mDelay.getValue() * ONE_MINUTE_MS);
config.setMaximumRecordingAge(mMaximumRecordingAge.getValue() * ONE_MINUTE_MS);
config.setEnabled(mEnabled.isSelected()); config.setEnabled(mEnabled.isSelected());
setModified(false); setModified(false);