add playlists and atmos support

pull/1/head
zhaarey 6 months ago
parent 0b759e338e
commit d7a8488845
  1. 1
      .gitignore
  2. 3
      README.md
  3. 32
      main.go
  4. 1645
      main_atmos.go

1
.gitignore vendored

@ -4,4 +4,5 @@
!go.mod !go.mod
!go.sum !go.sum
!main.go !main.go
!main_atmos.go
!README.md !README.md

@ -9,3 +9,6 @@ Original script by Sorrow. Modified by me to include some fixes and improvements
5. Start frida server. 5. Start frida server.
6. Start the frida agent: `frida -U -l agent.js -f com.apple.android.music`. 6. Start the frida agent: `frida -U -l agent.js -f com.apple.android.music`.
7. Start downloading some albums: `go run main.go https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511`. 7. Start downloading some albums: `go run main.go https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511`.
8. Start downloading some playlists: `go run main.go https://music.apple.com/us/playlist/taylor-swift-essentials/pl.3950454ced8c45a3b0cc693c2a7db97b` or `go run main.go https://music.apple.com/us/playlist/hi-res-lossless-24-bit-192khz/pl.u-MDAWvpjt38370N`.
9. For dolby atmos: `go run main_atmos.go https://music.apple.com/us/album/1989-taylors-version-deluxe/1713845538`.

@ -714,6 +714,7 @@ func writeM4a(w *mp4.Writer, info *SongInfo, meta *AutoGenerated, data []byte, t
return err return err
} }
// plID, err := strconv.ParseUint(album.ID, 10, 32) // plID, err := strconv.ParseUint(album.ID, 10, 32)
// if err != nil { // if err != nil {
// return err // return err
@ -896,6 +897,17 @@ func decryptSong(info *SongInfo, keys []string, manifest *AutoGenerated, filenam
func checkUrl(url string) (string, string) { func checkUrl(url string) (string, string) {
pat := regexp.MustCompile(`^(?:https:\/\/(?:beta\.music|music)\.apple\.com\/(\w{2})(?:\/album|\/album\/.+))\/(?:id)?(\d[^\D]+)(?:$|\?)`) pat := regexp.MustCompile(`^(?:https:\/\/(?:beta\.music|music)\.apple\.com\/(\w{2})(?:\/album|\/album\/.+))\/(?:id)?(\d[^\D]+)(?:$|\?)`)
matches := pat.FindAllStringSubmatch(url, -1) matches := pat.FindAllStringSubmatch(url, -1)
if matches == nil {
return "", ""
} else {
return matches[0][1], matches[0][2]
}
}
func checkUrlPlaylist(url string) (string, string) {
pat := regexp.MustCompile(`^(?:https:\/\/(?:beta\.music|music)\.apple\.com\/(\w{2})(?:\/playlist|\/playlist\/.+))\/(?:id)?(pl\.[\w-]+)(?:$|\?)`)
matches := pat.FindAllStringSubmatch(url, -1)
if matches == nil { if matches == nil {
return "", "" return "", ""
} else { } else {
@ -903,8 +915,16 @@ func checkUrl(url string) (string, string) {
} }
} }
func getMeta(albumId string, token string, storefront string) (*AutoGenerated, error) { func getMeta(albumId string, token string, storefront string) (*AutoGenerated, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("https://amp-api.music.apple.com/v1/catalog/%s/albums/%s", storefront, albumId), nil) var mtype string
if strings.Contains(albumId, "pl.") {
mtype = "playlists"
} else {
mtype = "albums"
}
req, err := http.NewRequest("GET", fmt.Sprintf("https://amp-api.music.apple.com/v1/catalog/%s/%s/%s", storefront,mtype, albumId), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -973,6 +993,8 @@ func writeCover(sanAlbumFolder, url string) error {
} }
func rip(albumId string, token string, storefront string) error { func rip(albumId string, token string, storefront string) error {
meta, err := getMeta(albumId, token, storefront) meta, err := getMeta(albumId, token, storefront)
if err != nil { if err != nil {
fmt.Println("Failed to get album metadata.\n") fmt.Println("Failed to get album metadata.\n")
@ -1050,7 +1072,13 @@ func main() {
albumTotal := len(os.Args[1:]) albumTotal := len(os.Args[1:])
for albumNum, url := range os.Args[1:] { for albumNum, url := range os.Args[1:] {
fmt.Printf("Album %d of %d:\n", albumNum+1, albumTotal) fmt.Printf("Album %d of %d:\n", albumNum+1, albumTotal)
storefront, albumId := checkUrl(url) var storefront, albumId string
if strings.Contains(url, "playlist") {
storefront, albumId = checkUrlPlaylist(url)
} else {
storefront, albumId = checkUrl(url)
}
if albumId == "" { if albumId == "" {
fmt.Printf("Invalid URL: %s\n", url) fmt.Printf("Invalid URL: %s\n", url)
continue continue

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save