From 3ecfb530166c7c74348daa176e2d5fedfd286fa1 Mon Sep 17 00:00:00 2001 From: uh wot Date: Sat, 13 Jul 2024 17:13:50 +0200 Subject: [PATCH 1/2] tidal: add 24bit flac support --- src/streamers/tidal/main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/streamers/tidal/main.ts b/src/streamers/tidal/main.ts index 9de6ac0..5ca4d09 100644 --- a/src/streamers/tidal/main.ts +++ b/src/streamers/tidal/main.ts @@ -262,11 +262,11 @@ export default class Tidal implements Streamer { tracks: tracksResponse.items.map(parseTrack) } } - async #getFileUrl(trackId: number | string, quality = 'LOSSLESS'): Promise { + async #getFileUrl(trackId: number | string, quality = 'HI_RES_LOSSLESS'): Promise { interface PlaybackInfo { manifest: string manifestMimeType: string - audioQuality: 'LOW' | 'HIGH' | 'LOSSLESS' | 'HI_RES' + audioQuality: 'LOW' | 'HIGH' | 'LOSSLESS' | 'HI_RES' | 'HI_RES_LOSSLESS' } const playbackInfoResponse = await this.#get( `tracks/${trackId}/playbackinfopostpaywall/v4`, From 616f331f4b09dbdb9f0324ae424555e59daf0386 Mon Sep 17 00:00:00 2001 From: uh wot Date: Sat, 13 Jul 2024 20:56:32 +0200 Subject: [PATCH 2/2] tidal: fix 404 error on tracks/albums not available in the US --- src/streamers/tidal/main.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/streamers/tidal/main.ts b/src/streamers/tidal/main.ts index 9de6ac0..cb563f2 100644 --- a/src/streamers/tidal/main.ts +++ b/src/streamers/tidal/main.ts @@ -28,6 +28,7 @@ interface TidalOptions { accessToken: string refreshToken: string expires: number + countryCode: string } interface LoginData { @@ -37,12 +38,17 @@ interface LoginData { expires_in: number } +interface SessionData { + countryCode: string +} + export default class Tidal implements Streamer { tvToken: string tvSecret: string accessToken: string refreshToken: string expires: number + countryCode: string hostnames = ['tidal.com', 'www.tidal.com', 'listen.tidal.com'] failedAuth = false constructor(options: TidalOptions) { @@ -53,6 +59,7 @@ export default class Tidal implements Streamer { this.accessToken = options.accessToken this.refreshToken = options.refreshToken this.expires = options.expires + this.countryCode = options.countryCode const getReady = async () => { if (!this.refreshToken) return @@ -71,9 +78,10 @@ export default class Tidal implements Streamer { } } async #get(url: string, params: { [key: string]: string | number } = {}): Promise { - if (Date.now() > this.expires) await this.refresh() if (this.failedAuth) throw new Error(`Last request failed to authorize, get new tokens`) - params.countryCode = params.countryCode ?? 'US' + if (Date.now() > this.expires) await this.refresh() + if (!this.countryCode) await this.getCountryCode() + params.countryCode = params.countryCode ?? this.countryCode params.locale = params.locale ?? 'en_US' params.deviceType = params.deviceType ?? 'TV' for (const key in params) { @@ -112,6 +120,15 @@ export default class Tidal implements Streamer { }) return resp.ok } + async getCountryCode() { + const sessionResponse = await fetch('https://api.tidal.com/v1/sessions', { + headers: this.headers() + }) + if (sessionResponse.status != 200) return false + const sessionData = await sessionResponse.json() + this.countryCode = sessionData.countryCode + return true + } async getTokens() { const deviceAuthResponse = await fetch(`${TIDAL_AUTH_BASE}oauth2/device_authorization`, { method: 'post', @@ -151,6 +168,7 @@ export default class Tidal implements Streamer { this.accessToken = loginData.access_token this.refreshToken = loginData.refresh_token this.expires = Date.now() + loginData.expires_in * 1000 + await this.getCountryCode() console.log('[tidal] Using the following new config:', this.getCurrentConfig()) } @@ -164,7 +182,8 @@ export default class Tidal implements Streamer { tvSecret: this.tvSecret, accessToken: this.accessToken, refreshToken: this.refreshToken, - expires: this.expires + expires: this.expires, + countryCode: this.countryCode } } async refresh() {