[Basic UI] Add support for webaudio (#1426)

* [Basic UI] Add support for webaudio
* Add Web Audio configuration option

Signed-off-by: Wouter Born <github@maindrain.net>
pull/1470/head
Wouter Born 2022-08-15 10:43:19 +02:00 committed by GitHub
parent 49a6000c02
commit ba45055f66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 14 deletions

View File

@ -34,8 +34,11 @@ public class WebAppConfig {
public static final String THEME_NAME_DARK = "dark";
private static final String DEFAULT_THEME = THEME_NAME_DEFAULT;
private static final String DEFAULT_WEB_AUDIO = "false";
private String defaultSitemap = DEFAULT_SITEMAP;
private String theme = DEFAULT_THEME;
private boolean webAudio = Boolean.parseBoolean(DEFAULT_WEB_AUDIO);
private List<String> cssClassList = new ArrayList<>();
@ -66,7 +69,7 @@ public class WebAppConfig {
Boolean value = CSS_DEFAULT_VALUES.get(key);
Object configValue = configProps.get(key);
if (configValue != null) {
value = configValue.toString().equalsIgnoreCase("true");
value = "true".equalsIgnoreCase(configValue.toString());
}
if (value != null && value) {
cssClassList.add(entry.getValue());
@ -75,19 +78,9 @@ public class WebAppConfig {
}
public void applyConfig(Map<String, Object> configProps) {
String configDefaultSitemap = (String) configProps.get("defaultSitemap");
String configTheme = (String) configProps.get("theme");
if (configDefaultSitemap == null) {
configDefaultSitemap = DEFAULT_SITEMAP;
}
if (configTheme == null) {
configTheme = DEFAULT_THEME;
}
defaultSitemap = configDefaultSitemap;
theme = configTheme;
defaultSitemap = (String) configProps.getOrDefault("defaultSitemap", DEFAULT_SITEMAP);
theme = (String) configProps.getOrDefault("theme", DEFAULT_THEME);
webAudio = "true".equalsIgnoreCase((String) configProps.getOrDefault("webAudio", DEFAULT_WEB_AUDIO));
applyCssClasses(configProps);
}
@ -107,4 +100,8 @@ public class WebAppConfig {
}
return result;
}
public boolean isWebAudio() {
return webAudio;
}
}

View File

@ -98,6 +98,7 @@ public class PageRenderer extends AbstractWidgetRenderer {
snippet = snippet.replaceAll("%main.long-polling-mode-msg%", longPollingModeMsg);
}
snippet = snippet.replaceAll("%id%", id);
snippet = snippet.replace("%config.web-audio%", Boolean.toString(config.isWebAudio()));
// if the label contains a value span, we remove this span as
// the title of a page/layer cannot deal with this

View File

@ -42,6 +42,15 @@
</options>
<default>false</default>
</parameter>
<parameter name="webAudio" type="text" required="true">
<label>Web Audio</label>
<description>Play audio sent to the web audio sink.</description>
<options>
<option value="true">Enable</option>
<option value="false">Disable</option>
</options>
<default>false</default>
</parameter>
<parameter name="defaultSitemap" type="text" required="false">
<label>Default Sitemap</label>
<description>The sitemap to show if no parameter is passed.</description>

View File

@ -16,6 +16,10 @@ ui.config.basic.theme.label = Theme
ui.config.basic.theme.description = Defines the UI theme.
ui.config.basic.theme.option.default = Default
ui.config.basic.theme.option.dark = Dark
ui.config.basic.webAudio.label = Web Audio
ui.config.basic.webAudio.description = Play audio sent to the web audio sink.
ui.config.basic.webAudio.option.true = Enable
ui.config.basic.webAudio.option.false = Disable
# service

View File

@ -28,6 +28,7 @@
<link rel="stylesheet" type="text/css" href="roboto.css" />
<link rel="stylesheet" type="text/css" href="smarthome.css" />
<script type="application/json" id="config">{"webAudio":%config.web-audio%}</script>
<script src="smarthome.js"></script>
<script src="mdl/material.min.js"></script>
<script type="text/html" id="template-modal">

View File

@ -121,8 +121,10 @@
type = typeof p.type !== "undefined" ? p.type : "GET",
data = typeof p.data !== "undefined" ? p.data : "",
headers = typeof p.headers !== "undefined" ? p.headers : {},
reponseType = typeof p.reponseType !== "undefined" ? p.reponseType : "",
request = new XMLHttpRequest();
request.responseType = reponseType;
request.open(type, p.url, true);
for (var h in headers) {
@ -2313,6 +2315,47 @@
});
}
function PlayAudioUrlListener() {
var
_t = this;
_t.source = new EventSource("/rest/events?topics=openhab/webaudio/playurl");
_t.source.addEventListener("message", function(event) {
var context;
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
if (typeof (window.AudioContext) !== "undefined") {
context = new AudioContext();
}
var data = JSON.parse(event.data);
var audioUrl = JSON.parse(data.payload);
ajax({
url: audioUrl,
type: "GET",
reponseType: "arraybuffer",
callback: function(request) {
context.decodeAudioData(request.response, function(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.onended = function () {
context.close();
};
source.start(0);
});
}
});
}
catch (e) {
if (context) {
context.close();
}
}
});
}
document.addEventListener("DOMContentLoaded", function() {
smarthome.UI = new UI(document);
smarthome.UI.layoutChangeProxy = new VisibilityChangeProxy(100, 50);
@ -2320,6 +2363,10 @@
smarthome.UI.initControls();
smarthome.changeListener = new ChangeListener();
if (JSON.parse(document.getElementById("config").text).webAudio) {
smarthome.playAudioUrlListener = new PlayAudioUrlListener();
}
window.addEventListener("beforeunload", function() {
smarthome.changeListener.suppressErrors();
});