package net.pterodactylus.sonitus.data;
import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
import com.google.common.collect.Lists;
*/
public abstract class AbstractControlledComponent implements ControlledComponent {
+ /** The name of this filter. */
+ private final String name;
+
/** The list of metadata listeners. */
- private final List<MetadataListener> metadataListeners = Lists.newArrayList();
+ private final List<MetadataListener> metadataListeners = Lists.newCopyOnWriteArrayList();
+
+ /** The current metadata. */
+ private AtomicReference<Metadata> metadata = new AtomicReference<Metadata>();
+
+ /**
+ * Creates a new abstract controlled component.
+ *
+ * @param name
+ * The name of the component
+ */
+ protected AbstractControlledComponent(String name) {
+ this.name = name;
+ }
//
// LISTENER MANAGEMENT
}
//
+ // CONTROLLEDCOMPONENT METHODS
+ //
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public Metadata metadata() {
+ return metadata.get();
+ }
+
+ @Override
+ public void metadataUpdated(Metadata metadata) {
+ if (metadata.equals(this.metadata.get())) {
+ return;
+ }
+ this.metadata.set(metadata);
+ fireMetadataUpdated(metadata);
+ }
+
+ //
// EVENT METHODS
//
*/
public List<Controller<?>> controllers();
+ /**
+ * Notifies the sink that the metadata of the audio stream has changed. This
+ * method should return as fast as possible, i.e. every heavy lifting should be
+ * done from another thread.
+ *
+ * @param metadata
+ * The new metadata
+ */
+ void metadataUpdated(Metadata metadata);
+
}
Metadata firstMetadata = null;
while (!stopped.get()) {
try {
- final Metadata lastMetadata = firstMetadata;
- final Metadata metadata = firstMetadata = source.metadata();
final byte[] buffer;
try {
logger.finest(String.format("Getting %d bytes from %s...", 4096, source));
@Override
public Void call() throws Exception {
- if (!metadata.equals(lastMetadata)) {
- sink.metadataUpdated(metadata);
- }
try {
logger.finest(String.format("Sending %d bytes to %s.", buffer.length, sink));
sink.process(buffer);
*/
void process(byte[] buffer) throws IOException;
- /**
- * Notifies the sink that the metadata of the audio stream has changed. This
- * method should return as fast as possible, i.e. every heavy lifting should be
- * done from another thread.
- *
- * @param metadata
- * The new metadata
- */
- void metadataUpdated(Metadata metadata);
-
}
+++ /dev/null
-/*
- * Sonitus - MetadataUpdated.java - Copyright © 2013 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sonitus.data.event;
-
-import net.pterodactylus.sonitus.data.ControlledComponent;
-import net.pterodactylus.sonitus.data.Metadata;
-
-/**
- * Event that notifies all listeners that the {@link Metadata} of a {@link
- * ControlledComponent} component was changed.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MetadataUpdated {
-
- /** The controlled component. */
- private final ControlledComponent controlledComponent;
-
- /** The new metadata. */
- private final Metadata metadata;
-
- /**
- * Creates a new metadata updated event.
- *
- * @param controlledComponent
- * The controlled component
- * @param metadata
- * The new metadata
- */
- public MetadataUpdated(ControlledComponent controlledComponent, Metadata metadata) {
- this.controlledComponent = controlledComponent;
- this.metadata = metadata;
- }
-
- //
- // ACCESSORS
- //
-
- /**
- * Returns the controlled component.
- *
- * @return The controlled component
- */
- public ControlledComponent controlled() {
- return controlledComponent;
- }
-
- /**
- * Returns the new metadata.
- *
- * @return The new metadata
- */
- public Metadata metadata() {
- return metadata;
- }
-
-}
import net.pterodactylus.sonitus.data.Filter;
import net.pterodactylus.sonitus.io.ProcessingOutputStream;
-import com.google.common.eventbus.EventBus;
-
/**
* {@link Filter} implementation that can process audio samples internally.
*
/**
* Creates a new audio processing filter with the given name.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
*/
- protected AudioProcessingFilter(EventBus eventBus, String name) {
- super(eventBus, name);
+ protected AudioProcessingFilter(String name) {
+ super(name);
}
//
import net.pterodactylus.sonitus.data.Controller;
import net.pterodactylus.sonitus.data.Filter;
import net.pterodactylus.sonitus.data.Metadata;
-import net.pterodactylus.sonitus.data.event.MetadataUpdated;
-import com.google.common.eventbus.EventBus;
import com.google.common.io.Closeables;
/**
*/
public class DummyFilter extends AbstractControlledComponent implements Filter {
- /** The name of this filter. */
- private final String name;
-
- /** The event bus. */
- private final EventBus eventBus;
-
/** The input stream from which to read. */
private InputStream inputStream;
/** The output stream to which to write. */
private OutputStream outputStream;
- /** The current metadata. */
- private Metadata metadata;
-
/**
* Creates a new dummy filter with the given name.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
*/
- public DummyFilter(EventBus eventBus, String name) {
- this.eventBus = eventBus;
- this.name = name;
+ public DummyFilter(String name) {
+ super(name);
}
//
//
@Override
- public String name() {
- return name;
- }
-
- @Override
public List<Controller<?>> controllers() {
return Collections.emptyList();
}
}
@Override
- public Metadata metadata() {
- return metadata;
- }
-
- @Override
- public void metadataUpdated(Metadata metadata) {
- this.metadata = metadata;
- fireMetadataUpdated(metadata);
- eventBus.post(new MetadataUpdated(this, metadata));
- }
-
- @Override
public void process(byte[] buffer) throws IOException {
outputStream.write(buffer);
outputStream.flush();
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import com.google.common.eventbus.EventBus;
/**
* {@link net.pterodactylus.sonitus.data.Filter} implementation that runs its
/**
* Creates a new external filter with the given name.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
*/
- protected ExternalFilter(EventBus eventBus, String name) {
- super(eventBus, name);
+ protected ExternalFilter(String name) {
+ super(name);
}
//
import net.pterodactylus.sonitus.data.Metadata;
-import com.google.common.eventbus.EventBus;
-
/**
* Basic {@link net.pterodactylus.sonitus.data.filter.ExternalFilter}
* implementation that verifies that the connected source is MP3-encoded and
/**
* Creates a new external MP3 decoder.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
*/
- protected ExternalMp3Decoder(EventBus eventBus, String name) {
- super(eventBus, name);
+ protected ExternalMp3Decoder(String name) {
+ super(name);
}
@Override
import net.pterodactylus.sonitus.data.Metadata;
-import com.google.common.eventbus.EventBus;
-
/**
* Basic {@link net.pterodactylus.sonitus.data.filter.ExternalFilter}
* implementation that verifies that the connected source is PCM-encoded and
/**
* Creates a new external MP3 encoder.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
*/
- protected ExternalMp3Encoder(EventBus eventBus, String name) {
- super(eventBus, name);
+ protected ExternalMp3Encoder(String name) {
+ super(name);
}
@Override
import net.pterodactylus.sonitus.data.Metadata;
import com.google.common.collect.ImmutableList;
-import com.google.common.eventbus.EventBus;
/**
* Decoder {@link net.pterodactylus.sonitus.data.Filter} for FLAC files.
/**
* Creates a new FLAC decoder.
*
- * @param eventBus
- * The event bus
* @param binary
* The location of the binary
*/
- public FlacDecoder(EventBus eventBus, String binary) {
- super(eventBus, "FLAC Decoder");
+ public FlacDecoder(String binary) {
+ super("FLAC Decoder");
this.binary = binary;
}
import net.pterodactylus.sonitus.data.Metadata;
import com.google.common.collect.ImmutableList;
-import com.google.common.eventbus.EventBus;
/**
* {@link ExternalMp3Decoder} implementation that uses LAME to decode an MP3.
/**
* Creates a new LAME MP3 decoder.
*
- * @param eventBus
- * The event bus
* @param binary
* The location of the binary
*/
- public LameMp3Decoder(EventBus eventBus, String binary) {
- super(eventBus, "LAME Decoder");
+ public LameMp3Decoder(String binary) {
+ super("LAME Decoder");
this.binary = binary;
}
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
-import com.google.common.eventbus.EventBus;
/**
* {@link ExternalMp3Encoder} implementation that uses LAME to encode MP3s.
/**
* Creates a new LAME MP3 encoder.
*
- * @param eventBus
- * The event bus
* @param binary
* The location of the binary
* @param preset
- * The preset to use
*/
- public LameMp3Encoder(EventBus eventBus, String binary, Preset preset) {
- this(eventBus, binary, preset, -1);
+ public LameMp3Encoder(String binary, Preset preset) {
+ this(binary, preset, -1);
}
/**
* Creates a new LAME MP3 encoder.
*
- * @param eventBus
- * The event bus
* @param binary
* The location of the binary
* @param bitrate
- * The bitrate to encode to (in kbps)
*/
- public LameMp3Encoder(EventBus eventBus, String binary, int bitrate) {
- this(eventBus, binary, null, bitrate);
+ public LameMp3Encoder(String binary, int bitrate) {
+ this(binary, null, bitrate);
}
/**
* Creates a new LAME MP3 encoder.
*
- * @param eventBus
- * The event bus
* @param binary
* The location of the binary
* @param preset
* The preset to use
* @param bitrate
- * The bitrate to encode to (in kbps)
*/
- private LameMp3Encoder(EventBus eventBus, String binary, Preset preset, int bitrate) {
- super(eventBus, "LAME Encoder");
+ private LameMp3Encoder(String binary, Preset preset, int bitrate) {
+ super("LAME Encoder");
this.binary = binary;
this.preset = Optional.fromNullable(preset);
this.bitrate = (bitrate < 0) ? Optional.<Integer>absent() : Optional.<Integer>of(bitrate);
import net.pterodactylus.sonitus.data.Metadata;
import com.google.common.collect.ImmutableList;
-import com.google.common.eventbus.EventBus;
/**
* Ogg Vorbis decoder that uses {@code oggdec} (from the {@code vorbis-tools}
/**
* Creates a new Ogg Vorbis decoder.
*
- * @param eventBus
- * The event bus
* @param binary
* The location of the binary
*/
- public OggVorbisDecoder(EventBus eventBus, String binary) {
- super(eventBus, "Ogg Vorbis Decoder");
+ public OggVorbisDecoder(String binary) {
+ super("Ogg Vorbis Decoder");
this.binary = binary;
}
import net.pterodactylus.sonitus.data.Metadata;
import com.google.common.base.Predicate;
-import com.google.common.eventbus.EventBus;
/**
* {@link Filter} implementation that uses a {@link Predicate} to determine
/**
* Creates a new predicate filter.
*
- * @param eventBus
- * The event bus
* @param metadataPredicate
* The predicate to evaluate every time the metadata changes
* @param filter
- * The filter to use if the predicate matches the metadata
*/
- public PredicateFilter(EventBus eventBus, Predicate<Metadata> metadataPredicate, Filter filter) {
- super(eventBus, String.format("%s (maybe)", filter.name()));
+ public PredicateFilter(Predicate<Metadata> metadataPredicate, Filter filter) {
+ super(String.format("%s (maybe)", filter.name()));
this.metadataPredicate = metadataPredicate;
this.filter = filter;
}
}
@Override
- public Metadata metadata() {
- if (metadataMatches.get()) {
- return filter.metadata();
- } else {
- return super.metadata();
- }
- }
-
- @Override
public byte[] get(int bufferSize) throws IOException {
if (metadataMatches.get()) {
return filter.get(bufferSize);
import net.pterodactylus.sonitus.data.Metadata;
-import com.google.common.eventbus.EventBus;
-
/**
* Rate limiting filter that only passes a specified amount of data per second
* from its {@link net.pterodactylus.sonitus.data.Source} to its {@link
/**
* Creates a new rate limiting filter.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
* @param rate
- * The limiting rate (in bytes/second)
*/
- public RateLimitingFilter(EventBus eventBus, String name, int rate) {
- this(eventBus, name, rate, 0);
+ public RateLimitingFilter(String name, int rate) {
+ this(name, rate, 0);
}
/**
* Creates a new rate limiting filter.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
* @param rate
* The limiting rate (in bytes/second)
* @param fastStartTime
* The amount of time at the start of the filtering during which no delay
- * will occur (in milliseconds)
*/
- public RateLimitingFilter(EventBus eventBus, String name, int rate, long fastStartTime) {
- super(eventBus, name);
+ public RateLimitingFilter(String name, int rate, long fastStartTime) {
+ super(name);
this.rate = rate;
this.counter = (long) (-rate * (fastStartTime / 1000.0));
}
import net.pterodactylus.sonitus.data.Metadata;
import com.google.common.collect.ImmutableList;
-import com.google.common.eventbus.EventBus;
/**
* {@link net.pterodactylus.sonitus.data.Filter} implementation that uses {@code
/**
* Creates a new resample filter.
*
- * @param eventBus
- * The event bus
* @param binary
* The location of the binary
* @param rate
- * The new sampling rate
*/
- public SoxResampleFilter(EventBus eventBus, String binary, int rate) {
- super(eventBus, String.format("Resample to %s kHz", rate / 1000.0));
+ public SoxResampleFilter(String binary, int rate) {
+ super(String.format("Resample to %s kHz", rate / 1000.0));
this.binary = binary;
this.rate = rate;
}
import net.pterodactylus.sonitus.data.Filter;
import net.pterodactylus.sonitus.data.controller.Knob;
-import com.google.common.eventbus.EventBus;
-
/**
* {@link Filter} implementation that can reduce the stereo width of a signal,
* or even reverse the channels.
/** The separation knob. */
private final Knob separationKnob;
- /**
- * Creates a new stereo separation filter.
- *
- * @param eventBus
- * The event bus
- */
- public StereoSeparationFilter(EventBus eventBus) {
- super(eventBus, "Stereo Separation");
+ /** Creates a new stereo separation filter. */
+ public StereoSeparationFilter() {
+ super("Stereo Separation");
separationKnob = new Knob("Separation", 1.0);
}
import net.pterodactylus.sonitus.data.Filter;
import net.pterodactylus.sonitus.data.Metadata;
-import com.google.common.eventbus.EventBus;
-
/**
* {@link Filter} implementation that uses the number of bytes that have been
* {@link #process(byte[]) processed} together with the {@link Metadata} to
* Creates a new time counter filter that automatically resets the counter when
* the metadata is {@link #metadataUpdated(Metadata) updated}.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
*/
- public TimeCounterFilter(EventBus eventBus, String name) {
- this(eventBus, name, true);
+ public TimeCounterFilter(String name) {
+ this(name, true);
}
/**
* Creates a new time counter filter.
*
- * @param eventBus
- * The event bus
* @param name
* The name of the filter
* @param resetOnMetadataUpdate
* {@code true} if the counter should automatically be reset if the metadata
* is updated, {@code false} otherwise
*/
- public TimeCounterFilter(EventBus eventBus, String name, boolean resetOnMetadataUpdate) {
- super(eventBus, name);
+ public TimeCounterFilter(String name, boolean resetOnMetadataUpdate) {
+ super(name);
this.resetOnMetadataUpdate = resetOnMetadataUpdate;
}
import net.pterodactylus.sonitus.data.controller.Fader;
import net.pterodactylus.sonitus.data.controller.Switch;
-import com.google.common.eventbus.EventBus;
-
/**
* Internal {@link Filter} implementation that can reduce the volume of the
* signal.
/** The mute switch. */
private final Switch muteSwitch;
- /**
- * Creates a new volume filter.
- *
- * @param eventBus
- * The event bus
- */
- public VolumeFilter(EventBus eventBus) {
- super(eventBus, "Volume");
+ /** Creates a new volume filter. */
+ public VolumeFilter() {
+ super("Volume");
volumeFader = new Fader("Volume", 1.0);
muteSwitch = new Switch("Mute", false);
}
import net.pterodactylus.sonitus.data.Source;
import net.pterodactylus.sonitus.data.controller.Fader;
import net.pterodactylus.sonitus.data.controller.Switch;
-import net.pterodactylus.sonitus.data.event.MetadataUpdated;
import net.pterodactylus.sonitus.io.IntegralWriteOutputStream;
import com.google.common.base.Preconditions;
-import com.google.common.eventbus.EventBus;
/**
* {@link Sink} implementation that uses the JDK’s {@link AudioSystem} to play
/** The logger. */
private static final Logger logger = Logger.getLogger(AudioSink.class.getName());
- /** The event bus. */
- private final EventBus eventBus;
-
/** The volume fader. */
private final Fader volumeFader;
/** The “mute” switch. */
private final Switch muteSwitch;
- /** The current metadata. */
- private Metadata metadata;
-
/** The audio output. */
private SourceDataLine sourceDataLine;
}
}, 1024);
- /**
- * Creates a new audio sink.
- *
- * @param eventBus
- * The event bus
- */
- public AudioSink(EventBus eventBus) {
- this.eventBus = eventBus;
+ /** Creates a new audio sink. */
+ public AudioSink() {
+ super("Audio Output");
volumeFader = new Fader("Volume") {
@Override
//
@Override
- public String name() {
- return "Audio Output";
- }
-
- @Override
- public Metadata metadata() {
- return metadata;
- }
-
- @Override
public List<Controller<?>> controllers() {
return Arrays.<Controller<?>>asList(volumeFader, muteSwitch);
}
@Override
public void metadataUpdated(Metadata metadata) {
- logger.info(String.format("Now playing %s.", metadata));
- this.metadata = metadata;
- fireMetadataUpdated(metadata);
- eventBus.post(new MetadataUpdated(this, metadata));
+ super.metadataUpdated(metadata);
+ logger.fine(String.format("Now playing %s.", metadata));
}
@Override
import net.pterodactylus.sonitus.data.Controller;
import net.pterodactylus.sonitus.data.Metadata;
import net.pterodactylus.sonitus.data.Sink;
-import net.pterodactylus.sonitus.data.event.MetadataUpdated;
-
-import com.google.common.eventbus.EventBus;
/**
* {@link net.pterodactylus.sonitus.data.Sink} that writes all received data
/** The logger. */
private static final Logger logger = Logger.getLogger(FileSink.class.getName());
- /** The event bus. */
- private final EventBus eventBus;
-
/** The path of the file to write to. */
private final String path;
/** The output stream writing to the file. */
private FileOutputStream fileOutputStream;
- /** The current metadata. */
- private Metadata metadata;
-
/**
* Creates a new file sink that will write to the given path.
*
- * @param eventBus
- * The event bus
* @param path
* The path of the file to write to
*/
- public FileSink(EventBus eventBus, String path) {
- this.eventBus = eventBus;
+ public FileSink(String path) {
+ super(path);
this.path = path;
}
//
@Override
- public String name() {
- return path;
- }
-
- @Override
- public Metadata metadata() {
- return metadata;
- }
-
- @Override
public List<Controller<?>> controllers() {
return Collections.emptyList();
}
}
@Override
- public void metadataUpdated(Metadata metadata) {
- this.metadata = metadata;
- fireMetadataUpdated(metadata);
- eventBus.post(new MetadataUpdated(this, metadata));
- }
-
- @Override
public void process(byte[] buffer) throws IOException {
fileOutputStream.write(buffer);
logger.finest(String.format("FileSink: Wrote %d Bytes.", buffer.length));
import net.pterodactylus.sonitus.data.Controller;
import net.pterodactylus.sonitus.data.Metadata;
import net.pterodactylus.sonitus.data.Sink;
-import net.pterodactylus.sonitus.data.event.MetadataUpdated;
import net.pterodactylus.sonitus.io.InputStreamDrainer;
-import com.google.common.eventbus.EventBus;
import com.google.common.io.BaseEncoding;
import com.google.common.io.Closeables;
/** The logger. */
private static final Logger logger = Logger.getLogger(Icecast2Sink.class.getName());
- /** The event bus. */
- private final EventBus eventBus;
-
/** The server name. */
private final String server;
/** The output stream to the server. */
private OutputStream socketOutputStream;
- /** The current metadata. */
- private Metadata metadata;
-
/**
* Creates a new Icecast2 sink.
*
* {@code true} to publish the server in a public directory, {@code false} to
* not publish it
*/
- public Icecast2Sink(EventBus eventBus, String server, int port, String password, String mountPoint, String serverName, String serverDescription, String genre, boolean publishServer) {
- this.eventBus = eventBus;
+ public Icecast2Sink(String server, int port, String password, String mountPoint, String serverName, String serverDescription, String genre, boolean publishServer) {
+ super(String.format("icecast://%s:%d/%s", server, port, mountPoint));
this.server = server;
this.port = port;
this.password = password;
//
@Override
- public String name() {
- return String.format("icecast://%s:%d/%s", server, port, mountPoint);
- }
-
- @Override
- public Metadata metadata() {
- return metadata;
- }
-
- @Override
public List<Controller<?>> controllers() {
return Collections.emptyList();
}
@Override
public void metadataUpdated(final Metadata metadata) {
- this.metadata = metadata;
+ super.metadataUpdated(metadata);
new Thread(new Runnable() {
@Override
}
}
}).start();
- fireMetadataUpdated(metadata);
- eventBus.post(new MetadataUpdated(this, metadata));
}
@Override
/** The path of the file. */
private final String path;
- /** The identified metadata of the file. */
- private final Metadata metadata;
-
/** The input stream. */
private InputStream fileInputStream;
* if the file can not be found, or an I/O error occurs
*/
public FileSource(String path) throws IOException {
+ super(path);
this.path = checkNotNull(path, "path must not be null");
fileInputStream = new FileInputStream(path);
/* identify file type. */
Optional<IdentifyingInputStream> identifyingInputStream = IdentifyingInputStream.create(new FileInputStream(path));
if (identifyingInputStream.isPresent()) {
- metadata = identifyingInputStream.get().metadata();
+ metadataUpdated(identifyingInputStream.get().metadata());
} else {
/* fallback. */
- metadata = new Metadata().name(path);
+ metadataUpdated(new Metadata().name(path));
}
}
//
@Override
- public String name() {
- return path;
- }
-
- @Override
public List<Controller<?>> controllers() {
return Collections.emptyList();
}
return Arrays.copyOf(buffer, read);
}
- @Override
- public Metadata metadata() {
- return metadata;
- }
-
//
// OBJECT METHODS
//
@Override
public String toString() {
- return String.format("%s (%s)", path, metadata);
+ return String.format("%s (%s)", path, metadata());
}
}
import net.pterodactylus.sonitus.data.AbstractControlledComponent;
import net.pterodactylus.sonitus.data.Controller;
-import net.pterodactylus.sonitus.data.Metadata;
import net.pterodactylus.sonitus.data.Source;
-import net.pterodactylus.sonitus.data.event.MetadataUpdated;
import net.pterodactylus.sonitus.data.event.SourceFinishedEvent;
import com.google.common.eventbus.EventBus;
/**
* Creates a new multi source.
- *
- * @param eventBus
- * The event bus
*/
@Inject
public MultiSource(EventBus eventBus) {
+ super("Multisource");
this.eventBus = eventBus;
}
sourceChanged = true;
this.source.notifyAll();
}
- fireMetadataUpdated(source.metadata());
- eventBus.post(new MetadataUpdated(this, source.metadata()));
+ metadataUpdated(source.metadata());
logger.info(String.format("Next Source set: %s", source));
}
}
//
@Override
- public String name() {
- return "Multisource";
- }
-
- @Override
public List<Controller<?>> controllers() {
return Collections.emptyList();
}
//
@Override
- public Metadata metadata() {
- return source.get().metadata();
- }
-
- @Override
public byte[] get(int bufferSize) throws EOFException, IOException {
while (true) {
try {
import net.pterodactylus.sonitus.data.FormatMetadata;
import net.pterodactylus.sonitus.data.Metadata;
import net.pterodactylus.sonitus.data.Source;
-import net.pterodactylus.sonitus.data.event.MetadataUpdated;
import net.pterodactylus.sonitus.io.MetadataStream;
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
-import com.google.common.eventbus.EventBus;
import com.google.common.primitives.Ints;
/**
*/
public class StreamSource extends AbstractControlledComponent implements Source {
- /** The event bus. */
- private final EventBus eventBus;
-
/** The URL of the stream. */
private final String streamUrl;
/** The metadata stream. */
private final MetadataStream metadataStream;
- /** The current metadata. */
- private Metadata metadata;
-
/**
* Creates a new stream source. This will also connect to the server and parse
* the response header for vital information (sampling frequency, number of
* @throws IOException
* if an I/O error occurs
*/
- public StreamSource(EventBus eventBus, String streamUrl) throws IOException {
- this.eventBus = eventBus;
+ public StreamSource(String streamUrl) throws IOException {
+ super(null);
this.streamUrl = streamUrl;
URL url = new URL(streamUrl);
throw new IllegalArgumentException(String.format("Invalid Metadata Interval header: %s", metadataIntervalHeader));
}
- metadata = new Metadata(new FormatMetadata(audioParameters.get("ice-channels"), audioParameters.get("ice-samplerate"), "MP3"), new ContentMetadata());
+ metadataUpdated(new Metadata(new FormatMetadata(audioParameters.get("ice-channels"), audioParameters.get("ice-samplerate"), "MP3"), new ContentMetadata()));
metadataStream = new MetadataStream(new BufferedInputStream(httpUrlConnection.getInputStream()), metadataInterval);
streamName = httpUrlConnection.getHeaderField("ICY-Name");
}
public Metadata metadata() {
Optional<ContentMetadata> streamMetadata = metadataStream.getContentMetadata();
if (!streamMetadata.isPresent()) {
- return metadata;
+ return super.metadata();
}
- metadata = metadata.title(streamMetadata.get().title());
- fireMetadataUpdated(metadata);
- eventBus.post(new MetadataUpdated(this, metadata));
- return metadata;
+ metadataUpdated(super.metadata().title(streamMetadata.get().title()));
+ return super.metadata();
}
@Override
@Override
public String toString() {
- return String.format("StreamSource(%s,%s)", streamUrl, metadata);
+ return String.format("StreamSource(%s,%s)", streamUrl, metadata());
}
}