Compare commits

..

7 Commits

Author SHA1 Message Date
zhaarey 4cfa5251b6
Merge pull request #20 from itouakirai/main 5 months ago
itouakirai a7e11e7beb
add emby animated artwork config 5 months ago
itouakirai e7f2986988
add animated artwork for emby 5 months ago
itouakirai 21925437c1
fix playlist animated artwork 5 months ago
itouakirai 4fba1ee0bc
fix Config to config 5 months ago
itouakirai 9f4636598c
add save-animated-artwork 5 months ago
itouakirai 013f70d220
add animated artwork download 5 months ago
  1. 2
      config.yaml
  2. 81
      main.go

@ -1,6 +1,8 @@
media-user-token: "your-media-user-token"
embed-lrc: true
save-lrc-file: false
save-animated-artwork: false # If enabled, requires ffmpeg
emby-animated-artwork: false # If enabled, requires ffmpeg
embed-cover: true
cover-size: 5000x5000
cover-format: jpg #jpg or png

@ -41,6 +41,8 @@ var (
type Config struct {
MediaUserToken string `yaml:"media-user-token"`
SaveLrcFile bool `yaml:"save-lrc-file"`
SaveAnimatedArtwork bool `yaml:"save-animated-artwork"`
EmbyAnimatedArtwork bool `yaml:"emby-animated-artwork"`
EmbedLrc bool `yaml:"embed-lrc"`
EmbedCover bool `yaml:"embed-cover"`
CoverSize string `yaml:"cover-size"`
@ -1153,6 +1155,7 @@ func getMeta(albumId string, token string, storefront string) (*AutoGenerated, e
query.Set("fields[artists]", "name")
query.Set("fields[albums:albums]", "artistName,artwork,name,releaseDate,url")
query.Set("fields[record-labels]", "name")
query.Set("extend", "editorialVideo")
// query.Set("l", "en-gb")
req.URL.RawQuery = query.Encode()
do, err := http.DefaultClient.Do(req)
@ -1389,6 +1392,36 @@ func rip(albumId string, token string, storefront string, userToken string) erro
if err != nil {
fmt.Println("Failed to write cover.")
}
//get animated artwork
if config.SaveAnimatedArtwork && meta.Data[0].Attributes.EditorialVideo.MotionDetailSquare.Video != "" {
fmt.Println("Found Animation Artwork.")
motionvideoUrl, err := extractVideo(meta.Data[0].Attributes.EditorialVideo.MotionDetailSquare.Video)
if err != nil {
fmt.Println("no motion video.\n", err)
}
exists, err := fileExists(filepath.Join(sanAlbumFolder, "animated_artwork.mp4"))
if err != nil {
fmt.Println("Failed to check if animated artwork exists.")
}
if exists {
fmt.Println("Animated artwork already exists locally.")
} else {
fmt.Println("Animation Artwork Downloading...")
cmd := exec.Command("ffmpeg", "-loglevel", "quiet", "-y", "-i", motionvideoUrl, "-c", "copy", filepath.Join(sanAlbumFolder, "animated_artwork.mp4"))
if err := cmd.Run(); err != nil {
fmt.Printf("animated artwork dl err: %v\n", err)
} else {
fmt.Println("Animation Artwork Downloaded")
}
if config.EmbyAnimatedArtwork {
cmd2 := exec.Command("ffmpeg", "-i", filepath.Join(sanAlbumFolder, "animated_artwork.mp4"), "-vf", "scale=440:-1", "-r", "24", "-f", "gif", filepath.Join(sanAlbumFolder, "folder.jpg"))
if err := cmd2.Run(); err != nil {
fmt.Printf("animated artwork to gif err: %v\n", err)
}
}
}
}
trackTotal := len(meta.Data[0].Relationships.Tracks.Data)
for trackNum, track := range meta.Data[0].Relationships.Tracks.Data {
trackNum++
@ -1857,7 +1890,45 @@ func extractMedia(b string) (string, []string, error) {
}
return streamUrl.String(), keys, nil
}
func extractVideo(c string) (string, error) {
MediaUrl, err := url.Parse(c)
if err != nil {
return "", err
}
resp, err := http.Get(c)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", errors.New(resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
videoString := string(body)
from, listType, err := m3u8.DecodeFrom(strings.NewReader(videoString), true)
if err != nil || listType != m3u8.MASTER {
return "", errors.New("m3u8 not of media type")
}
video := from.(*m3u8.MasterPlaylist)
var streamUrl *url.URL
sort.Slice(video.Variants, func(i, j int) bool {
return video.Variants[i].AverageBandwidth > video.Variants[j].AverageBandwidth
})
if len(video.Variants) > 0 {
highestBandwidthVariant := video.Variants[0]
streamUrl, err = MediaUrl.Parse(highestBandwidthVariant.URI)
if err != nil {
return "", err
}
}
if streamUrl == nil {
return "", errors.New("no video codec found")
}
return streamUrl.String(), nil
}
func extractSong(url string) (*SongInfo, error) {
fmt.Println("Downloading...")
track, err := http.Get(url)
@ -2307,6 +2378,14 @@ type AutoGenerated struct {
Kind string `json:"kind"`
} `json:"playParams"`
IsCompilation bool `json:"isCompilation"`
EditorialVideo struct {
MotionDetailSquare struct {
Video string `json:"video"`
} `json:"motionDetailSquare"`
MotionSquareVideo1x1 struct {
Video string `json:"video"`
} `json:"motionSquareVideo1x1"`
} `json:"editorialVideo"`
} `json:"attributes"`
Relationships struct {
RecordLabels struct {

Loading…
Cancel
Save