]> git.basschouten.com Git - openhab-addons.git/blob
4319fa421d2535f13087a62c378a8d44c7a6a7db
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.chromecast.internal;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.openhab.core.audio.AudioFormat;
18 import org.openhab.core.audio.AudioHTTPServer;
19 import org.openhab.core.audio.AudioStream;
20 import org.openhab.core.audio.FixedLengthAudioStream;
21 import org.openhab.core.audio.URLAudioStream;
22 import org.openhab.core.audio.UnsupportedAudioFormatException;
23 import org.openhab.core.library.types.OnOffType;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Handles the AudioSink portion of the Chromecast add-on.
29  *
30  * @author Jason Holmes - Initial contribution
31  */
32 @NonNullByDefault
33 public class ChromecastAudioSink {
34     private final Logger logger = LoggerFactory.getLogger(ChromecastAudioSink.class);
35
36     private static final String MIME_TYPE_AUDIO_WAV = "audio/wav";
37     private static final String MIME_TYPE_AUDIO_MPEG = "audio/mpeg";
38
39     private final ChromecastCommander commander;
40     private final AudioHTTPServer audioHTTPServer;
41     private final @Nullable String callbackUrl;
42
43     public ChromecastAudioSink(ChromecastCommander commander, AudioHTTPServer audioHTTPServer,
44             @Nullable String callbackUrl) {
45         this.commander = commander;
46         this.audioHTTPServer = audioHTTPServer;
47         this.callbackUrl = callbackUrl;
48     }
49
50     public void process(@Nullable AudioStream audioStream) throws UnsupportedAudioFormatException {
51         if (audioStream == null) {
52             // in case the audioStream is null, this should be interpreted as a request to end any currently playing
53             // stream.
54             logger.trace("Stop currently playing stream.");
55             commander.handleCloseApp(OnOffType.ON);
56         } else {
57             final String url;
58             if (audioStream instanceof URLAudioStream) {
59                 // it is an external URL, the speaker can access it itself and play it.
60                 URLAudioStream urlAudioStream = (URLAudioStream) audioStream;
61                 url = urlAudioStream.getURL();
62             } else {
63                 if (callbackUrl != null) {
64                     // we serve it on our own HTTP server
65                     String relativeUrl;
66                     if (audioStream instanceof FixedLengthAudioStream) {
67                         relativeUrl = audioHTTPServer.serve((FixedLengthAudioStream) audioStream, 10);
68                     } else {
69                         relativeUrl = audioHTTPServer.serve(audioStream);
70                     }
71                     url = callbackUrl + relativeUrl;
72                 } else {
73                     logger.warn("We do not have any callback url, so Chromecast cannot play the audio stream!");
74                     return;
75                 }
76             }
77             commander.playMedia("Notification", url,
78                     AudioFormat.MP3.isCompatible(audioStream.getFormat()) ? MIME_TYPE_AUDIO_MPEG : MIME_TYPE_AUDIO_WAV);
79         }
80     }
81 }