Skip to content

Commit

Permalink
Fix issue where transcoded files would not play, provide support for …
Browse files Browse the repository at this point in the history
…custom clients to transcode (#194)
  • Loading branch information
simojenki authored Feb 7, 2024
1 parent 6bf89b8 commit 9b9a348
Show file tree
Hide file tree
Showing 10 changed files with 801 additions and 524 deletions.
7 changes: 7 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,12 @@
"version": "latest",
"moby": true
}
},
"customizations": {
"vscode": {
"extensions": [
"esbenp.prettier-vscode"
]
}
}
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ Support for Subsonic API clones (tested against Navidrome and Gonic).
- Discovery of sonos devices using seed IP address
- Auto registration with sonos on start
- Multiple registrations within a single household.
- Transcoding support for flacs using a specific player for the flac mimeType bonob/sonos
- Transcoding within subsonic clone
- Custom players by mime type, allowing custom transcoding rules for different file types

## Running

Expand Down Expand Up @@ -163,15 +164,14 @@ BNB_URL | http://$(hostname):4534 | URL (including path) for bonob so that sonos
BNB_SECRET | bonob | secret used for encrypting credentials
BNB_AUTH_TIMEOUT | 1h | Timeout for the sonos auth token, described in the format [ms](https://github.com/vercel/ms), ie. '5s' == 5 seconds, '11h' == 11 hours. In the case of using Navidrome this should be less than the value for ND_SESSIONTIMEOUT
BNB_LOG_LEVEL | info | Log level. One of ['debug', 'info', 'warn', 'error']
BNB_DISABLE_PLAYLIST_ART | undefined | Disables playlist art generation, ie. when there are many playlists and art generation takes too long
BNB_SERVER_LOG_REQUESTS | false | Whether or not to log http requests
BNB_SONOS_AUTO_REGISTER | false | Whether or not to try and auto-register on startup
BNB_SONOS_DEVICE_DISCOVERY | true | Enable/Disable sonos device discovery entirely. Setting this to 'false' will disable sonos device search, regardless of whether a seed host is specified.
BNB_SONOS_SEED_HOST | undefined | sonos device seed host for discovery, or ommitted for for auto-discovery
BNB_SONOS_SERVICE_NAME | bonob | service name for sonos
BNB_SONOS_SERVICE_ID | 246 | service id for sonos
BNB_SUBSONIC_URL | http://$(hostname):4533 | URL for subsonic clone
BNB_SUBSONIC_CUSTOM_CLIENTS | undefined | Comma delimeted mime types for custom subsonic clients when streaming. ie. "audio/flac,audio/ogg" would use client = 'bonob+audio/flac' for flacs, and 'bonob+audio/ogg' for oggs.
BNB_SUBSONIC_CUSTOM_CLIENTS | undefined | Comma delimeted mime types for custom subsonic clients when streaming. Must specify by the source mime type and the transcoded mime type. For example; <p>If you want to simply re-encode some flacs, then you could specify just "audio/flac". <p>However; if your subsonic server will transcode the track then you need to specify the resulting mime type, ie. "audio/flac>audio/mp3" <p>If you want to specify many something like; "audio/flac>audio/mp3,audio/ogg" would use client = 'bonob+audio/flac' for flacs, and 'bonob+audio/ogg' for oggs. <p>!!! Getting this configuration wrong will confuse SONOS as it will expect the wrong mime type for a track, as a result it will not play. Use with care...
BNB_SUBSONIC_ARTIST_IMAGE_CACHE | undefined | Path for caching of artist images that are sourced externally. ie. Navidrome provides spotify URLs. Remember to provide a volume-mapping for Docker, when enabling this cache.
BNB_SCROBBLE_TRACKS | true | Whether to scrobble the playing of a track if it has been played for >30s
BNB_REPORT_NOW_PLAYING | true | Whether to report a track as now playing
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@
"scripts": {
"clean": "rm -Rf build node_modules",
"build": "tsc",
"dev": "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_URL=\"http://${BNB_DEV_HOST_IP}:4534\" BNB_SUBSONIC_URL=\"${BNB_DEV_SUBSONIC_URL}\" nodemon -V ./src/app.ts",
"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",
"dev": "BNB_SUBSONIC_CUSTOM_CLIENTS1=audio/flac,audio/mpeg,audio/mp4\\>audio/flac 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_URL=\"http://${BNB_DEV_HOST_IP}:4534\" BNB_SUBSONIC_URL=\"${BNB_DEV_SUBSONIC_URL}\" nodemon -V ./src/app.ts",
"devr": "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",
Expand Down
12 changes: 6 additions & 6 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import server from "./server";
import logger from "./logger";

import {
appendMimeTypeToClientFor,
axiosImageFetcher,
cachingImageFetcher,
DEFAULT,
Subsonic,
TranscodingCustomPlayers,
NO_CUSTOM_PLAYERS
} from "./subsonic";
import { InMemoryAPITokens, sha256 } from "./api_tokens";
import { InMemoryLinkCodes } from "./link_codes";
Expand All @@ -32,17 +32,17 @@ const bonob = bonobService(

const sonosSystem = sonos(config.sonos.discovery);

const streamUserAgent = config.subsonic.customClientsFor
? appendMimeTypeToClientFor(config.subsonic.customClientsFor.split(","))
: DEFAULT;
const customPlayers = config.subsonic.customClientsFor
? TranscodingCustomPlayers.from(config.subsonic.customClientsFor)
: NO_CUSTOM_PLAYERS;

const artistImageFetcher = config.subsonic.artistImageCache
? cachingImageFetcher(config.subsonic.artistImageCache, axiosImageFetcher)
: axiosImageFetcher;

const subsonic = new Subsonic(
config.subsonic.url,
streamUserAgent,
customPlayers,
artistImageFetcher
);

Expand Down
7 changes: 6 additions & 1 deletion src/music_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,15 @@ export type Rating = {
stars: number;
}

export type Encoding = {
player: string,
mimeType: string
}

export type Track = {
id: string;
name: string;
mimeType: string;
encoding: Encoding,
duration: number;
number: number | undefined;
genre: Genre | undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/smapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ export const album = (bonobUrl: URLBuilder, album: AlbumSummary) => ({
export const track = (bonobUrl: URLBuilder, track: Track) => ({
itemType: "track",
id: `track:${track.id}`,
mimeType: sonosifyMimeType(track.mimeType),
mimeType: sonosifyMimeType(track.encoding.mimeType),
title: track.name,

trackMetadata: {
Expand Down
Loading

0 comments on commit 9b9a348

Please sign in to comment.