sonos presentation xml image map for image resizing

This commit is contained in:
simojenki
2021-03-13 09:52:54 +11:00
parent 3d1e8a48c9
commit 3373ae773b
9 changed files with 144 additions and 53 deletions

View File

@@ -7,6 +7,7 @@ import {
SOAP_PATH,
STRINGS_ROUTE,
PRESENTATION_MAP_ROUTE,
SONOS_RECOMMENDED_IMAGE_SIZES,
LOGIN_ROUTE,
} from "./smapi";
import { LinkCodes, InMemoryLinkCodes } from "./link_codes";
@@ -101,19 +102,29 @@ function server(
res.type("application/xml").send(`<?xml version="1.0" encoding="utf-8" ?>
<stringtables xmlns="http://sonos.com/sonosapi">
<stringtable rev="1" xml:lang="en-US">
<string stringId="AppLinkMessage">Linking sonos with bonob</string>
<string stringId="string2">string2</string>
<string stringId="AppLinkMessage">Linking sonos with ${bonobService.name}</string>
</stringtable>
<stringtable rev="1" xml:lang="fr-FR">
<string stringId="AppLinkMessage">Linking sonos with bonob fr</string>
<string stringId="string2">string2 fr</string>
<string stringId="AppLinkMessage">Lier les sonos à la ${bonobService.name}</string>
</stringtable>
</stringtables>
`);
});
app.get(PRESENTATION_MAP_ROUTE, (_, res) => {
res.send("");
res.type("application/xml").send(`<?xml version="1.0" encoding="utf-8" ?>
<Presentation>
<PresentationMap type="ArtWorkSizeMap">
<Match>
<imageSizeMap>
${SONOS_RECOMMENDED_IMAGE_SIZES.map(
(size) =>
`<sizeEntry size="${size}" substitution="/art/size/${size}"/>`
)}
</imageSizeMap>
</Match>
</PresentationMap>
</Presentation>`);
});
app.get("/stream/track/:id", async (req, res) => {
@@ -138,7 +149,7 @@ function server(
}
});
app.get("/album/:albumId/art", (req, res) => {
app.get("/album/:albumId/art/size/:size", (req, res) => {
const authToken = accessTokens.authTokenFor(
req.query[BONOB_ACCESS_TOKEN_HEADER] as string
);
@@ -147,7 +158,12 @@ function server(
} else {
return musicService
.login(authToken)
.then((it) => it.coverArt(req.params["albumId"]!, 200))
.then((it) =>
it.coverArt(
req.params["albumId"]!,
Number.parseInt(req.params["size"]!)
)
)
.then((coverArt) => {
res.status(200);
res.setHeader("content-type", coverArt.contentType);

View File

@@ -20,6 +20,21 @@ export const LOGIN_ROUTE = "/login";
export const SOAP_PATH = "/ws/sonos";
export const STRINGS_ROUTE = "/sonos/strings.xml";
export const PRESENTATION_MAP_ROUTE = "/sonos/presentationMap.xml";
export const SONOS_RECOMMENDED_IMAGE_SIZES = [
"60",
"80",
"120",
"180",
"192",
"200",
"230",
"300",
"600",
"640",
"750",
"1242",
"1500",
];
const WSDL_FILE = path.resolve(
__dirname,
@@ -203,7 +218,7 @@ const album = (
itemType: "album",
id: `album:${album.id}`,
title: album.name,
albumArtURI: `${webAddress}/album/${album.id}/art?${BONOB_ACCESS_TOKEN_HEADER}=${accessToken}`,
albumArtURI: `${webAddress}/album/${album.id}/art/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${accessToken}`,
});
const track = (track: Track) => ({

View File

@@ -4,9 +4,11 @@ import { parse } from "node-html-parser";
import { MusicService } from "@svrooij/sonos/lib/services";
import { head } from "underscore";
import logger from "./logger";
import STRINGS from "./strings";
import { SOAP_PATH, STRINGS_ROUTE, PRESENTATION_MAP_ROUTE } from "./smapi";
export const STRINGS_VERSION = "2";
export const PRESENTATION_MAP_VERSION = "7";
export type Device = {
name: string;
group: string;
@@ -40,11 +42,11 @@ export const bonobService = (
secureUri: `${stripTailingSlash(bonobRoot)}${SOAP_PATH}`,
strings: {
uri: `${stripTailingSlash(bonobRoot)}${STRINGS_ROUTE}`,
version: STRINGS.version,
version: STRINGS_VERSION,
},
presentation: {
uri: `${stripTailingSlash(bonobRoot)}${PRESENTATION_MAP_ROUTE}`,
version: "1",
version: PRESENTATION_MAP_VERSION,
},
pollInterval: 1200,
authType,

View File

@@ -1,10 +0,0 @@
const STRINGS = {
version: "1",
values: {
"foo": "bar"
}
}
export default STRINGS;