Something went wrong. Try again.
Self-hosted web interface and downloader for Qobuz.
downloader self-hosted music qobuz
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217package api
import ( "encoding/json" "strings")
// ID represents an identifier that can be decoded from either a JSON string or integer.type ID string
func (id *ID) UnmarshalJSON(b []byte) error { if len(b) == 0 || string(b) == "null" { *id = "" return nil } if b[0] == '"' { var s string if err := json.Unmarshal(b, &s); err != nil { return err } *id = ID(s) return nil } *id = ID(strings.TrimSpace(string(b))) return nil}
func (id ID) String() string { return string(id)}
// Quality represents audio streaming and download quality formats.type Quality int
const ( QualityMp3 Quality = 5 // MP3 320kbps QualityLossless Quality = 6 // 16-bit / 44.1kHz (CD Quality) QualityHiRes Quality = 7 // 24-bit / ≤96kHz QualityUltraHiRes Quality = 27 // 24-bit / >96kHz)
// ID returns the numeric format identifier.func (q Quality) ID() int { return int(q)}
// Label returns a human-readable description of the quality setting.func (q Quality) Label() string { switch q { case QualityMp3: return "MP3 320kbps" case QualityLossless: return "FLAC 16-bit/44.1kHz" case QualityHiRes: return "FLAC 24-bit/≤96kHz" case QualityUltraHiRes: return "FLAC 24-bit/>96kHz" default: return "Unknown" }}
// IsValid reports whether the quality setting is a known format.func (q Quality) IsValid() bool { switch q { case QualityMp3, QualityLossless, QualityHiRes, QualityUltraHiRes: return true default: return false }}
// Image holds artwork URLs across various resolutions.type Image struct { Small string `json:"small,omitempty"` Thumbnail string `json:"thumbnail,omitempty"` Medium string `json:"medium,omitempty"` Large string `json:"large,omitempty"` ExtraLarge string `json:"extralarge,omitempty"` Mega string `json:"mega,omitempty"` Back string `json:"back,omitempty"`}
// Best returns the highest-resolution image URL available.func (img Image) Best() string { if img.Mega != "" { return img.Mega } if img.ExtraLarge != "" { return img.ExtraLarge } if img.Large != "" { return img.Large } if img.Thumbnail != "" { return img.Thumbnail } return img.Small}
// Smallest returns the lowest-resolution image URL available.func (img Image) Smallest() string { if img.Small != "" { return img.Small } if img.Thumbnail != "" { return img.Thumbnail } if img.Large != "" { return img.Large } if img.ExtraLarge != "" { return img.ExtraLarge } return img.Mega}
// Label represents record label metadata.type Label struct { ID ID `json:"id"` Name string `json:"name"` AlbumsCount int `json:"albums_count,omitempty"` Slug string `json:"slug,omitempty"` SupplierID int `json:"supplier_id,omitempty"`}
// Genre represents musical genre classification.type Genre struct { ID int `json:"id"` Name string `json:"name"` Path []int `json:"path,omitempty"` Slug string `json:"slug,omitempty"` Color string `json:"color,omitempty"`}
// AlbumAward represents press and catalog accolades.type AlbumAward struct { ID ID `json:"id"` AwardID ID `json:"award_id,omitempty"` Name string `json:"name"` AwardedAt ID `json:"awarded_at,omitempty"`}
func (a *AlbumAward) UnmarshalJSON(b []byte) error { var raw struct { ID ID `json:"id"` AwardID ID `json:"award_id"` AwardIDCamel ID `json:"awardId"` Name string `json:"name"` AwardedAt ID `json:"awarded_at"` AwardedAtCamel ID `json:"awardedAt"` } if err := json.Unmarshal(b, &raw); err != nil { return err } a.Name = raw.Name if raw.ID != "" { a.ID = raw.ID } else if raw.AwardID != "" { a.ID = raw.AwardID } else { a.ID = raw.AwardIDCamel } a.AwardID = a.ID
if raw.AwardedAt != "" { a.AwardedAt = raw.AwardedAt } else { a.AwardedAt = raw.AwardedAtCamel } return nil}
// Dates contains release date timestamps.type Dates struct { Original string `json:"original,omitempty"` Download string `json:"download,omitempty"` Stream string `json:"stream,omitempty"`}
// AudioInfo describes audio resolution and replaygain metadata.type AudioInfo struct { MaximumSamplingRate float64 `json:"maximum_sampling_rate,omitempty"` MaximumBitDepth int `json:"maximum_bit_depth,omitempty"` MaximumChannelCount int `json:"maximum_channel_count,omitempty"` ReplayGainTrackGain float64 `json:"replaygain_track_gain,omitempty"` ReplayGainTrackPeak float64 `json:"replaygain_track_peak,omitempty"`}
// Rights specifies streaming, purchase, and download availability.type Rights struct { Streamable *bool `json:"streamable,omitempty"` HiResStreamable *bool `json:"hires_streamable,omitempty"` HiResPurchasable *bool `json:"hires_purchasable,omitempty"` Purchasable *bool `json:"purchasable,omitempty"` Downloadable *bool `json:"downloadable,omitempty"` Previewable *bool `json:"previewable,omitempty"` Sampleable *bool `json:"sampleable,omitempty"`}
// Goodie represents supplementary media such as digital booklets.type Goodie struct { ID ID `json:"id"` Name string `json:"name"` URL string `json:"url"` OriginalURL string `json:"original_url,omitempty"` FileURL string `json:"file_url,omitempty"` FileFormatID int `json:"file_format_id,omitempty"` Description string `json:"description,omitempty"`}
// Restriction describes playback or streaming limitations.type Restriction struct { Code string `json:"code"` Msg string `json:"msg,omitempty"`}