package qmc import ( "context" "errors" "fmt" "io" "strings" "github.com/samber/lo" "unlock-music.dev/cli/algo/common" "unlock-music.dev/cli/algo/qmc/client" "unlock-music.dev/cli/internal/ffmpeg" ) func (d *Decoder) GetAudioMeta(ctx context.Context) (common.AudioMeta, error) { if d.meta != nil { return d.meta, nil } if d.songID != 0 { if err := d.getMetaBySongID(ctx); err != nil { return nil, err } return d.meta, nil } embedMeta, err := ffmpeg.ProbeReader(ctx, d.probeBuf) if err != nil { return nil, fmt.Errorf("qmc[GetAudioMeta] probe reader: %w", err) } d.meta = embedMeta d.embeddedCover = embedMeta.HasAttachedPic() if !d.embeddedCover && embedMeta.HasMetadata() { if err := d.searchMetaOnline(ctx, embedMeta); err != nil { return nil, err } return d.meta, nil } return d.meta, nil } func (d *Decoder) getMetaBySongID(ctx context.Context) error { c := client.NewQQMusicClient() // todo: use global client trackInfo, err := c.GetTrackInfo(ctx, d.songID) if err != nil { return fmt.Errorf("qmc[GetAudioMeta] get track info: %w", err) } d.meta = trackInfo d.albumID = trackInfo.Album.Id if trackInfo.Album.Pmid == "" { d.albumMediaID = trackInfo.Album.Pmid } else { d.albumMediaID = trackInfo.Album.Mid } return nil } func (d *Decoder) searchMetaOnline(ctx context.Context, original common.AudioMeta) error { c := client.NewQQMusicClient() // todo: use global client keyword := lo.WithoutEmpty(append( []string{original.GetTitle(), original.GetAlbum()}, original.GetArtists()...), ) if len(keyword) == 0 { return errors.New("qmc[searchMetaOnline] no keyword") } trackList, err := c.Search(ctx, strings.Join(keyword, " ")) if err != nil { return fmt.Errorf("qmc[searchMetaOnline] search: %w", err) } if len(trackList) == 0 { return errors.New("qmc[searchMetaOnline] no result") } meta := trackList[0] d.meta = meta d.albumID = meta.Album.Id if meta.Album.Pmid == "" { d.albumMediaID = meta.Album.Pmid } else { d.albumMediaID = meta.Album.Mid } return nil } func (d *Decoder) GetCoverImage(ctx context.Context) ([]byte, error) { if d.cover != nil { return d.cover, nil } if d.embeddedCover { img, err := ffmpeg.ExtractAlbumArt(ctx, d.probeBuf) if err != nil { return nil, fmt.Errorf("qmc[GetCoverImage] extract album art: %w", err) } d.cover, err = io.ReadAll(img) if err != nil { return nil, fmt.Errorf("qmc[GetCoverImage] read embed cover: %w", err) } return d.cover, nil } c := client.NewQQMusicClient() // todo: use global client var err error if d.albumMediaID != "" { d.cover, err = c.AlbumCoverByMediaID(ctx, d.albumMediaID) if err != nil { return nil, fmt.Errorf("qmc[GetCoverImage] get cover by media id: %w", err) } } else if d.albumID != 0 { d.cover, err = c.AlbumCoverByID(ctx, d.albumID) if err != nil { return nil, fmt.Errorf("qmc[GetCoverImage] get cover by id: %w", err) } } else { return nil, errors.New("qmc[GetAudioMeta] album (or media) id is empty") } return d.cover, nil }