Ralph_Cramden
Major Contributor
- Joined
- Dec 6, 2020
- Messages
- 2,998
- Likes
- 3,988
A very basic example of a responsive web page displaying the current track on your WiiM Mini. Just install the Python requirements (xmltodict,upnpclient), update the IP address in server.py to point to your WiiM Mini, chmod +x server.py, and start it up. Point your browser to http://localhost:8080 I'm running it on a Chromebook (in a Linux instance), but anything that runs Python should work.
server.py:
wiim.html:
server.py:
Python:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import http.server
import socketserver
from urllib.parse import urlparse
from urllib.parse import parse_qs
import json
import xmltodict
import upnpclient
class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
# Extract query param
action = ''
query_components = parse_qs(urlparse(self.path).query)
if 'action' in query_components:
action = query_components["action"][0]
content_type = "application/json"
self.send_response(200)
self.send_header("Content-type", content_type)
self.end_headers()
if action == "getdata":
####################################################################
#### Change the ip address to that of your WiiM Mini
d = upnpclient.Device("http://192.168.68.112:49152/description.xml")
####################################################################
obj = d.AVTransport.GetMediaInfo(InstanceID='0')
meta = obj['CurrentURIMetaData']
items = xmltodict.parse(meta)["DIDL-Lite"]["item"]
self.wfile.write(str.encode(json.dumps(items)))
return
else:
self.path = 'wiim.html'
return http.server.SimpleHTTPRequestHandler.do_GET(self)
# Create an object of the above class
handler_object = MyHttpRequestHandler
PORT = 8080
my_server = socketserver.TCPServer(("", PORT), handler_object)
# Start the server
my_server.serve_forever()
wiim.html:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WiiM Mini</title>
<style>
body {
background-color: grey;
}
h1 {
color: blue;
font-family: verdana;
font-size: 300%;
}
p {
color: white;
font-family: veranda;
font-size: 180%;
margin: 10px 10px 10px 25px;
}
div.container {
width: 96%;
max-width: 1200px;
/* to center the container */
}
img { width: 100%; height: auto; }
.columns {
Width: 100%;
max-width: 1200px;
}
.column {
width:100%;
}
@media (min-width: 48em) {
.column {
width: 50%;
float:left;
}
.columns {
content: "";
display: table;
clear: both;
}
}
</style>
</head>
<body>
<div id="myData" class="columns">
<div id="albumcover" class="column"></div>
<div class="column">
<p id="title"></p>
<p id="album"></p>
<p id="artist"></p>
<p id="info"></p>
</div>
<script>
function fetchJson() {
fetch('?action=getdata')
.then(function (response) {
return response.json();
})
.then(function (data) {
updateData(data);
})
.catch(function (err) {
console.log('error: ' + err);
});
}
function updateData(data) {
var mainContainer = document.getElementById("myData");
var div = document.getElementById("albumcover");
div.innerHTML = '<img src="' + data['upnp:albumArtURI'] + '" style="width:100%;"</img>';
var el = document.getElementById("title");
el.innerHTML = data['dc:title'];
el = document.getElementById("artist");
el.innerHTML = data['upnp:artist'];
el = document.getElementById("album");
el.innerHTML = data['upnp:album'];
var depth = data['song:format_s'];
if(depth > 24) depth=24;
var actualQuality = data['song:actualQuality'];
var rate = data['song:rate_hz'] / 1000.0;
var bitrate = data['song:bitrate'] / 1000.0;
el = document.getElementById("info");
el.innerHTML = `${depth} bits / ${rate} kHz ${bitrate} kbps`
}
setInterval(fetchJson,1000);
fetchJson();
</script>
</body>
</html>
Last edited: