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