mirror of
https://git.sr.ht/~joren/streamrip-go
synced 2026-07-27 23:42:28 +02:00
fix: use exact qobuz download quality
This commit is contained in:
@@ -364,40 +364,60 @@ func qobuzDownloadExtension(resp map[string]any, quality int, streamURL string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func qobuzAudioProfile(resp map[string]any, requestedQuality int, ext string) provider.AudioProfile {
|
func qobuzAudioProfile(resp map[string]any, requestedQuality int, ext string) provider.AudioProfile {
|
||||||
|
exactBitDepth, _ := intValue(firstNonNil(resp["bit_depth"], resp["bits_depth"], resp["maximum_bit_depth"]))
|
||||||
|
exactSampling, _ := floatValue(firstNonNil(resp["sampling_rate"], resp["sample_rate"], resp["maximum_sampling_rate"]))
|
||||||
if formatID, ok := intValue(resp["format_id"]); ok {
|
if formatID, ok := intValue(resp["format_id"]); ok {
|
||||||
switch formatID {
|
switch formatID {
|
||||||
case 5:
|
case 5:
|
||||||
|
if exactBitDepth == 0 {
|
||||||
|
exactBitDepth = 16
|
||||||
|
}
|
||||||
|
if exactSampling == 0 {
|
||||||
|
exactSampling = 44.1
|
||||||
|
}
|
||||||
return provider.AudioProfile{
|
return provider.AudioProfile{
|
||||||
Container: "MP3",
|
Container: "MP3",
|
||||||
Codec: "MP3",
|
Codec: "MP3",
|
||||||
Quality: "HIGH",
|
Quality: "HIGH",
|
||||||
BitDepth: 16,
|
BitDepth: exactBitDepth,
|
||||||
SamplingRate: "44.1",
|
SamplingRate: formatSamplingRate(exactSampling),
|
||||||
BitrateKbps: 320,
|
BitrateKbps: 320,
|
||||||
}
|
}
|
||||||
case 6:
|
case 6:
|
||||||
|
if exactBitDepth == 0 {
|
||||||
|
exactBitDepth = 16
|
||||||
|
}
|
||||||
|
if exactSampling == 0 {
|
||||||
|
exactSampling = 44.1
|
||||||
|
}
|
||||||
return provider.AudioProfile{
|
return provider.AudioProfile{
|
||||||
Container: "FLAC",
|
Container: "FLAC",
|
||||||
Codec: "FLAC",
|
Codec: "FLAC",
|
||||||
Quality: "LOSSLESS",
|
Quality: "LOSSLESS",
|
||||||
BitDepth: 16,
|
BitDepth: exactBitDepth,
|
||||||
SamplingRate: "44.1",
|
SamplingRate: formatSamplingRate(exactSampling),
|
||||||
}
|
}
|
||||||
case 7:
|
case 7:
|
||||||
|
if exactBitDepth == 0 {
|
||||||
|
exactBitDepth = 24
|
||||||
|
}
|
||||||
return provider.AudioProfile{
|
return provider.AudioProfile{
|
||||||
Container: "FLAC",
|
Container: "FLAC",
|
||||||
Codec: "FLAC",
|
Codec: "FLAC",
|
||||||
Quality: "HI_RES",
|
Quality: "HI_RES",
|
||||||
BitDepth: 24,
|
BitDepth: exactBitDepth,
|
||||||
SamplingRate: "96",
|
SamplingRate: formatSamplingRate(exactSampling),
|
||||||
}
|
}
|
||||||
case 27:
|
case 27:
|
||||||
|
if exactBitDepth == 0 {
|
||||||
|
exactBitDepth = 24
|
||||||
|
}
|
||||||
return provider.AudioProfile{
|
return provider.AudioProfile{
|
||||||
Container: "FLAC",
|
Container: "FLAC",
|
||||||
Codec: "FLAC",
|
Codec: "FLAC",
|
||||||
Quality: "HI_RES",
|
Quality: "HI_RES",
|
||||||
BitDepth: 24,
|
BitDepth: exactBitDepth,
|
||||||
SamplingRate: "192",
|
SamplingRate: formatSamplingRate(exactSampling),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -438,6 +458,22 @@ func qobuzAudioProfile(resp map[string]any, requestedQuality int, ext string) pr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func firstNonNil(vals ...any) any {
|
||||||
|
for _, v := range vals {
|
||||||
|
if v != nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatSamplingRate(v float64) string {
|
||||||
|
if v <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) Close() error {
|
func (c *Client) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,6 +371,24 @@ func TestGetDownloadableUsesReturnedURLExtension(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQobuzAudioProfileUsesExactReturnedQuality(t *testing.T) {
|
||||||
|
profile := qobuzAudioProfile(map[string]any{
|
||||||
|
"format_id": float64(7),
|
||||||
|
"bit_depth": float64(24),
|
||||||
|
"sampling_rate": float64(44.1),
|
||||||
|
}, 4, "flac")
|
||||||
|
if profile.BitDepth != 24 || profile.SamplingRate != "44.1" || profile.Quality != "HI_RES" {
|
||||||
|
t.Fatalf("unexpected profile: %+v", profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQobuzAudioProfileAvoidsGuessingHiResSampleRate(t *testing.T) {
|
||||||
|
profile := qobuzAudioProfile(map[string]any{"format_id": float64(7)}, 4, "flac")
|
||||||
|
if profile.BitDepth != 24 || profile.SamplingRate != "" || profile.Quality != "HI_RES" {
|
||||||
|
t.Fatalf("unexpected profile: %+v", profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func qobuzSecretSig(requestTS, secret string) string {
|
func qobuzSecretSig(requestTS, secret string) string {
|
||||||
raw := "trackgetFileUrlformat_id27intentstreamtrack_id19512574" + requestTS + secret
|
raw := "trackgetFileUrlformat_id27intentstreamtrack_id19512574" + requestTS + secret
|
||||||
hash := md5.Sum([]byte(raw))
|
hash := md5.Sum([]byte(raw))
|
||||||
|
|||||||
Reference in New Issue
Block a user