From 66c248fe44bc990b0dcaeceee21f83311faf3cfa Mon Sep 17 00:00:00 2001 From: Simon J Date: Fri, 2 Feb 2024 19:43:53 +1100 Subject: [PATCH] Use transcodedContentType when available to indicate to sonos device the transcoded mimeType #191 (#192) --- .devcontainer/devcontainer.json | 1 + README.md | 6 ------ package.json | 1 + src/subsonic.ts | 3 ++- tests/subsonic.test.ts | 24 ++++++++++++++++++++++++ 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0713b27..c26d8cc 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,6 +10,7 @@ "BNB_DEV_SUBSONIC_URL": "${localEnv:BNB_DEV_SUBSONIC_URL}" }, "remoteUser": "node", + "forwardPorts": [4534], "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { "version": "latest", diff --git a/README.md b/README.md index e1dcc0d..38b5f31 100644 --- a/README.md +++ b/README.md @@ -218,12 +218,6 @@ Afterwards the Sonos app displays a dropdown underneath the service, allowing to - Implement the MusicService/MusicLibrary interface - Startup bonob with your new implementation. -## A note on transcoding - -tldr; Transcoding to mp3/m4a is not supported as sonos devices will not play the track. However transcoding to flac does work, use BNB_SUBSONIC_CUSTOM_CLIENTS=audio/flac if you want to transcode flac->flac ie. to downsample HD flacs (see below). - -Sonos devices are very particular about how audio streams are presented to them, see [streaming basics](https://docs.sonos.com/docs/playback-on-sonos). When using transcoding both Navidrome and Gonic report no 'content-length', nor do they support range queries, this will cause the sonos device to fail to play the track. - ### Audio File type specific transcoding options within Subsonic In some situations you may wish to have different 'Players' within you Subsonic server so that you can configure different transcoding options depending on the file type. For example if you have flacs with a mixture of frequency formats where not all are supported by sonos [See issue #52](https://github.com/simojenki/bonob/issues/52) & [Sonos supported audio formats](https://docs.sonos.com/docs/supported-audio-formats) diff --git a/package.json b/package.json index 022be0b..eaa1bc1 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "devr": "BNB_DISABLE_PLAYLIST_ART=true BNB_LOG_LEVEL=debug BNB_DEBUG=true BNB_SCROBBLE_TRACKS=false BNB_REPORT_NOW_PLAYING=false BNB_SONOS_SEED_HOST=$BNB_DEV_SONOS_DEVICE_IP BNB_SONOS_SERVICE_NAME=z_bonobDev BNB_SONOS_DEVICE_DISCOVERY=true BNB_SONOS_AUTO_REGISTER=true BNB_URL=\"http://${BNB_DEV_HOST_IP}:4534\" BNB_SUBSONIC_URL=\"${BNB_DEV_SUBSONIC_URL}\" nodemon -V ./src/app.ts", "register-dev": "ts-node ./src/register.ts http://${BNB_DEV_HOST_IP}:4534", "test": "jest", + "testw": "jest --watch", "gitinfo": "git describe --tags > .gitinfo" } } diff --git a/src/subsonic.ts b/src/subsonic.ts index 7917e09..e55e726 100644 --- a/src/subsonic.ts +++ b/src/subsonic.ts @@ -163,6 +163,7 @@ export type song = { bitRate: number | undefined; suffix: string | undefined; contentType: string | undefined; + transcodedContentType: string | undefined; type: string | undefined; userRating: number | undefined; starred: string | undefined; @@ -273,7 +274,7 @@ export const artistImageURN = ( export const asTrack = (album: Album, song: song): Track => ({ id: song.id, name: song.title, - mimeType: song.contentType!, + mimeType: song.transcodedContentType ? song.transcodedContentType : song.contentType!, duration: song.duration || 0, number: song.track || 0, genre: maybeAsGenre(song.genre), diff --git a/tests/subsonic.test.ts b/tests/subsonic.test.ts index e2560db..1d77cb1 100644 --- a/tests/subsonic.test.ts +++ b/tests/subsonic.test.ts @@ -322,6 +322,7 @@ const asSongJson = (track: Track) => ({ size: "5624132", suffix: "mp3", contentType: track.mimeType, + transcodedContentType: undefined, isVideo: "false", path: "ACDC/High voltage/ACDC - The Jack.mp3", albumId: track.album.id, @@ -686,8 +687,31 @@ describe("asTrack", () => { }); }); }); + + describe("when the song has a transcodedContentType", () => { + const album = anAlbum(); + + describe("with an undefined value", () => { + const track = aTrack({ mimeType: "sourced-from/mimeType" }); + + it("should fall back on the default mime", () => { + const result = asTrack(album, { ...asSongJson(track), transcodedContentType: undefined }); + expect(result.mimeType).toEqual("sourced-from/mimeType") + }); + }); + + describe("with a value", () => { + const track = aTrack({ mimeType: "sourced-from/mimeType" }); + + it("should use the transcoded value", () => { + const result = asTrack(album, { ...asSongJson(track), transcodedContentType: "sourced-from/transcodedContentType" }); + expect(result.mimeType).toEqual("sourced-from/transcodedContentType") + }); + }); + }); }); + describe("Subsonic", () => { const url = new URLBuilder("http://127.0.0.22:4567/some-context-path"); const username = `user1-${uuid()}`;