album art when playing track

This commit is contained in:
simojenki
2021-03-13 11:07:53 +11:00
parent 283b319f87
commit f432d5b11f
2 changed files with 70 additions and 100 deletions

View File

@@ -221,7 +221,7 @@ const album = (
albumArtURI: `${webAddress}/album/${album.id}/art/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${accessToken}`, albumArtURI: `${webAddress}/album/${album.id}/art/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${accessToken}`,
}); });
const track = (track: Track) => ({ export const track = (webAddress: string, accessToken: string, track: Track) => ({
itemType: "track", itemType: "track",
id: `track:${track.id}`, id: `track:${track.id}`,
mimeType: track.mimeType, mimeType: track.mimeType,
@@ -232,7 +232,7 @@ const track = (track: Track) => ({
albumId: track.album.id, albumId: track.album.id,
albumArtist: track.artist.name, albumArtist: track.artist.name,
albumArtistId: track.artist.id, albumArtistId: track.artist.id,
// albumArtURI albumArtURI: `${webAddress}/album/${track.album.id}/art/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${accessToken}`,
artist: track.artist.name, artist: track.artist.name,
artistId: track.artist.id, artistId: track.artist.id,
duration: track.duration, duration: track.duration,
@@ -314,6 +314,7 @@ function bindSmapiSoapServiceToExpress(
}, },
}; };
} }
const authToken = headers.credentials.loginToken.token;
const login = await musicService const login = await musicService
.login(headers.credentials.loginToken.token) .login(headers.credentials.loginToken.token)
.catch((_) => { .catch((_) => {
@@ -327,9 +328,12 @@ function bindSmapiSoapServiceToExpress(
const typeId = id.split(":")[1]; const typeId = id.split(":")[1];
const musicLibrary = login as MusicLibrary; const musicLibrary = login as MusicLibrary;
return musicLibrary return musicLibrary.track(typeId!).then((it) => {
.track(typeId!) const accessToken = accessTokens.mint(authToken);
.then((it) => ({ getMediaMetadataResult: track(it) })); return {
getMediaMetadataResult: track(webAddress, accessToken, it),
};
});
}, },
getMetadata: async ( getMetadata: async (
{ {
@@ -430,13 +434,16 @@ function bindSmapiSoapServiceToExpress(
return await musicLibrary return await musicLibrary
.tracks(typeId!) .tracks(typeId!)
.then(slice2(paging)) .then(slice2(paging))
.then(([page, total]) => .then(([page, total]) => {
getMetadataResult2({ const accessToken = accessTokens.mint(authToken);
mediaMetadata: page.map(track), return getMetadataResult2({
mediaMetadata: page.map((it) =>
track(webAddress, accessToken, it)
),
index: paging._index, index: paging._index,
total, total,
}) });
); });
default: default:
throw `Unsupported id:${id}`; throw `Unsupported id:${id}`;
} }

View File

@@ -5,6 +5,7 @@ import { v4 as uuid } from "uuid";
import { DOMParserImpl } from "xmldom-ts"; import { DOMParserImpl } from "xmldom-ts";
import * as xpath from "xpath-ts"; import * as xpath from "xpath-ts";
import { randomInt } from "crypto";
import { InMemoryLinkCodes, LinkCodes } from "../src/link_codes"; import { InMemoryLinkCodes, LinkCodes } from "../src/link_codes";
import makeServer, { BONOB_ACCESS_TOKEN_HEADER } from "../src/server"; import makeServer, { BONOB_ACCESS_TOKEN_HEADER } from "../src/server";
@@ -16,6 +17,7 @@ import {
getMetadataResult2, getMetadataResult2,
PRESENTATION_MAP_ROUTE, PRESENTATION_MAP_ROUTE,
SONOS_RECOMMENDED_IMAGE_SIZES, SONOS_RECOMMENDED_IMAGE_SIZES,
track,
} from "../src/smapi"; } from "../src/smapi";
import { import {
@@ -124,6 +126,43 @@ describe("getMetadataResult", () => {
}); });
}); });
describe("track", () => {
it("should map into a sonos expected track", () => {
const webAddress = "http://localhost:4567";
const accessToken = uuid();
const someTrack = aTrack({
id: uuid(),
mimeType: "audio/something",
name: "great song",
duration: randomInt(1000),
number: randomInt(100),
album: anAlbum({ name: "great album", id: uuid(), genre: "some genre" }),
artist: anArtist({ name: "great artist", id: uuid() }),
});
expect(track(webAddress, accessToken, someTrack)).toEqual({
itemType: "track",
id: `track:${someTrack.id}`,
mimeType: someTrack.mimeType,
title: someTrack.name,
trackMetadata: {
album: someTrack.album.name,
albumId: someTrack.album.id,
albumArtist: someTrack.artist.name,
albumArtistId: someTrack.artist.id,
albumArtURI: `${webAddress}/album/${someTrack.album.id}/art/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${accessToken}`,
artist: someTrack.artist.name,
artistId: someTrack.artist.id,
duration: someTrack.duration,
genre: someTrack.album.genre,
// genreId
trackNumber: someTrack.number,
},
});
});
});
class Base64AccessTokens implements AccessTokens { class Base64AccessTokens implements AccessTokens {
mint(authToken: string) { mint(authToken: string) {
return Buffer.from(authToken).toString("base64"); return Buffer.from(authToken).toString("base64");
@@ -611,31 +650,6 @@ describe("api", () => {
}); });
}); });
// describe("asking for an album by id", () => {
// it("should return it", async () => {
// musicService.hasArtists(BLONDIE, BOB_MARLEY);
// const album = BOB_MARLEY.albums[0]!;
// const result = await ws.getMetadataAsync({
// id: `album:${album.id}`,
// index: 0,
// count: 100,
// });
// expect(result).toEqual(
// getMetadataResult({
// mediaCollection: [
// ...BLONDIE.albums,
// ...BOB_MARLEY.albums,
// ].map((it) =>
// ({ itemType: "album", id: `album:${it.id}`, title: it.name })
// ),
// index: 0,
// total: BLONDIE.albums.length + BOB_MARLEY.albums.length,
// })
// );
// });
// });
describe("asking for albums", () => { describe("asking for albums", () => {
const artist1 = anArtist({ const artist1 = anArtist({
albums: [anAlbum(), anAlbum(), anAlbum()], albums: [anAlbum(), anAlbum(), anAlbum()],
@@ -740,27 +754,14 @@ describe("api", () => {
}); });
expect(result[0]).toEqual( expect(result[0]).toEqual(
getMetadataResult2({ getMetadataResult2({
mediaMetadata: [track1, track2, track3, track4, track5].map( mediaMetadata: [
(track) => ({ track1,
itemType: "track", track2,
id: `track:${track.id}`, track3,
mimeType: track.mimeType, track4,
title: track.name, track5,
].map((it) =>
trackMetadata: { track(rootUrl, accessTokens.mint(token.authToken), it)
album: track.album.name,
albumId: track.album.id,
albumArtist: track.artist.name,
albumArtistId: track.artist.id,
// albumArtURI
artist: track.artist.name,
artistId: track.artist.id,
duration: track.duration,
genre: track.album.genre,
// genreId
trackNumber: track.number,
},
})
), ),
index: 0, index: 0,
total: 5, total: 5,
@@ -778,26 +779,7 @@ describe("api", () => {
}); });
expect(result[0]).toEqual( expect(result[0]).toEqual(
getMetadataResult2({ getMetadataResult2({
mediaMetadata: [track3, track4].map((track) => ({ mediaMetadata: [track3, track4].map(it => track(rootUrl, accessTokens.mint(token.authToken), it)),
itemType: "track",
id: `track:${track.id}`,
mimeType: track.mimeType,
title: track.name,
trackMetadata: {
album: track.album.name,
albumId: track.album.id,
albumArtist: track.artist.name,
albumArtistId: track.artist.id,
// albumArtURI
artist: track.artist.name,
artistId: track.artist.id,
duration: track.duration,
genre: track.album.genre,
// genreId
trackNumber: track.number,
},
})),
index: 2, index: 2,
total: 5, total: 5,
}) })
@@ -980,7 +962,7 @@ describe("api", () => {
const artist = anArtist({ const artist = anArtist({
albums: [album], albums: [album],
}); });
const track = aTrack(); const someTrack = aTrack();
beforeEach(async () => { beforeEach(async () => {
musicService.hasUser({ username, password }); musicService.hasUser({ username, password });
@@ -995,35 +977,16 @@ describe("api", () => {
ws.addSoapHeader({ credentials: someCredentials(token.authToken) }); ws.addSoapHeader({ credentials: someCredentials(token.authToken) });
musicService.hasArtists(artist); musicService.hasArtists(artist);
musicService.hasTracks(track); musicService.hasTracks(someTrack);
}); });
describe("asking for media metadata for a tack", () => { describe("asking for media metadata for a track", () => {
it("should return it with auth header", async () => { it("should return it with auth header", async () => {
const root = await ws.getMediaMetadataAsync({ const root = await ws.getMediaMetadataAsync({
id: `track:${track.id}`, id: `track:${someTrack.id}`,
}); });
expect(root[0]).toEqual({ expect(root[0]).toEqual({
getMediaMetadataResult: { getMediaMetadataResult: track(rootUrl, accessTokens.mint(token.authToken), someTrack),
itemType: "track",
id: `track:${track.id}`,
mimeType: track.mimeType,
title: track.name,
trackMetadata: {
album: track.album.name,
albumId: track.album.id,
albumArtist: track.artist.name,
albumArtistId: track.artist.id,
// albumArtURI
artist: track.artist.name,
artistId: track.artist.id,
duration: track.duration,
genre: track.album.genre,
// genreId
trackNumber: track.number,
},
},
}); });
}); });
}); });