import java.io.IOException;
import java.util.Locale;
import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.upnpcontrol.internal.handler.UpnpRendererHandler;
import org.openhab.core.audio.AudioFormat;
import org.openhab.core.audio.AudioHTTPServer;
-import org.openhab.core.audio.AudioSink;
+import org.openhab.core.audio.AudioSinkAsync;
import org.openhab.core.audio.AudioStream;
-import org.openhab.core.audio.FixedLengthAudioStream;
+import org.openhab.core.audio.StreamServed;
import org.openhab.core.audio.URLAudioStream;
import org.openhab.core.audio.UnsupportedAudioFormatException;
import org.openhab.core.audio.UnsupportedAudioStreamException;
/**
*
* @author Mark Herwege - Initial contribution
+ * @author Laurent Garnier - Support for more audio streams through the HTTP audio servlet
*/
@NonNullByDefault
-public class UpnpAudioSink implements AudioSink {
+public class UpnpAudioSink extends AudioSinkAsync {
private final Logger logger = LoggerFactory.getLogger(UpnpAudioSink.class);
- private static final Set<Class<? extends AudioStream>> SUPPORTED_STREAMS = Stream
- .of(AudioStream.class, FixedLengthAudioStream.class).collect(Collectors.toSet());
+ private static final Set<Class<? extends AudioStream>> SUPPORTED_STREAMS = Set.of(AudioStream.class);
protected UpnpRendererHandler handler;
protected AudioHTTPServer audioHTTPServer;
protected String callbackUrl;
}
@Override
- public void process(@Nullable AudioStream audioStream)
+ protected void processAsynchronously(@Nullable AudioStream audioStream)
throws UnsupportedAudioFormatException, UnsupportedAudioStreamException {
if (audioStream == null) {
stopMedia();
return;
}
- String url = null;
- if (audioStream instanceof URLAudioStream) {
- URLAudioStream urlAudioStream = (URLAudioStream) audioStream;
- url = urlAudioStream.getURL();
+ if (audioStream instanceof URLAudioStream urlAudioStream) {
+ playMedia(urlAudioStream.getURL());
+ try {
+ audioStream.close();
+ } catch (IOException e) {
+ }
} else if (!callbackUrl.isEmpty()) {
- String relativeUrl = audioStream instanceof FixedLengthAudioStream
- ? audioHTTPServer.serve((FixedLengthAudioStream) audioStream, 20)
- : audioHTTPServer.serve(audioStream);
- url = String.valueOf(this.callbackUrl) + relativeUrl;
+ StreamServed streamServed;
+ try {
+ streamServed = audioHTTPServer.serve(audioStream, 5, true);
+ } catch (IOException e) {
+ try {
+ audioStream.close();
+ } catch (IOException ex) {
+ }
+ throw new UnsupportedAudioStreamException(
+ handler.getUDN() + " was not able to handle the audio stream (cache on disk failed).",
+ audioStream.getClass(), e);
+ }
+ streamServed.playEnd().thenRun(() -> this.playbackFinished(audioStream));
+ playMedia(callbackUrl + streamServed.url());
} else {
logger.warn("We do not have any callback url, so {} cannot play the audio stream!", handler.getUDN());
- return;
+ try {
+ audioStream.close();
+ } catch (IOException e) {
+ }
}
- playMedia(url);
}
@Override