-
-
Save marco79cgn/98616fcbb2dfdbd752b33a452208bcc8 to your computer and use it in GitHub Desktop.
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: cyan; icon-glyph: magic; | |
// the node sonos http api base url (running on your Pi for example) | |
let sonosBaseUrl = "http://192.168.178.10:5005" | |
// optional for cover art: the ip address of one of your Sonos speakers | |
let sonosPlayerUrl = "http://192.168.178.38:1400" | |
let param = args.widgetParameter | |
let nowPlaying = await loadNowPlaying() | |
let widget = await createWidget(nowPlaying) | |
Script.setWidget(widget) | |
Script.complete() | |
//widget.presentSmall() | |
async function createWidget(nowPlaying) { | |
let widget = new ListWidget() | |
widget.setPadding(5, 6, 0, 5) | |
// show album art if configured and available | |
let albumArtUrl = nowPlaying.currentTrack.albumArtUri | |
if(param === "cover" && albumArtUrl != null && albumArtUrl.length > 1) { | |
if(albumArtUrl.indexOf("http") > -1) { | |
let albumArt = await loadImage(albumArtUrl) | |
widget.backgroundImage = albumArt | |
} else { | |
let albumArt = await loadImage(sonosPlayerUrl + nowPlaying.currentTrack.albumArtUri) | |
widget.backgroundImage = albumArt | |
} | |
} | |
// set gradient background | |
let startColor = new Color("#da2f68e6") | |
let endColor = new Color("#c30645b3") | |
let gradient = new LinearGradient() | |
gradient.colors = [startColor, endColor] | |
gradient.locations = [0, 1] | |
widget.backgroundColor = new Color("#b00a0f") | |
widget.backgroundGradient = gradient | |
let sonosLogo = await loadImage("https://pisces.bbystatic.com/image2/BestBuy_US/Gallery/sonos_logo_white_2.png") | |
let image = widget.addImage(sonosLogo) | |
image.imageSize = new Size(35,15) | |
image.centerAlignImage() | |
widget.addSpacer(5) | |
let nowText = widget.addText("NOW PLAYING:") | |
nowText.font = Font.boldSystemFont(12) | |
nowText.textColor = Color.white() | |
nowText.centerAlignText() | |
nowText.textOpacity = 0.8 | |
// add title and artist | |
let shortTitle = "" | |
if (nowPlaying.currentTrack.type === "radio" && albumArtUrl != null && albumArtUrl.indexOf("radioparadise") === -1) { | |
widget.addSpacer(15) | |
if(nowPlaying.currentTrack.title.indexOf("x-sonosapi") === -1) { | |
shortTitle = demasterRadio(nowPlaying.currentTrack.title) | |
} | |
} else { | |
shortTitle = demaster(nowPlaying.currentTrack.title) | |
} | |
let titleTxt = widget.addText(shortTitle) | |
titleTxt.font = Font.semiboldSystemFont(12) | |
titleTxt.textColor = Color.white() | |
titleTxt.centerAlignText() | |
let artistTxt = widget.addText(nowPlaying.currentTrack.artist) | |
artistTxt.font = Font.semiboldSystemFont(12) | |
artistTxt.textColor = Color.cyan() | |
artistTxt.centerAlignText() | |
if (nowPlaying.currentTrack.type !== "radio" || (albumArtUrl != null && albumArtUrl.indexOf("radioparadise") !== -1)) { | |
let separatorText = widget.addText("—") | |
separatorText.textColor = Color.white() | |
separatorText.centerAlignText() | |
separatorText.textOpacity = 0.7 | |
let nextText = widget.addText("NEXT UP:") | |
nextText.font = Font.boldSystemFont(12) | |
nextText.textColor = Color.white() | |
nextText.centerAlignText() | |
nextText.textOpacity = 0.8 | |
// add next title and artist | |
let shortNextTitle = demaster(nowPlaying.nextTrack.title) | |
let nextTitleTxt = widget.addText(shortNextTitle) | |
nextTitleTxt.textColor = Color.white() | |
nextTitleTxt.font = Font.semiboldSystemFont(12) | |
nextTitleTxt.centerAlignText() | |
let nextArtistTxt = widget.addText(nowPlaying.nextTrack.artist) | |
nextArtistTxt.textColor = Color.cyan() | |
nextArtistTxt.font = Font.semiboldSystemFont(12) | |
nextArtistTxt.centerAlignText() | |
} | |
if(config.runsInApp) { | |
let request = new Request(sonosBaseUrl + "/playpause") | |
request.allowInsecureRequest = true | |
let json = await request.loadJSON() | |
Safari.open("shortcuts://run-shortcut?name=SpringBoard") | |
} | |
widget.addSpacer() | |
return widget | |
} | |
// load and parse a restful json api | |
async function loadNowPlaying() { | |
let url = sonosBaseUrl + "/state" | |
let req = new Request(url) | |
req.allowInsecureRequest = true | |
let json = await req.loadJSON() | |
console.log(json) | |
return json | |
} | |
// download an image from a given url | |
async function loadImage(imgUrl) { | |
console.log(imgUrl) | |
let req = new Request(imgUrl) | |
req.allowInsecureRequest = true | |
let image = await req.loadImage() | |
return image | |
} | |
function demaster(trackName) { | |
let shortenedTrackName = trackName.split(" - ") | |
shortenedTrackName = shortenedTrackName[0].split(" (Live") | |
shortenedTrackName = shortenedTrackName[0].split(" (feat") | |
console.log("short name: " + shortenedTrackName[0]) | |
return shortenedTrackName[0] | |
} | |
function demasterRadio(trackName) { | |
let shortenedTrackName = trackName.split(" |") | |
shortenedTrackName = shortenedTrackName[0].split(" --") | |
console.log("short name: " + shortenedTrackName[0]) | |
return shortenedTrackName[0] | |
} |
Hi Marco,
... vielleicht kannst du mit der Fehlermeldung mehr anfangen, und evtl. mir weiterhelfen?
2021-06-09 00:51:45: {"volume":13,"mute":false,"elapsedTimeFormatted":"00:00:00","currentTrack":{"artist":"Radio Brocken","trackUri":"x-sonosapi-stream:rpde_svc_74?sid=232&flags=32&sn=2","albumArtUri":"/getaa?s=1&u=x-sonosapi-stream%3arpde_svc_74%3fsid%3d232%26flags%3d32%26sn%3d2","absoluteAlbumArtUri":"http://192.168.2.115:1400/getaa?s=1&u=x-sonosapi-stream%3arpde_svc_74%3fsid%3d232%26flags%3d32%26sn%3d2","duration":0,"stationName":"Radio Brocken","type":"radio","uri":"x-sonosapi-stream:rpde_svc_74?sid=232&flags=32&sn=2"},"trackNo":1,"elapsedTime":0,"equalizer":{"nightMode":false,"treble":-1,"bass":2,"loudness":true,"speechEnhancement":false},"playbackState":"STOPPED","playMode":{"shuffle":false,"crossfade":false,"repeat":"none"},"nextTrack":{"duration":0,"uri":"","title":"","album":"","albumArtUri":"","artist":""}}
2021-06-09 00:51:45: https://pisces.bbystatic.com/image2/BestBuy_US/Gallery/sonos_logo_white_2.png
2021-06-09 00:51:45: Error on line 60:37: TypeError: undefined is not an object (evaluating 'nowPlaying.currentTrack.title.indexOf')
Danke
Intro
iOS 14 Custom Widget made with the help of the Scriptable app.
The widget shows what's currently playing on your Sonos system. It relies on the node-sonos-http-api which has to be running locally (e.g. on a Raspberry Pi). Once you tap on the widget it toggles the playback state (pause/play).
Requirements
Thanks
A big Thank you to @simonbs for making great apps like Scriptable, DataJar or Jayson.
Changelog
-- display proper information when playing radio
-- showing transparent cover in the background
-- cleanup song information (to avoid unneeded stuff like "Remastered Version" etc.)