You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
5.2 KiB
Go
179 lines
5.2 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/samber/lo"
|
|
)
|
|
|
|
type getTrackInfoParams struct {
|
|
Ctx int `json:"ctx"`
|
|
Ids []int `json:"ids"`
|
|
Types []int `json:"types"`
|
|
}
|
|
|
|
type getTrackInfoResponse struct {
|
|
Tracks []*TrackInfo `json:"tracks"`
|
|
}
|
|
|
|
func (c *QQMusic) GetTracksInfo(ctx context.Context, songIDs []int) ([]*TrackInfo, error) {
|
|
resp, err := c.rpcCall(ctx,
|
|
"Protocol_UpdateSongInfo",
|
|
"CgiGetTrackInfo",
|
|
"music.trackInfo.UniformRuleCtrl",
|
|
&getTrackInfoParams{Ctx: 0, Ids: songIDs, Types: []int{0}},
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("qqMusicClient[GetTrackInfo] rpc call: %w", err)
|
|
}
|
|
respData := getTrackInfoResponse{}
|
|
if err := json.Unmarshal(resp, &respData); err != nil {
|
|
return nil, fmt.Errorf("qqMusicClient[GetTrackInfo] unmarshal response: %w", err)
|
|
}
|
|
|
|
return respData.Tracks, nil
|
|
}
|
|
|
|
func (c *QQMusic) GetTrackInfo(ctx context.Context, songID int) (*TrackInfo, error) {
|
|
tracks, err := c.GetTracksInfo(ctx, []int{songID})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("qqMusicClient[GetTrackInfo] get tracks info: %w", err)
|
|
}
|
|
|
|
if len(tracks) == 0 {
|
|
return nil, fmt.Errorf("qqMusicClient[GetTrackInfo] track not found")
|
|
}
|
|
|
|
return tracks[0], nil
|
|
}
|
|
|
|
type TrackSinger struct {
|
|
Id int `json:"id"`
|
|
Mid string `json:"mid"`
|
|
Name string `json:"name"`
|
|
Title string `json:"title"`
|
|
Type int `json:"type"`
|
|
Uin int `json:"uin"`
|
|
Pmid string `json:"pmid"`
|
|
}
|
|
type TrackAlbum struct {
|
|
Id int `json:"id"`
|
|
Mid string `json:"mid"`
|
|
Name string `json:"name"`
|
|
Title string `json:"title"`
|
|
Subtitle string `json:"subtitle"`
|
|
Pmid string `json:"pmid"`
|
|
}
|
|
type TrackInfo struct {
|
|
Id int `json:"id"`
|
|
Type int `json:"type"`
|
|
Mid string `json:"mid"`
|
|
Name string `json:"name"`
|
|
Title string `json:"title"`
|
|
Subtitle string `json:"subtitle"`
|
|
Singer []TrackSinger `json:"singer"`
|
|
Album TrackAlbum `json:"album"`
|
|
Mv struct {
|
|
Id int `json:"id"`
|
|
Vid string `json:"vid"`
|
|
Name string `json:"name"`
|
|
Title string `json:"title"`
|
|
Vt int `json:"vt"`
|
|
} `json:"mv"`
|
|
Interval int `json:"interval"`
|
|
Isonly int `json:"isonly"`
|
|
Language int `json:"language"`
|
|
Genre int `json:"genre"`
|
|
IndexCd int `json:"index_cd"`
|
|
IndexAlbum int `json:"index_album"`
|
|
TimePublic string `json:"time_public"`
|
|
Status int `json:"status"`
|
|
Fnote int `json:"fnote"`
|
|
File struct {
|
|
MediaMid string `json:"media_mid"`
|
|
Size24Aac int `json:"size_24aac"`
|
|
Size48Aac int `json:"size_48aac"`
|
|
Size96Aac int `json:"size_96aac"`
|
|
Size192Ogg int `json:"size_192ogg"`
|
|
Size192Aac int `json:"size_192aac"`
|
|
Size128Mp3 int `json:"size_128mp3"`
|
|
Size320Mp3 int `json:"size_320mp3"`
|
|
SizeApe int `json:"size_ape"`
|
|
SizeFlac int `json:"size_flac"`
|
|
SizeDts int `json:"size_dts"`
|
|
SizeTry int `json:"size_try"`
|
|
TryBegin int `json:"try_begin"`
|
|
TryEnd int `json:"try_end"`
|
|
Url string `json:"url"`
|
|
SizeHires int `json:"size_hires"`
|
|
HiresSample int `json:"hires_sample"`
|
|
HiresBitdepth int `json:"hires_bitdepth"`
|
|
B30S int `json:"b_30s"`
|
|
E30S int `json:"e_30s"`
|
|
Size96Ogg int `json:"size_96ogg"`
|
|
Size360Ra []interface{} `json:"size_360ra"`
|
|
SizeDolby int `json:"size_dolby"`
|
|
SizeNew []interface{} `json:"size_new"`
|
|
} `json:"file"`
|
|
Pay struct {
|
|
PayMonth int `json:"pay_month"`
|
|
PriceTrack int `json:"price_track"`
|
|
PriceAlbum int `json:"price_album"`
|
|
PayPlay int `json:"pay_play"`
|
|
PayDown int `json:"pay_down"`
|
|
PayStatus int `json:"pay_status"`
|
|
TimeFree int `json:"time_free"`
|
|
} `json:"pay"`
|
|
Action struct {
|
|
Switch int `json:"switch"`
|
|
Msgid int `json:"msgid"`
|
|
Alert int `json:"alert"`
|
|
Icons int `json:"icons"`
|
|
Msgshare int `json:"msgshare"`
|
|
Msgfav int `json:"msgfav"`
|
|
Msgdown int `json:"msgdown"`
|
|
Msgpay int `json:"msgpay"`
|
|
Switch2 int `json:"switch2"`
|
|
Icon2 int `json:"icon2"`
|
|
} `json:"action"`
|
|
Ksong struct {
|
|
Id int `json:"id"`
|
|
Mid string `json:"mid"`
|
|
} `json:"ksong"`
|
|
Volume struct {
|
|
Gain float64 `json:"gain"`
|
|
Peak float64 `json:"peak"`
|
|
Lra float64 `json:"lra"`
|
|
} `json:"volume"`
|
|
Label string `json:"label"`
|
|
Url string `json:"url"`
|
|
Ppurl string `json:"ppurl"`
|
|
Bpm int `json:"bpm"`
|
|
Version int `json:"version"`
|
|
Trace string `json:"trace"`
|
|
DataType int `json:"data_type"`
|
|
ModifyStamp int `json:"modify_stamp"`
|
|
Aid int `json:"aid"`
|
|
Tid int `json:"tid"`
|
|
Ov int `json:"ov"`
|
|
Sa int `json:"sa"`
|
|
Es string `json:"es"`
|
|
Vs []string `json:"vs"`
|
|
}
|
|
|
|
func (t *TrackInfo) GetArtists() []string {
|
|
return lo.Map(t.Singer, func(v TrackSinger, i int) string {
|
|
return v.Name
|
|
})
|
|
}
|
|
|
|
func (t *TrackInfo) GetTitle() string {
|
|
return t.Title
|
|
}
|
|
|
|
func (t *TrackInfo) GetAlbum() string {
|
|
return t.Album.Name
|
|
}
|