Compare commits

...

2 Commits

Author SHA1 Message Date
zhaarey b98e4c698c fix 3 months ago
zhaarey e77cd8291d add limit folder length and select all album command 3 months ago
  1. 12
      README.md
  2. 1
      config.yaml
  3. 33
      main.go

@ -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)`

@ -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}"

@ -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)
@ -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)
}

Loading…
Cancel
Save