diff --git a/config.yaml b/config.yaml index be60959..5551435 100644 --- a/config.yaml +++ b/config.yaml @@ -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 \ No newline at end of file +mv-max: 2160 \ No newline at end of file diff --git a/main.go b/main.go index 83b1913..0d62441 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "log" "net" "net/http" @@ -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 ( @@ -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 } @@ -411,7 +410,7 @@ 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 { @@ -419,7 +418,7 @@ func getSongLyrics(songId string, storefront string, token string, userToken str } } -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] @@ -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) @@ -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 { @@ -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) @@ -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 } @@ -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 { @@ -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, ":") @@ -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 } @@ -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 } @@ -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.") } @@ -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 } } @@ -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 @@ -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 } @@ -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) @@ -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) @@ -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)) } } @@ -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 } diff --git a/utils/structs/structs.go b/utils/structs/structs.go index 639165b..10ebfcf 100644 --- a/utils/structs/structs.go +++ b/utils/structs/structs.go @@ -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 {