(fixes #981) HI_RES_LOSSLESS downloads via MPEG-DASH manifest support#998
(fixes #981) HI_RES_LOSSLESS downloads via MPEG-DASH manifest support#998joshtheclipper wants to merge 2 commits into
Conversation
This fork adds support for Tidal's HI_RES_LOSSLESS quality tier, improving the handling of MPEG-DASH manifests and enhancing the download process for hi-res tracks.
|
for some reason it doesn't work for me |
Not working for me either |
|
One thing I noticed is that is does not work 100% of the time. I am suspecting that TIDAL is not always sending true flac audio file will only send you AAC files. Are you seeing some come through as flac at all? |
|
@flying-fox-1 you are on the wrong version of rip i assume. you need to switch to github's version 2.2.0. |
|
Hey, I'm sorry for a late reply. So i install from the beta branch? pip3 install git+https://github.com/nathom/streamrip.git@dev |
|
@flying-fox-1 please, see the comment: |
|
Hello, it now works for me i had to change the main.py in \AppData\Local\Programs\Python\Python311\Lib\site-packages\streamrip\rip line 31 from: asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) to: asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) |
|
you are on windows? rly |


Summary
This PR fixes a issue (#981) where Tidal HI_RES_LOSSLESS tracks would silently fall back to lower quality (HIGH/AAC 320kbps) even on accounts with a HiFi subscription.
Root Cause
Tidal serves HI_RES_LOSSLESS tracks using MPEG-DASH manifests (application/dash+xml) rather than the standard JSON manifest format (application/vnd.tidal.bts) used for lower quality tiers. The existing code in get_downloadable() attempts to json.loads() every manifest and catches JSONDecodeError by falling back to a lower quality — meaning hi-res tracks were never downloaded at hi-res, silently and without a meaningful error.
The warning Failed to get manifest for {track_id}. Retrying with lower quality was the only indication something was wrong.
Changes
streamrip/client/tidal.pyget_downloadable() now checks manifestMimeType on JSONDecodeError and routes application/dash+xml manifests to a new handler instead of falling back
New _get_downloadable_from_dash() method parses the MPEG-DASH XML using xml.etree.ElementTree, extracts the initialization URL, all numbered media segment URLs from the , codec, and sample rate
streamrip/client/downloadable.pyNew TidalDASHDownloadable class inheriting from TidalDownloadable
Downloads initialization segment + all media segments sequentially, concatenating into a temporary .mp4 file
Remuxes from MP4 container to FLAC using ffmpeg -c copy (lossless, no re-encoding) — necessary because Tidal wraps FLAC audio in an MP4/ISOBMFF container even when the codec is FLAC
Fully compatible with existing progress tracking, size reporting, and download pipeline
Requirements
ffmpeg must be installed and available on PATH. This is already a soft dependency of streamrip for other features.
Testing
All HI_RES_LOSSLESS tracks now correctly download as 24-bit FLAC. Tracks that Tidal's API reports as HIGH (AAC) on a per-track basis continue to download correctly as .m4a — this is a Tidal-side licensing limitation and not something that can be addressed client-side.
This fork and pull request were researched, debugged, and written with the assistance of Claude AI (Anthropic). The root cause analysis, code changes, and testing approach were developed collaboratively through an iterative debugging session. The human contributor verified and tested all changes against a live Tidal HiFi account.