mirror of
https://git.sr.ht/~joren/streamrip-go
synced 2026-06-17 15:05:39 +02:00
fix tidal lossless quality negotiation and atmos format fallback
This commit is contained in:
@@ -37,12 +37,12 @@ var qualityMap = map[int]string{
|
||||
4: "HI_RES_LOSSLESS",
|
||||
}
|
||||
|
||||
var qualityToFormat = map[int]string{
|
||||
0: "HEAACV1",
|
||||
1: "AACLC",
|
||||
2: "FLAC",
|
||||
3: "FLAC_HIRES",
|
||||
4: "FLAC_HIRES",
|
||||
var qualityToFormats = map[int][]string{
|
||||
0: {"HEAACV1"},
|
||||
1: {"HEAACV1", "AACLC"},
|
||||
2: {"HEAACV1", "AACLC", "FLAC"},
|
||||
3: {"HEAACV1", "AACLC", "FLAC", "FLAC_HIRES"},
|
||||
4: {"HEAACV1", "AACLC", "FLAC", "FLAC_HIRES"},
|
||||
}
|
||||
|
||||
var atmosAudioQualities = []string{"HI_RES_LOSSLESS", "HI_RES", "LOSSLESS", "HIGH"}
|
||||
@@ -54,6 +54,7 @@ type Client struct {
|
||||
http *http.Client
|
||||
limiter *ratelimit.Limiter
|
||||
baseURL string
|
||||
openAPI string
|
||||
loggedIn bool
|
||||
}
|
||||
|
||||
@@ -63,6 +64,7 @@ func New(cfg *config.Config) *Client {
|
||||
http: netutil.NewHTTPClient(30*time.Second, cfg.Session.Downloads.VerifySSL),
|
||||
limiter: ratelimit.New(cfg.Session.Downloads.RequestsPerMinute),
|
||||
baseURL: baseURL,
|
||||
openAPI: openAPIV2,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +265,11 @@ func (c *Client) GetDownloadable(ctx context.Context, trackID string, quality in
|
||||
}
|
||||
if status == http.StatusOK {
|
||||
if d := downloadableFromPlaybackManifest(resp); d != nil {
|
||||
if quality >= 2 && d.Extension == "m4a" {
|
||||
if strict, strictErr := c.getDownloadableFromTrackManifest(ctx, trackID, quality); strictErr == nil && strict != nil {
|
||||
return strict, nil
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
}
|
||||
@@ -475,19 +482,23 @@ func (c *Client) fetchArtistAlbums(ctx context.Context, artistID string) ([]map[
|
||||
}
|
||||
|
||||
func (c *Client) getDownloadableFromTrackManifest(ctx context.Context, trackID string, quality int) (*provider.Downloadable, error) {
|
||||
format := qualityToFormat[quality]
|
||||
return c.getDownloadableFromTrackManifestForFormat(ctx, trackID, format)
|
||||
formats := formatsForQuality(quality, c.cfg.Session.Tidal.PreferAtmos)
|
||||
return c.getDownloadableFromTrackManifestForFormats(ctx, trackID, formats)
|
||||
}
|
||||
|
||||
func (c *Client) getDownloadableFromTrackManifestForFormat(ctx context.Context, trackID, format string) (*provider.Downloadable, error) {
|
||||
return c.getDownloadableFromTrackManifestForFormats(ctx, trackID, []string{format})
|
||||
}
|
||||
|
||||
func (c *Client) getDownloadableFromTrackManifestForFormats(ctx context.Context, trackID string, formats []string) (*provider.Downloadable, error) {
|
||||
params := url.Values{}
|
||||
params.Set("manifestType", "MPEG_DASH")
|
||||
params.Set("formats", format)
|
||||
params.Set("formats", strings.Join(formats, ","))
|
||||
params.Set("uriScheme", "HTTPS")
|
||||
params.Set("usage", "PLAYBACK")
|
||||
params.Set("adaptive", "false")
|
||||
|
||||
resp, status, err := c.apiRequest(ctx, "trackManifests/"+trackID, params, openAPIV2)
|
||||
resp, status, err := c.apiRequest(ctx, "trackManifests/"+trackID, params, c.openAPI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -507,9 +518,9 @@ func (c *Client) getDownloadableFromTrackManifestForFormat(ctx context.Context,
|
||||
if uri == "" {
|
||||
return nil, errors.New("tidal trackManifests missing uri")
|
||||
}
|
||||
formats, _ := attrs["formats"].([]any)
|
||||
attrFormats, _ := attrs["formats"].([]any)
|
||||
ext := "m4a"
|
||||
for _, f := range formats {
|
||||
for _, f := range attrFormats {
|
||||
fv := strings.ToUpper(stringify(f))
|
||||
if strings.Contains(fv, "FLAC") {
|
||||
ext = "flac"
|
||||
@@ -523,6 +534,18 @@ func (c *Client) getDownloadableFromTrackManifestForFormat(ctx context.Context,
|
||||
return &provider.Downloadable{URL: uri, Extension: ext, Source: "tidal"}, nil
|
||||
}
|
||||
|
||||
func formatsForQuality(quality int, preferAtmos bool) []string {
|
||||
base, ok := qualityToFormats[quality]
|
||||
if !ok {
|
||||
base = qualityToFormats[0]
|
||||
}
|
||||
out := append([]string(nil), base...)
|
||||
if preferAtmos {
|
||||
out = append(out, "EAC3_JOC")
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *Client) GetVideoDownloadable(ctx context.Context, videoID string) (*provider.Downloadable, error) {
|
||||
if !c.loggedIn {
|
||||
return nil, errors.New("tidal client not logged in")
|
||||
|
||||
Reference in New Issue
Block a user