Skip to content

Commit

Permalink
Merge pull request #60 from itouakirai/main
Browse files Browse the repository at this point in the history
fix:mv封面获取错误,mv路径特殊字符
  • Loading branch information
zhaarey authored Feb 19, 2025
2 parents 0de01fd + 3e90946 commit 6795982
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 37 deletions.
3 changes: 1 addition & 2 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,4 @@ use-songinfo-for-playlist: false
#if set true,will download album cover for playlist
dl-albumcover-for-playlist: false
mv-audio-type: atmos #atmos ac3 aac
mv-max: 2160
save-thumbnail-image: false #true or false of thumbnail image
mv-max: 2160
76 changes: 42 additions & 34 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"net/http"
Expand All @@ -26,12 +25,12 @@ import (
"main/utils/structs"

"github.com/beevik/etree"
"github.com/fatih/color"
"github.com/grafov/m3u8"
"github.com/olekukonko/tablewriter"
"github.com/spf13/pflag"
"github.com/zhaarey/go-mp4tag"
"gopkg.in/yaml.v2"
"github.com/fatih/color"
)

var (
Expand All @@ -54,7 +53,7 @@ var (

func loadConfig() error {
// 读取config.yaml文件内容
data, err := ioutil.ReadFile("config.yaml")
data, err := os.ReadFile("config.yaml")
if err != nil {
return err
}
Expand Down Expand Up @@ -411,15 +410,15 @@ func getSongLyrics(songId string, storefront string, token string, userToken str
}
defer do.Body.Close()
obj := new(structs.SongLyrics)
err = json.NewDecoder(do.Body).Decode(&obj)
_ = json.NewDecoder(do.Body).Decode(&obj)
if obj.Data != nil {
return obj.Data[0].Attributes.Ttml, nil
} else {
return "", errors.New("failed to get lyrics")
}
}

func writeCover(sanAlbumFolder, name string, url string) error {
func writeCover(sanAlbumFolder, name string, url string) (string, error) {
covPath := filepath.Join(sanAlbumFolder, name+"."+Config.CoverFormat)
if Config.CoverFormat == "original" {
ext := strings.Split(url, "/")[len(strings.Split(url, "/"))-2]
Expand All @@ -429,7 +428,7 @@ func writeCover(sanAlbumFolder, name string, url string) error {
exists, err := fileExists(covPath)
if err != nil {
fmt.Println("Failed to check if cover exists.")
return err
return "", err
}
if exists {
_ = os.Remove(covPath)
Expand All @@ -446,27 +445,27 @@ func writeCover(sanAlbumFolder, name string, url string) error {
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
return "", err
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
do, err := http.DefaultClient.Do(req)
if err != nil {
return err
return "", err
}
defer do.Body.Close()
if do.StatusCode != http.StatusOK {
errors.New(do.Status)
return "", errors.New(do.Status)
}
f, err := os.Create(covPath)
if err != nil {
return err
return "", err
}
defer f.Close()
_, err = io.Copy(f, do.Body)
if err != nil {
return err
return "", err
}
return nil
return covPath, nil
}

func writeLyrics(sanAlbumFolder, filename string, lrc string) error {
Expand All @@ -493,7 +492,7 @@ func contains(slice []string, item string) bool {
}

// 下载单曲逻辑
func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, track structs.TrackData, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec string, counter *structs.Counter) {
func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, track structs.TrackData, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec string, covPath string) {
counter.Total++
fmt.Printf("Track %d of %d:\n", trackNum, trackTotal)

Expand Down Expand Up @@ -547,7 +546,7 @@ func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, tr
}
var EnhancedHls_m3u8 string
if needCheck && !needDlAacLc {
EnhancedHls_m3u8, err = checkM3u8(track.ID, "song")
EnhancedHls_m3u8, _ = checkM3u8(track.ID, "song")
if strings.HasSuffix(EnhancedHls_m3u8, ".m3u8") {
manifest.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8
}
Expand All @@ -557,7 +556,7 @@ func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, tr
if dl_atmos {
Quality = fmt.Sprintf("%dkbps", Config.AtmosMax-2000)
} else if needDlAacLc {
Quality = fmt.Sprintf("256kbps")
Quality = "256kbps"
} else {
_, Quality, err = extractMedia(manifest.Attributes.ExtendedAssetUrls.EnhancedHls, true)
if err != nil {
Expand Down Expand Up @@ -674,15 +673,16 @@ func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, tr
fmt.Sprintf("artist=%s", meta.Data[0].Attributes.ArtistName),
fmt.Sprintf("lyrics=%s", lrc),
}
var trackCovPath string
if Config.EmbedCover {
if strings.Contains(albumId, "pl.") && Config.DlAlbumcoverForPlaylist {
err = writeCover(sanAlbumFolder, track.ID, track.Attributes.Artwork.URL)
trackCovPath, err = writeCover(sanAlbumFolder, track.ID, track.Attributes.Artwork.URL)
if err != nil {
fmt.Println("Failed to write cover.")
}
tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", sanAlbumFolder, track.ID, Config.CoverFormat))
tags = append(tags, fmt.Sprintf("cover=%s", trackCovPath))
} else {
tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", sanAlbumFolder, "cover", Config.CoverFormat))
tags = append(tags, fmt.Sprintf("cover=%s", covPath))
}
}
tagsString := strings.Join(tags, ":")
Expand All @@ -692,9 +692,9 @@ func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, tr
counter.Error++
return
}
if strings.Contains(albumId, "pl.") && Config.DlAlbumcoverForPlaylist {
if err := os.Remove(fmt.Sprintf("%s/%s.%s", sanAlbumFolder, track.ID, Config.CoverFormat)); err != nil {
fmt.Printf("Error deleting file: %s/%s.%s\n", sanAlbumFolder, track.ID, Config.CoverFormat)
if strings.Contains(albumId, "pl.") && Config.DlAlbumcoverForPlaylist && trackCovPath != "" {
if err := os.Remove(trackCovPath); err != nil {
fmt.Printf("Error deleting file: %s\n", trackCovPath)
counter.Error++
return
}
Expand Down Expand Up @@ -824,7 +824,7 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
}
var EnhancedHls_m3u8 string
if needCheck {
EnhancedHls_m3u8, err = checkM3u8(meta.Data[0].Relationships.Tracks.Data[0].ID, "album")
EnhancedHls_m3u8, _ = checkM3u8(meta.Data[0].Relationships.Tracks.Data[0].ID, "album")
if strings.HasSuffix(EnhancedHls_m3u8, ".m3u8") {
manifest1.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8
}
Expand Down Expand Up @@ -889,14 +889,14 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
//get artist cover
if Config.SaveArtistCover && !(strings.Contains(albumId, "pl.")) {
if len(meta.Data[0].Relationships.Artists.Data) > 0 {
err = writeCover(singerFolder, "folder", meta.Data[0].Relationships.Artists.Data[0].Attributes.Artwork.Url)
_, err = writeCover(singerFolder, "folder", meta.Data[0].Relationships.Artists.Data[0].Attributes.Artwork.Url)
if err != nil {
fmt.Println("Failed to write artist cover.")
}
}
}
//get album cover
err = writeCover(sanAlbumFolder, "cover", meta.Data[0].Attributes.Artwork.URL)
covPath, err := writeCover(sanAlbumFolder, "cover", meta.Data[0].Attributes.Artwork.URL)
if err != nil {
fmt.Println("Failed to write cover.")
}
Expand Down Expand Up @@ -971,7 +971,7 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
for trackNum, track := range meta.Data[0].Relationships.Tracks.Data {
trackNum++
if urlArg_i == track.ID {
downloadTrack(trackNum, trackTotal, meta, track, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec, &counter)
downloadTrack(trackNum, trackTotal, meta, track, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec, covPath)
return nil
}
}
Expand Down Expand Up @@ -1097,7 +1097,7 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
continue
}
if isInArray(selected, trackNum) {
downloadTrack(trackNum, trackTotal, meta, track, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec, &counter)
downloadTrack(trackNum, trackTotal, meta, track, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec, covPath)
}
}
return nil
Expand Down Expand Up @@ -1282,7 +1282,7 @@ func main() {
"{ArtistId}", "",
).Replace(Config.ArtistFolderFormat)
if mvSaveDir != "" {
mvSaveDir = filepath.Join(Config.AlacSaveFolder, mvSaveDir)
mvSaveDir = filepath.Join(Config.AlacSaveFolder, forbiddenNames.ReplaceAllString(mvSaveDir, "_"))
} else {
mvSaveDir = Config.AlacSaveFolder
}
Expand Down Expand Up @@ -1354,12 +1354,18 @@ func mvDownloader(adamID string, saveDir string, token string, storefront string
}
}

if strings.HasSuffix(saveDir, ".") {
saveDir = strings.ReplaceAll(saveDir, ".", "")
}
saveDir = strings.TrimSpace(saveDir)

vidPath := filepath.Join(saveDir, fmt.Sprintf("%s_vid.mp4", adamID))
audPath := filepath.Join(saveDir, fmt.Sprintf("%s_aud.mp4", adamID))
mvSaveName := MVInfo.Data[0].Attributes.Name
mvSaveName := fmt.Sprintf("%s (%s)", MVInfo.Data[0].Attributes.Name, adamID)
if meta != nil {
mvSaveName = fmt.Sprintf("%02d. %s", trackNum, MVInfo.Data[0].Attributes.Name)
}

mvOutPath := filepath.Join(saveDir, fmt.Sprintf("%s.mp4", forbiddenNames.ReplaceAllString(mvSaveName, "_")))

fmt.Println(MVInfo.Data[0].Attributes.Name)
Expand All @@ -1372,7 +1378,7 @@ func mvDownloader(adamID string, saveDir string, token string, storefront string

mvm3u8url, _, _ := runv3.GetWebplayback(adamID, token, mediaUserToken, true)
if mvm3u8url == "" {
return errors.New("media-user-token may wrong or expired.")
return errors.New("media-user-token may wrong or expired")
}

os.MkdirAll(saveDir, os.ModePerm)
Expand Down Expand Up @@ -1435,21 +1441,22 @@ func mvDownloader(adamID string, saveDir string, token string, storefront string
}

// Extract and save thumbnail if enabled
if Config.SaveThumbnailImage {
var covPath string
//强制嵌入封面
if true {
// Get the highest quality thumbnail URL from the MV info
thumbURL := MVInfo.Data[0].Attributes.Artwork.URL
thumbURL = strings.Replace(thumbURL, "{w}x{h}", Config.CoverSize, 1)

// Generate base name without extension
baseThumbName := forbiddenNames.ReplaceAllString(mvSaveName, "_") + "_thumbnail"

// Download and save thumbnail
err = writeCover(saveDir, baseThumbName, thumbURL)
covPath, err = writeCover(saveDir, baseThumbName, thumbURL)
if err != nil {
fmt.Println("Failed to save MV thumbnail:", err)
} else {
fmt.Println("MV thumbnail saved successfully")
tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", saveDir, baseThumbName, Config.CoverFormat))
//fmt.Println("MV thumbnail saved successfully")
tags = append(tags, fmt.Sprintf("cover=%s", covPath))
}
}

Expand All @@ -1464,6 +1471,7 @@ func mvDownloader(adamID string, saveDir string, token string, storefront string
fmt.Printf("\rMV Remuxed. \n")
defer os.Remove(vidPath)
defer os.Remove(audPath)
defer os.Remove(covPath)

return nil
}
Expand Down
1 change: 0 additions & 1 deletion utils/structs/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ type ConfigSet struct {
DlAlbumcoverForPlaylist bool `yaml:"dl-albumcover-for-playlist"`
MVAudioType string `yaml:"mv-audio-type"`
MVMax int `yaml:"mv-max"`
SaveThumbnailImage bool `yaml:"save-thumbnail-image"`
}

type Counter struct {
Expand Down

0 comments on commit 6795982

Please sign in to comment.