kv-music/.opencode/plans/tidal-web-backend.md

107 lines
4.4 KiB
Markdown

# Replace Tidal OAuth2 Backend with Public Web API + Self-Hosted Proxy
## Goal
Replace Monochrome's Tidal OAuth2 backend (which is blocked in your country) with the SpotiFLAC tidal-web approach that uses:
1. **Tidal public web endpoints** (`tidal.com/v1/`) with a public token for metadata/search
2. **Self-hosted proxy** (SpotiFLAC Go backend) for audio streaming/downloads
## Changes
### 1. `js/HiFi.ts` - Complete rewrite
- Remove OAuth2 token flow (`auth.tidal.com/v1/oauth2/token`)
- Use public web token (`x-tidal-token` header, default: `49YxDN9a2aFV6RTG`)
- Change API base from `api.tidal.com/v1/` to `tidal.com/v1/`
- Keep all TypeScript type interfaces (TidalTrack, TidalAlbum, etc.)
- Keep `TidalResponse` class
- Update `query()` to use `tidal.com/v1/` endpoints
- Methods updated: `getInfo`, `getTrack`, `getAlbum`, `getPlaylist`, `getPlaylistItems`, `getArtist`, `search`, `getVideo`, `getLyrics`, `getSimilarArtists`, `getSimilarAlbums`
- Constructor accepts: `publicToken`, `countryCode`, `locale`, `deviceType`
- Remove: `#fetchAppToken`, `#fetchAuthenticated`, `#fetchJson` (OAuth2-based), `fetchToken`, `getTrackManifest`
### 2. `js/api.js` - Rewrite LosslessAPI
- `fetchWithRetry()` - Remove HiFiClient OAuth2 fallback, remove proxy instance iteration for metadata (use HiFiClient directly). Keep proxy logic only for streaming if needed.
- `search()`, `searchTracks()`, `searchArtists()`, `searchAlbums()`, `searchPlaylists()`, `searchVideos()` - Update to use new HiFiClient.search()
- `getAlbum()` - Update to handle pages API response structure (`pages/album` returns page modules with `ALBUM_HEADER` and `ALBUM_ITEMS`)
- `getPlaylist()` - Update to use new HiFiClient methods
- `getArtist()` - Update to handle pages API response (`pages/artist` returns `ARTIST_HEADER` module)
- `getTrack()` - Route through self-hosted proxy instead of Tidal OpenAPI
- `getStreamUrl()` - Route through self-hosted proxy
- `getVideo()` - Update for new endpoints
- `downloadTrack()` - Stream URLs come from self-hosted proxy
- `enrichTrack()` - Update to use proxy for playback info
- `normalizeTrackManifestResponse()` - Adapt to proxy response format
- Keep: `getCoverUrl()`, `getCoverSrcset()`, `getArtistPictureUrl()`, `getArtistPictureSrcset()`, `getVideoCoverUrl()`, cache methods, prepare methods
### 3. `js/storage.js` - Add tidalWebSettings
```js
export const tidalWebSettings = {
STORAGE_KEY: 'tidal-web-settings',
DEFAULT_PROXY_URL: '', // User must set their self-hosted proxy
DEFAULT_PUBLIC_TOKEN: '49YxDN9a2aFV6RTG',
DEFAULT_COUNTRY_CODE: 'US',
getProxyUrl() { ... },
setProxyUrl(url) { ... },
getPublicToken() { ... },
setPublicToken(token) { ... },
getCountryCode() { ... },
setCountryCode(code) { ... },
};
```
### 4. `js/proxy-utils.js` - Simplify
- Remove tidal CDN URL proxying (no longer needed - streaming goes through self-hosted proxy)
- Keep CORS proxy list for any remaining direct stream URLs
### 5. `js/music-api.js` - Minimal changes
- `getTrack()`, `getStreamUrl()`, `downloadTrack()` already delegate to LosslessAPI
- No structural changes needed
### 6. `js/app.js` - Update initialization
- Change `HiFiClient.initialize()` to pass `publicToken`, `countryCode` from tidalWebSettings
- Remove OAuth2 token/tokenExpiry storage references
## Self-Hosted Proxy API Contract
The self-hosted SpotiFLAC Go backend must expose:
```
POST {proxyUrl}/v1/dl/tid2
Body: { "id": "123456", "quality": "HI_RES_LOSSLESS" }
Response:
{
"data": {
"manifest": "base64-encoded-manifest",
"manifestMimeType": "application/dash+xml",
"audioQuality": "HI_RES_LOSSLESS",
"bitDepth": 24,
"sampleRate": 96000,
"trackPresentation": "FULL"
}
}
```
Alternative response format (from mirror proxies):
```json
[{ "OriginalTrackUrl": "https://direct-stream-url.flac" }]
```
## Deployment Notes
The SpotiFLAC Go backend is at `go_backend/` in the SpotiFLAC-Mobile repo:
- Build: `cd go_backend && go build`
- Run: `./go_backend` (listens on port)
- Configure with Tidal credentials or public token
## Files Modified
1. `js/HiFi.ts` - Full rewrite
2. `js/api.js` - Major rewrite (LosslessAPI class)
3. `js/storage.js` - Add tidalWebSettings
4. `js/proxy-utils.js` - Simplify
5. `js/music-api.js` - Minimal changes
6. `js/app.js` - Update initialization
## Files NOT Modified
- Server-side functions (Cloudflare Workers for SEO) - continue using OAuth2
- Frontend UI components
- Player, downloads, metadata embedding logic (unchanged interfaces)