diff --git a/README.md b/README.md index ae265c9..069872a 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ 3. 运行结束后显示总体完成情况 4. 自动内嵌封面和LRC歌词(需要media-user-token,获取方式看最后的说明) 5. 自动构建 可以到 [Actions](https://github.com/zhaarey/apple-music-alac-atmos-downloader/actions) 页面下载最新自动构建版本 可以直接`main.exe url` -6. main 支持使用 go run main.go "txt文件地址" txt文件名需要指定格式 例如 cn_1707581102_THE BOOK 3.txt 建议使用这个[Reqable 脚本代码](https://telegra.ph/Reqable-For-Apple-Music-05-01) 自动生成 -7. main 支持check 可以填入文本地址 或API数据库. -8. 新增get-m3u8-from-device 改为true 且设置端口`adb forward tcp:20020 tcp:20020`即从模拟器获取m3u8 -9. 文件夹和文件支持模板 -10. 支持下载歌手 `go run main.go https://music.apple.com/us/artist/taylor-swift/159260351` -11. 新增[wrapper](https://github.com/zhaarey/wrapper/releases)模式 目前只能linux运行,解密速度超快,基本秒解 +6. main 支持check 可以填入文本地址 或API数据库. +7. 新增get-m3u8-from-device 改为true 且设置端口`adb forward tcp:20020 tcp:20020`即从模拟器获取m3u8 +8. 文件夹和文件支持模板 +9. 支持下载歌手 `go run main.go https://music.apple.com/us/artist/taylor-swift/159260351` `--all-album` 自动选择歌手的所有专辑 +10. 新增[wrapper](https://github.com/zhaarey/wrapper/releases)模式 目前只能linux运行,解密速度超快,基本秒解 +11. `limit-max`支持限制长度 默认200 本项目仅支持ALAC和Atmos - `alac (audio-alac-stereo)` diff --git a/config.yaml b/config.yaml index 62d23ee..013f315 100644 --- a/config.yaml +++ b/config.yaml @@ -16,6 +16,7 @@ get-m3u8-port: "127.0.0.1:20020" get-m3u8-from-device: false alac-max: 192000 #192000 96000 48000 44100 atmos-max: 2768 #2768 2448 +limit-max: 200 #{AlbumId} {AlbumName} {ArtistName} {ReleaseDate} {ReleaseYear} {UPC} {Copyright} {Quality} {Codec} {Tag} {RecordLabel} #example: {ReleaseYear} - {ArtistName} - {AlbumName}({AlbumId})({UPC})({Copyright}){Codec} album-folder-format: "{AlbumName}" diff --git a/main.go b/main.go index 09e6702..773f259 100644 --- a/main.go +++ b/main.go @@ -39,6 +39,7 @@ var ( ) var dl_atmos = false var dl_select = false +var artist_select = false type Config struct { MediaUserToken string `yaml:"media-user-token"` @@ -66,6 +67,7 @@ type Config struct { GetM3u8FromDevice bool `yaml:"get-m3u8-from-device"` AlacMax int `yaml:"alac-max"` AtmosMax int `yaml:"atmos-max"` + LimitMax int `yaml:"limit-max"` UseSongInfoForPlaylist bool `yaml:"use-songinfo-for-playlist"` DlAlbumcoverForPlaylist bool `yaml:"dl-albumcover-for-playlist"` } @@ -101,6 +103,13 @@ func loadConfig() error { return nil } +func LimitString(s string) string { + if len([]rune(s)) > config.LimitMax { + return string([]rune(s)[:config.LimitMax]) + } + return s +} + func (s *SongInfo) Duration() (ret uint64) { for i := range s.samples { ret += uint64(s.samples[i].duration) @@ -726,12 +735,12 @@ func writeM4a(w *mp4.Writer, info *SongInfo, meta *AutoGenerated, data []byte, t return err } - err = addMeta(mp4.BoxType{'\251', 'A', 'R', 'T'}, meta.Data[0].Relationships.Tracks.Data[index].Attributes.ArtistName) + err = addMeta(mp4.BoxType{'\251', 'A', 'R', 'T'}, meta.Data[0].Attributes.ArtistName) if err != nil { return err } - err = addMeta(mp4.BoxType{'s', 'o', 'a', 'r'}, meta.Data[0].Relationships.Tracks.Data[index].Attributes.ArtistName) + err = addMeta(mp4.BoxType{'s', 'o', 'a', 'r'}, meta.Data[0].Attributes.ArtistName) if err != nil { return err } @@ -796,12 +805,12 @@ func writeM4a(w *mp4.Writer, info *SongInfo, meta *AutoGenerated, data []byte, t if len(meta.Data) > 0 { album := meta.Data[0] - err = addMeta(mp4.BoxType{'a', 'A', 'R', 'T'}, meta.Data[0].Relationships.Tracks.Data[index].Attributes.ArtistName) + err = addMeta(mp4.BoxType{'a', 'A', 'R', 'T'}, meta.Data[0].Attributes.ArtistName) if err != nil { return err } - err = addMeta(mp4.BoxType{'s', 'o', 'a', 'a'}, meta.Data[0].Relationships.Tracks.Data[index].Attributes.ArtistName) + err = addMeta(mp4.BoxType{'s', 'o', 'a', 'a'}, meta.Data[0].Attributes.ArtistName) if err != nil { return err } @@ -1105,6 +1114,10 @@ func checkArtist(artistUrl string, token string) ([]string, error) { for i, option := range options { fmt.Printf("%02d: %s\n", i+1, option) } + if artist_select { + fmt.Println("You have selected all options:") + return urls, nil + } reader := bufio.NewReader(os.Stdin) fmt.Println("Please select from the following options (multiple options separated by commas, ranges supported, or type 'all' to select all)") fmt.Print("Enter your choice: ") @@ -1344,12 +1357,12 @@ func rip(albumId string, token string, storefront string, userToken string) erro ).Replace(config.ArtistFolderFormat) } else if len(meta.Data[0].Relationships.Artists.Data) > 0 { singerFoldername = strings.NewReplacer( - "{ArtistName}", meta.Data[0].Attributes.ArtistName, + "{ArtistName}", LimitString(meta.Data[0].Attributes.ArtistName), "{ArtistId}", meta.Data[0].Relationships.Artists.Data[0].ID, ).Replace(config.ArtistFolderFormat) } else { singerFoldername = strings.NewReplacer( - "{ArtistName}", meta.Data[0].Attributes.ArtistName, + "{ArtistName}", LimitString(meta.Data[0].Attributes.ArtistName), "{ArtistId}", "", ).Replace(config.ArtistFolderFormat) } @@ -1408,7 +1421,7 @@ func rip(albumId string, token string, storefront string, userToken string) erro if strings.Contains(albumId, "pl.") { albumFolder = strings.NewReplacer( "{ArtistName}", "Apple Music", - "{PlaylistName}", meta.Data[0].Attributes.Name, + "{PlaylistName}", LimitString(meta.Data[0].Attributes.Name), "{PlaylistId}", albumId, "{Quality}", Quality, "{Codec}", Codec, @@ -1418,8 +1431,8 @@ func rip(albumId string, token string, storefront string, userToken string) erro albumFolder = strings.NewReplacer( "{ReleaseDate}", meta.Data[0].Attributes.ReleaseDate, "{ReleaseYear}", meta.Data[0].Attributes.ReleaseDate[:4], - "{ArtistName}", meta.Data[0].Attributes.ArtistName, - "{AlbumName}", meta.Data[0].Attributes.Name, + "{ArtistName}", LimitString(meta.Data[0].Attributes.ArtistName), + "{AlbumName}", LimitString(meta.Data[0].Attributes.Name), "{UPC}", meta.Data[0].Attributes.Upc, "{RecordLabel}", meta.Data[0].Attributes.RecordLabel, "{Copyright}", meta.Data[0].Attributes.Copyright, @@ -1574,7 +1587,7 @@ func rip(albumId string, token string, storefront string, userToken string) erro songName := strings.NewReplacer( "{SongId}", track.ID, "{SongNumer}", fmt.Sprintf("%02d", trackNum), - "{SongName}", track.Attributes.Name, + "{SongName}", LimitString(track.Attributes.Name), "{DiscNumber}", fmt.Sprintf("%0d", track.Attributes.DiscNumber), "{TrackNumber}", fmt.Sprintf("%0d", track.Attributes.TrackNumber), "{Quality}", Quality, @@ -1675,7 +1688,7 @@ func rip(albumId string, token string, storefront string, userToken string) erro fmt.Sprintf("album_artist=%s", meta.Data[0].Attributes.ArtistName), fmt.Sprintf("composer=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.ComposerName), fmt.Sprintf("writer=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.ComposerName), - fmt.Sprintf("performer=%s", meta.Data[0].Attributes.ArtistName), + fmt.Sprintf("performer=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.ArtistName), fmt.Sprintf("copyright=%s", meta.Data[0].Attributes.Copyright), fmt.Sprintf("ISRC=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.Isrc), fmt.Sprintf("UPC=%s", meta.Data[0].Attributes.Upc), @@ -1756,6 +1769,8 @@ func main() { dl_atmos = true } else if strings.Contains(arg, "--select") { dl_select = true + } else if strings.Contains(arg, "--all-album") { + artist_select = true } else { dlArgs = append(dlArgs, arg) }