[squeezebox] Support for more audio streams through the audio servlet (#15194)
* [squeezebox] Support for more audio streams through the audio servlet Audio sink supporting more audio streams --------- Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
This commit is contained in:
parent
11512a9db9
commit
dee79190a9
|
@ -12,17 +12,20 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.squeezebox.internal;
|
package org.openhab.binding.squeezebox.internal;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.squeezebox.internal.handler.SqueezeBoxPlayerHandler;
|
import org.openhab.binding.squeezebox.internal.handler.SqueezeBoxPlayerHandler;
|
||||||
import org.openhab.core.audio.AudioFormat;
|
import org.openhab.core.audio.AudioFormat;
|
||||||
import org.openhab.core.audio.AudioHTTPServer;
|
import org.openhab.core.audio.AudioHTTPServer;
|
||||||
import org.openhab.core.audio.AudioSink;
|
import org.openhab.core.audio.AudioSink;
|
||||||
|
import org.openhab.core.audio.AudioSinkSync;
|
||||||
import org.openhab.core.audio.AudioStream;
|
import org.openhab.core.audio.AudioStream;
|
||||||
import org.openhab.core.audio.FileAudioStream;
|
import org.openhab.core.audio.FileAudioStream;
|
||||||
import org.openhab.core.audio.FixedLengthAudioStream;
|
import org.openhab.core.audio.StreamServed;
|
||||||
import org.openhab.core.audio.URLAudioStream;
|
import org.openhab.core.audio.URLAudioStream;
|
||||||
import org.openhab.core.audio.UnsupportedAudioFormatException;
|
import org.openhab.core.audio.UnsupportedAudioFormatException;
|
||||||
import org.openhab.core.audio.UnsupportedAudioStreamException;
|
import org.openhab.core.audio.UnsupportedAudioStreamException;
|
||||||
|
@ -38,25 +41,17 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Mark Hilbush - Initial contribution
|
* @author Mark Hilbush - Initial contribution
|
||||||
* @author Mark Hilbush - Add callbackUrl
|
* @author Mark Hilbush - Add callbackUrl
|
||||||
*/
|
*/
|
||||||
public class SqueezeBoxAudioSink implements AudioSink {
|
public class SqueezeBoxAudioSink extends AudioSinkSync {
|
||||||
private final Logger logger = LoggerFactory.getLogger(SqueezeBoxAudioSink.class);
|
private final Logger logger = LoggerFactory.getLogger(SqueezeBoxAudioSink.class);
|
||||||
|
|
||||||
private static final HashSet<AudioFormat> SUPPORTED_FORMATS = new HashSet<>();
|
private static final Set<AudioFormat> SUPPORTED_FORMATS = Set.of(AudioFormat.WAV, AudioFormat.MP3);
|
||||||
private static final HashSet<Class<? extends AudioStream>> SUPPORTED_STREAMS = new HashSet<>();
|
private static final Set<Class<? extends AudioStream>> SUPPORTED_STREAMS = Set.of(AudioStream.class);
|
||||||
|
|
||||||
// Needed because Squeezebox does multiple requests for the stream
|
// Needed because Squeezebox does multiple requests for the stream
|
||||||
private static final int STREAM_TIMEOUT = 15;
|
private static final int STREAM_TIMEOUT = 10;
|
||||||
|
|
||||||
private String callbackUrl;
|
private String callbackUrl;
|
||||||
|
|
||||||
static {
|
|
||||||
SUPPORTED_FORMATS.add(AudioFormat.WAV);
|
|
||||||
SUPPORTED_FORMATS.add(AudioFormat.MP3);
|
|
||||||
|
|
||||||
SUPPORTED_STREAMS.add(FixedLengthAudioStream.class);
|
|
||||||
SUPPORTED_STREAMS.add(URLAudioStream.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AudioHTTPServer audioHTTPServer;
|
private AudioHTTPServer audioHTTPServer;
|
||||||
private SqueezeBoxPlayerHandler playerHandler;
|
private SqueezeBoxPlayerHandler playerHandler;
|
||||||
|
|
||||||
|
@ -81,19 +76,26 @@ public class SqueezeBoxAudioSink implements AudioSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(AudioStream audioStream)
|
public void processSynchronously(AudioStream audioStream)
|
||||||
throws UnsupportedAudioFormatException, UnsupportedAudioStreamException {
|
throws UnsupportedAudioFormatException, UnsupportedAudioStreamException {
|
||||||
|
if (audioStream == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
AudioFormat format = audioStream.getFormat();
|
AudioFormat format = audioStream.getFormat();
|
||||||
if (!AudioFormat.WAV.isCompatible(format) && !AudioFormat.MP3.isCompatible(format)) {
|
if (!AudioFormat.WAV.isCompatible(format) && !AudioFormat.MP3.isCompatible(format)) {
|
||||||
|
tryClose(audioStream);
|
||||||
throw new UnsupportedAudioFormatException("Currently only MP3 and WAV formats are supported: ", format);
|
throw new UnsupportedAudioFormatException("Currently only MP3 and WAV formats are supported: ", format);
|
||||||
}
|
}
|
||||||
|
|
||||||
String url;
|
String url;
|
||||||
if (audioStream instanceof URLAudioStream) {
|
if (audioStream instanceof URLAudioStream) {
|
||||||
url = ((URLAudioStream) audioStream).getURL();
|
url = ((URLAudioStream) audioStream).getURL();
|
||||||
} else if (audioStream instanceof FixedLengthAudioStream) {
|
tryClose(audioStream);
|
||||||
// Since Squeezebox will make multiple requests for the stream, set a timeout on the stream
|
} else {
|
||||||
url = audioHTTPServer.serve((FixedLengthAudioStream) audioStream, STREAM_TIMEOUT).toString();
|
try {
|
||||||
|
// Since Squeezebox will make multiple requests for the stream, set multiple to true
|
||||||
|
StreamServed streamServed = audioHTTPServer.serve(audioStream, STREAM_TIMEOUT, true);
|
||||||
|
url = streamServed.url();
|
||||||
|
|
||||||
if (AudioFormat.WAV.isCompatible(format)) {
|
if (AudioFormat.WAV.isCompatible(format)) {
|
||||||
url += AudioStreamUtils.EXTENSION_SEPARATOR + FileAudioStream.WAV_EXTENSION;
|
url += AudioStreamUtils.EXTENSION_SEPARATOR + FileAudioStream.WAV_EXTENSION;
|
||||||
|
@ -101,23 +103,37 @@ public class SqueezeBoxAudioSink implements AudioSink {
|
||||||
url += AudioStreamUtils.EXTENSION_SEPARATOR + FileAudioStream.MP3_EXTENSION;
|
url += AudioStreamUtils.EXTENSION_SEPARATOR + FileAudioStream.MP3_EXTENSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Form the URL for streaming the notification from the OH2 web server
|
// Form the URL for streaming the notification from the OH web server
|
||||||
// Use the callback URL if it is set in the binding configuration
|
// Use the callback URL if it is set in the binding configuration
|
||||||
String host = callbackUrl == null || callbackUrl.isEmpty() ? playerHandler.getHostAndPort() : callbackUrl;
|
String host = callbackUrl == null || callbackUrl.isEmpty() ? playerHandler.getHostAndPort()
|
||||||
|
: callbackUrl;
|
||||||
if (host == null) {
|
if (host == null) {
|
||||||
logger.warn("Unable to get host/port from which to stream notification");
|
logger.warn("Unable to get host/port from which to stream notification");
|
||||||
|
tryClose(audioStream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
url = host + url;
|
url = host + url;
|
||||||
} else {
|
} catch (IOException e) {
|
||||||
|
tryClose(audioStream);
|
||||||
throw new UnsupportedAudioStreamException(
|
throw new UnsupportedAudioStreamException(
|
||||||
"SqueezeBox can only handle URLAudioStream or FixedLengthAudioStreams.", null);
|
"Squeezebox binding was not able to handle the audio stream (cache on disk failed)",
|
||||||
|
audioStream.getClass(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Processing audioStream {} of format {}", url, format);
|
logger.debug("Processing audioStream {} of format {}", url, format);
|
||||||
playerHandler.playNotificationSoundURI(new StringType(url));
|
playerHandler.playNotificationSoundURI(new StringType(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryClose(@Nullable InputStream is) {
|
||||||
|
if (is != null) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<AudioFormat> getSupportedFormats() {
|
public Set<AudioFormat> getSupportedFormats() {
|
||||||
return SUPPORTED_FORMATS;
|
return SUPPORTED_FORMATS;
|
||||||
|
|
Loading…
Reference in New Issue