add atmos and select to main.go

--atmos,--select
pull/23/merge
zhaarey 2 months ago
parent af1a310cb6
commit c1c62ab94c
  1. 519
      main.go

@ -37,6 +37,8 @@ const (
var ( var (
forbiddenNames = regexp.MustCompile(`[/\\<>:"|?*]`) forbiddenNames = regexp.MustCompile(`[/\\<>:"|?*]`)
) )
var dl_atmos = false
var dl_select = false
type Config struct { type Config struct {
MediaUserToken string `yaml:"media-user-token"` MediaUserToken string `yaml:"media-user-token"`
@ -63,6 +65,7 @@ type Config struct {
GetM3u8Port string `yaml:"get-m3u8-port"` GetM3u8Port string `yaml:"get-m3u8-port"`
GetM3u8FromDevice bool `yaml:"get-m3u8-from-device"` GetM3u8FromDevice bool `yaml:"get-m3u8-from-device"`
AlacMax int `yaml:"alac-max"` AlacMax int `yaml:"alac-max"`
AtmosMax int `yaml:"atmos-max"`
UseSongInfoForPlaylist bool `yaml:"use-songinfo-for-playlist"` UseSongInfoForPlaylist bool `yaml:"use-songinfo-for-playlist"`
DlAlbumcoverForPlaylist bool `yaml:"dl-albumcover-for-playlist"` DlAlbumcoverForPlaylist bool `yaml:"dl-albumcover-for-playlist"`
} }
@ -109,6 +112,15 @@ func (*Alac) GetType() mp4.BoxType {
return BoxTypeAlac() return BoxTypeAlac()
} }
func isInArray(arr []int, target int) bool {
for _, num := range arr {
if num == target {
return true
}
}
return false
}
func fileExists(path string) (bool, error) { func fileExists(path string) (bool, error) {
f, err := os.Stat(path) f, err := os.Stat(path)
if err == nil { if err == nil {
@ -1009,6 +1021,14 @@ func decryptSong(info *SongInfo, keys []string, manifest *AutoGenerated, filenam
return err return err
} }
defer create.Close() defer create.Close()
if dl_atmos {
_, err = create.Write(decrypted)
if err != nil {
panic(err)
}
return nil
}
return writeM4a(mp4.NewWriter(create), info, manifest, decrypted, trackNum, trackTotal) return writeM4a(mp4.NewWriter(create), info, manifest, decrypted, trackNum, trackTotal)
} }
@ -1304,6 +1324,12 @@ func writeLyrics(sanAlbumFolder, filename string, lrc string) error {
} }
func rip(albumId string, token string, storefront string, userToken string) error { func rip(albumId string, token string, storefront string, userToken string) error {
var Codec string
if dl_atmos {
Codec = "Atmos"
} else {
Codec = "ALAC"
}
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")
@ -1336,20 +1362,24 @@ func rip(albumId string, token string, storefront string, userToken string) erro
singerFolder := filepath.Join(config.AlacSaveFolder, forbiddenNames.ReplaceAllString(singerFoldername, "_")) singerFolder := filepath.Join(config.AlacSaveFolder, forbiddenNames.ReplaceAllString(singerFoldername, "_"))
var Quality string var Quality string
if strings.Contains(config.AlbumFolderFormat, "Quality") { if strings.Contains(config.AlbumFolderFormat, "Quality") {
manifest1, err := getInfoFromAdam(meta.Data[0].Relationships.Tracks.Data[0].ID, token, storefront) if dl_atmos {
if err != nil { Quality = fmt.Sprintf("%dkbps", config.AtmosMax-2000)
fmt.Println("Failed to get manifest.\n", err)
} else { } else {
if manifest1.Attributes.ExtendedAssetUrls.EnhancedHls == "" { manifest1, err := getInfoFromAdam(meta.Data[0].Relationships.Tracks.Data[0].ID, token, storefront)
fmt.Println("Unavailable in ALAC.\n") if err != nil {
fmt.Println("Failed to get manifest.\n", err)
} else { } else {
EnhancedHls_m3u8, err := checkM3u8(meta.Data[0].Relationships.Tracks.Data[0].ID, "album") if manifest1.Attributes.ExtendedAssetUrls.EnhancedHls == "" {
if strings.HasPrefix(EnhancedHls_m3u8, "http") { fmt.Println("Unavailable.\n")
manifest1.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8 } else {
} EnhancedHls_m3u8, err := checkM3u8(meta.Data[0].Relationships.Tracks.Data[0].ID, "album")
Quality, err = extractMediaQuality(manifest1.Attributes.ExtendedAssetUrls.EnhancedHls) if strings.HasPrefix(EnhancedHls_m3u8, "http") {
if err != nil { manifest1.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8
fmt.Println("Failed to extract quality from manifest.\n", err) }
Quality, err = extractMediaQuality(manifest1.Attributes.ExtendedAssetUrls.EnhancedHls)
if err != nil {
fmt.Println("Failed to extract quality from manifest.\n", err)
}
} }
} }
} }
@ -1378,7 +1408,7 @@ func rip(albumId string, token string, storefront string, userToken string) erro
"{PlaylistName}", meta.Data[0].Attributes.Name, "{PlaylistName}", meta.Data[0].Attributes.Name,
"{PlaylistId}", albumId, "{PlaylistId}", albumId,
"{Quality}", Quality, "{Quality}", Quality,
"{Codec}", "ALAC", "{Codec}", Codec,
"{Tag}", Tag_string, "{Tag}", Tag_string,
).Replace(config.PlaylistFolderFormat) ).Replace(config.PlaylistFolderFormat)
} else { } else {
@ -1392,7 +1422,7 @@ func rip(albumId string, token string, storefront string, userToken string) erro
"{Copyright}", meta.Data[0].Attributes.Copyright, "{Copyright}", meta.Data[0].Attributes.Copyright,
"{AlbumId}", albumId, "{AlbumId}", albumId,
"{Quality}", Quality, "{Quality}", Quality,
"{Codec}", "ALAC", "{Codec}", Codec,
"{Tag}", Tag_string, "{Tag}", Tag_string,
).Replace(config.AlbumFolderFormat) ).Replace(config.AlbumFolderFormat)
} }
@ -1448,157 +1478,260 @@ func rip(albumId string, token string, storefront string, userToken string) erro
} }
} }
trackTotal := len(meta.Data[0].Relationships.Tracks.Data) trackTotal := len(meta.Data[0].Relationships.Tracks.Data)
for trackNum, track := range meta.Data[0].Relationships.Tracks.Data { arr := make([]int, trackTotal)
trackNum++ for i := 0; i < trackTotal; i++ {
trackTotalnum += 1 arr[i] = i + 1
fmt.Printf("Track %d of %d:\n", trackNum, trackTotal) }
manifest, err := getInfoFromAdam(track.ID, token, storefront) selected := []int{}
if !dl_select {
selected = arr
} else {
fmt.Print("select: ")
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil { if err != nil {
fmt.Println("Failed to get manifest.\n", err) fmt.Println(err)
continue
}
if manifest.Attributes.ExtendedAssetUrls.EnhancedHls == "" {
fmt.Println("Unavailable in ALAC.")
continue
}
EnhancedHls_m3u8, err := checkM3u8(track.ID, "song")
if strings.HasPrefix(EnhancedHls_m3u8, "http") {
manifest.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8
} }
var Quality string input = strings.TrimSpace(input)
if strings.Contains(config.SongFileFormat, "Quality") { inputs := strings.Fields(input)
Quality, err = extractMediaQuality(manifest.Attributes.ExtendedAssetUrls.EnhancedHls)
for _, str := range inputs {
num, err := strconv.Atoi(str)
if err != nil { if err != nil {
fmt.Println("Failed to extract quality from manifest.\n", err) fmt.Printf("wrong '%s', skip...\n", str)
continue continue
} }
}
stringsToJoin := []string{} found := false
if track.Attributes.IsAppleDigitalMaster { for i := 0; i < len(arr); i++ {
if config.AppleMasterChoice != "" { if arr[i] == num {
stringsToJoin = append(stringsToJoin, config.AppleMasterChoice) selected = append(selected, num)
} found = true
} break
if track.Attributes.ContentRating == "explicit" { }
if config.ExplicitChoice != "" {
stringsToJoin = append(stringsToJoin, config.ExplicitChoice)
} }
}
if track.Attributes.ContentRating == "clean" { if !found {
if config.CleanChoice != "" { fmt.Printf("Option '%d' not found or already selected, skipping...\n", num)
stringsToJoin = append(stringsToJoin, config.CleanChoice)
} }
} }
Tag_string := strings.Join(stringsToJoin, " ")
songName := strings.NewReplacer( fmt.Println("Selected options:", selected)
"{SongId}", track.ID, }
"{SongNumer}", fmt.Sprintf("%02d", trackNum), for trackNum, track := range meta.Data[0].Relationships.Tracks.Data {
"{SongName}", track.Attributes.Name, trackNum++
"{DiscNumber}", fmt.Sprintf("%0d", track.Attributes.DiscNumber), if isInArray(selected, trackNum) {
"{TrackNumber}", fmt.Sprintf("%0d", track.Attributes.TrackNumber), trackTotalnum += 1
"{Quality}", Quality, fmt.Printf("Track %d of %d:\n", trackNum, trackTotal)
"{Tag}", Tag_string, manifest, err := getInfoFromAdam(track.ID, token, storefront)
"{Codec}", "ALAC",
).Replace(config.SongFileFormat)
fmt.Println(songName)
filename := fmt.Sprintf("%s.m4a", forbiddenNames.ReplaceAllString(songName, "_"))
lrcFilename := fmt.Sprintf("%s.lrc", forbiddenNames.ReplaceAllString(songName, "_"))
trackPath := filepath.Join(sanAlbumFolder, filename)
var lrc string = ""
if userToken != "your-media-user-token" && (config.EmbedLrc || config.SaveLrcFile) {
ttml, err := getSongLyrics(track.ID, storefront, token, userToken)
if err != nil { if err != nil {
fmt.Println("Failed to get lyrics") fmt.Println("Failed to get manifest.\n", err)
} else { continue
lrc, err = conventTTMLToLRC(ttml) }
if manifest.Attributes.ExtendedAssetUrls.EnhancedHls == "" {
fmt.Println("Unavailable.")
continue
}
EnhancedHls_m3u8, err := checkM3u8(track.ID, "song")
if strings.HasPrefix(EnhancedHls_m3u8, "http") {
manifest.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8
}
var Quality string
if strings.Contains(config.SongFileFormat, "Quality") {
if dl_atmos {
Quality = fmt.Sprintf("%dkbps", config.AtmosMax-2000)
} else {
Quality, err = extractMediaQuality(manifest.Attributes.ExtendedAssetUrls.EnhancedHls)
if err != nil {
fmt.Println("Failed to extract quality from manifest.\n", err)
continue
}
}
}
stringsToJoin := []string{}
if track.Attributes.IsAppleDigitalMaster {
if config.AppleMasterChoice != "" {
stringsToJoin = append(stringsToJoin, config.AppleMasterChoice)
}
}
if track.Attributes.ContentRating == "explicit" {
if config.ExplicitChoice != "" {
stringsToJoin = append(stringsToJoin, config.ExplicitChoice)
}
}
if track.Attributes.ContentRating == "clean" {
if config.CleanChoice != "" {
stringsToJoin = append(stringsToJoin, config.CleanChoice)
}
}
Tag_string := strings.Join(stringsToJoin, " ")
songName := strings.NewReplacer(
"{SongId}", track.ID,
"{SongNumer}", fmt.Sprintf("%02d", trackNum),
"{SongName}", track.Attributes.Name,
"{DiscNumber}", fmt.Sprintf("%0d", track.Attributes.DiscNumber),
"{TrackNumber}", fmt.Sprintf("%0d", track.Attributes.TrackNumber),
"{Quality}", Quality,
"{Tag}", Tag_string,
"{Codec}", Codec,
).Replace(config.SongFileFormat)
fmt.Println(songName)
filename := fmt.Sprintf("%s.m4a", forbiddenNames.ReplaceAllString(songName, "_"))
if dl_atmos {
filename = fmt.Sprintf("%s.ec3", forbiddenNames.ReplaceAllString(songName, "_"))
}
m4afilename := fmt.Sprintf("%s.m4a", forbiddenNames.ReplaceAllString(songName, "_"))
lrcFilename := fmt.Sprintf("%s.lrc", forbiddenNames.ReplaceAllString(songName, "_"))
trackPath := filepath.Join(sanAlbumFolder, filename)
m4atrackPath := filepath.Join(sanAlbumFolder, m4afilename)
var lrc string = ""
if userToken != "your-media-user-token" && (config.EmbedLrc || config.SaveLrcFile) {
ttml, err := getSongLyrics(track.ID, storefront, token, userToken)
if err != nil { if err != nil {
fmt.Printf("Failed to parse lyrics: %s \n", err) fmt.Println("Failed to get lyrics")
} else { } else {
if config.SaveLrcFile { lrc, err = conventTTMLToLRC(ttml)
err := writeLyrics(sanAlbumFolder, lrcFilename, lrc) if err != nil {
if err != nil { fmt.Printf("Failed to parse lyrics: %s \n", err)
fmt.Printf("Failed to write lyrics") } else {
} if config.SaveLrcFile {
if !config.EmbedLrc { err := writeLyrics(sanAlbumFolder, lrcFilename, lrc)
lrc = "" if err != nil {
fmt.Printf("Failed to write lyrics")
}
if !config.EmbedLrc {
lrc = ""
}
} }
} }
} }
} }
} exists, err := fileExists(trackPath)
exists, err := fileExists(trackPath) if err != nil {
if err != nil { fmt.Println("Failed to check if track exists.")
fmt.Println("Failed to check if track exists.") }
} if exists {
if exists { fmt.Println("Track already exists locally.")
fmt.Println("Track already exists locally.") oktrackNum += 1
oktrackNum += 1 continue
continue }
} m4aexists, err := fileExists(m4atrackPath)
if err != nil {
fmt.Println("Failed to check if track exists.")
}
if m4aexists {
fmt.Println("Track already exists locally.")
oktrackNum += 1
continue
}
trackUrl, keys, err := extractMedia(manifest.Attributes.ExtendedAssetUrls.EnhancedHls) trackUrl, keys, err := extractMedia(manifest.Attributes.ExtendedAssetUrls.EnhancedHls)
if err != nil { if err != nil {
fmt.Println("Failed to extract info from manifest.\n", err) fmt.Println("Failed to extract info from manifest.\n", err)
continue continue
} }
info, err := extractSong(trackUrl) info, err := extractSong(trackUrl)
if err != nil { if err != nil {
fmt.Println("Failed to extract track.", err) fmt.Println("Failed to extract track.", err)
continue continue
} }
samplesOk := true samplesOk := true
for samplesOk { for samplesOk {
for _, i := range info.samples { for _, i := range info.samples {
if int(i.descIndex) >= len(keys) { if int(i.descIndex) >= len(keys) {
fmt.Println("Decryption size mismatch.") fmt.Println("Decryption size mismatch.")
samplesOk = false samplesOk = false
}
} }
break
} }
break if !samplesOk {
} continue
if !samplesOk { }
continue err = decryptSong(info, keys, meta, trackPath, trackNum, trackTotal)
} if err != nil {
err = decryptSong(info, keys, meta, trackPath, trackNum, trackTotal) fmt.Println("Failed to decrypt track.\n", err)
if err != nil { continue
fmt.Println("Failed to decrypt track.\n", err) }
continue tags := []string{
} fmt.Sprintf("lyrics=%s", lrc),
tags := []string{ }
fmt.Sprintf("lyrics=%s", lrc),
} index := trackNum - 1
if track.Attributes.ContentRating == "explicit" { if dl_atmos {
tags = append(tags, "rating=1") tags = []string{
} else if track.Attributes.ContentRating == "clean" { "tool=",
tags = append(tags, "rating=2") fmt.Sprintf("lyrics=%s", lrc),
} else { fmt.Sprintf("title=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.Name),
tags = append(tags, "rating=0") fmt.Sprintf("artist=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.ArtistName),
} fmt.Sprintf("genre=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.GenreNames[0]),
if config.EmbedCover { fmt.Sprintf("created=%s", meta.Data[0].Attributes.ReleaseDate),
if strings.Contains(albumId, "pl.") && config.DlAlbumcoverForPlaylist { fmt.Sprintf("album_artist=%s", meta.Data[0].Attributes.ArtistName),
err = writeCover(sanAlbumFolder, track.ID, track.Attributes.Artwork.URL) fmt.Sprintf("composer=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.ComposerName),
if err != nil { fmt.Sprintf("writer=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.ComposerName),
fmt.Println("Failed to write cover.") fmt.Sprintf("performer=%s", meta.Data[0].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),
}
if strings.Contains(albumId, "pl.") && !config.UseSongInfoForPlaylist {
tags = append(tags, "disk=1/1")
tags = append(tags, fmt.Sprintf("track=%s", trackNum))
tags = append(tags, fmt.Sprintf("tracknum=%d/%d", trackNum, trackTotal))
tags = append(tags, fmt.Sprintf("album=%s", meta.Data[0].Attributes.Name))
} else {
tags = append(tags, fmt.Sprintf("disk=%d/%d", meta.Data[0].Relationships.Tracks.Data[index].Attributes.DiscNumber, meta.Data[0].Relationships.Tracks.Data[trackTotal-1].Attributes.DiscNumber))
tags = append(tags, fmt.Sprintf("track=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.TrackNumber))
tags = append(tags, fmt.Sprintf("tracknum=%d/%d", meta.Data[0].Relationships.Tracks.Data[index].Attributes.TrackNumber, trackTotal))
tags = append(tags, fmt.Sprintf("album=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.AlbumName))
} }
tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", sanAlbumFolder, track.ID, config.CoverFormat)) }
if track.Attributes.ContentRating == "explicit" {
tags = append(tags, "rating=1")
} else if track.Attributes.ContentRating == "clean" {
tags = append(tags, "rating=2")
} else { } else {
tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", sanAlbumFolder, "cover", config.CoverFormat)) tags = append(tags, "rating=0")
} }
} if config.EmbedCover {
tagsString := strings.Join(tags, ":") if strings.Contains(albumId, "pl.") && config.DlAlbumcoverForPlaylist {
cmd := exec.Command("MP4Box", "-itags", tagsString, trackPath) err = writeCover(sanAlbumFolder, track.ID, track.Attributes.Artwork.URL)
if err := cmd.Run(); err != nil { if err != nil {
fmt.Printf("Embed failed: %v\n", err) fmt.Println("Failed to write cover.")
continue }
} tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", sanAlbumFolder, track.ID, config.CoverFormat))
if strings.Contains(albumId, "pl.") && config.DlAlbumcoverForPlaylist { } else {
if err := os.Remove(fmt.Sprintf("%s/%s.%s", sanAlbumFolder, track.ID, config.CoverFormat)); err != nil { tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", sanAlbumFolder, "cover", config.CoverFormat))
fmt.Printf("Error deleting file: %s/%s.%s\n", sanAlbumFolder, track.ID, config.CoverFormat) }
}
tagsString := strings.Join(tags, ":")
cmd := exec.Command("MP4Box", "-itags", tagsString, trackPath)
if dl_atmos {
cmd = exec.Command("MP4Box", "-add", trackPath, "-name", fmt.Sprintf("1=%s", meta.Data[0].Relationships.Tracks.Data[index].Attributes.Name), "-itags", tagsString, "-brand", "mp42", "-ab", "dby1", m4atrackPath)
}
if err := cmd.Run(); err != nil {
fmt.Printf("Embed failed: %v\n", err)
continue continue
} }
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)
continue
}
}
if dl_atmos {
fmt.Printf("Deleting original EC3 file: %s\n", filepath.Base(trackPath))
if err := os.Remove(trackPath); err != nil {
fmt.Printf("Error deleting file: %v\n", err)
continue
}
fmt.Printf("Successfully processed and deleted %s\n", filepath.Base(trackPath))
}
oktrackNum += 1
} }
oktrackNum += 1
} }
return err return err
} }
@ -1614,6 +1747,17 @@ func main() {
fmt.Println("Failed to get token.") fmt.Println("Failed to get token.")
return return
} }
var dlArgs []string
for _, arg := range os.Args {
if strings.Contains(arg, "--atmos") {
dl_atmos = true
} else if strings.Contains(arg, "--select") {
dl_select = true
} else {
dlArgs = append(dlArgs, arg)
}
}
os.Args = dlArgs
if strings.Contains(os.Args[1], "/artist/") { if strings.Contains(os.Args[1], "/artist/") {
newArgs, err := checkArtist(os.Args[1], token) newArgs, err := checkArtist(os.Args[1], token)
if err != nil { if err != nil {
@ -1882,26 +2026,46 @@ func extractMedia(b string) (string, []string, error) {
return master.Variants[i].AverageBandwidth > master.Variants[j].AverageBandwidth return master.Variants[i].AverageBandwidth > master.Variants[j].AverageBandwidth
}) })
for _, variant := range master.Variants { for _, variant := range master.Variants {
if variant.Codecs == "alac" { if dl_atmos {
split := strings.Split(variant.Audio, "-") if variant.Codecs == "ec-3" {
length := len(split) split := strings.Split(variant.Audio, "-")
length_int, err := strconv.Atoi(split[length-2]) length := len(split)
if err != nil { length_int, err := strconv.Atoi(split[length-1])
return "", nil, err if err != nil {
return "", nil, err
}
if length_int <= config.AtmosMax {
fmt.Printf("%s\n", variant.Audio)
streamUrlTemp, err := masterUrl.Parse(variant.URI)
if err != nil {
panic(err)
}
streamUrl = streamUrlTemp
break
}
} }
if length_int <= config.AlacMax { } else {
fmt.Printf("%s-bit / %s Hz\n", split[length-1], split[length-2]) if variant.Codecs == "alac" {
streamUrlTemp, err := masterUrl.Parse(variant.URI) split := strings.Split(variant.Audio, "-")
length := len(split)
length_int, err := strconv.Atoi(split[length-2])
if err != nil { if err != nil {
panic(err) return "", nil, err
}
if length_int <= config.AlacMax {
fmt.Printf("%s-bit / %s Hz\n", split[length-1], split[length-2])
streamUrlTemp, err := masterUrl.Parse(variant.URI)
if err != nil {
panic(err)
}
streamUrl = streamUrlTemp
break
} }
streamUrl = streamUrlTemp
break
} }
} }
} }
if streamUrl == nil { if streamUrl == nil {
return "", nil, errors.New("no alac codec found") return "", nil, errors.New("no codec found")
} }
var keys []string var keys []string
keys = append(keys, prefetchKey) keys = append(keys, prefetchKey)
@ -1909,8 +2073,14 @@ func extractMedia(b string) (string, []string, error) {
regex := regexp.MustCompile(`"(skd?://[^"]*)"`) regex := regexp.MustCompile(`"(skd?://[^"]*)"`)
matches := regex.FindAllStringSubmatch(masterString, -1) matches := regex.FindAllStringSubmatch(masterString, -1)
for _, match := range matches { for _, match := range matches {
if strings.HasSuffix(match[1], "c23") || strings.HasSuffix(match[1], "c6") { if dl_atmos {
keys = append(keys, match[1]) if strings.HasSuffix(match[1], "c24") || strings.HasSuffix(match[1], "c6") {
keys = append(keys, match[1])
}
} else {
if strings.HasSuffix(match[1], "c23") || strings.HasSuffix(match[1], "c6") {
keys = append(keys, match[1])
}
} }
} }
return streamUrl.String(), keys, nil return streamUrl.String(), keys, nil
@ -1992,23 +2162,30 @@ func extractSong(url string) (*SongInfo, error) {
return nil, err return nil, err
} }
enca, err := mp4.ExtractBoxWithPayload(f, stbl[0], []mp4.BoxType{ var extracted *SongInfo
mp4.BoxTypeStsd(), if !dl_atmos {
mp4.BoxTypeEnca(), enca, err := mp4.ExtractBoxWithPayload(f, stbl[0], []mp4.BoxType{
}) mp4.BoxTypeStsd(),
if err != nil { mp4.BoxTypeEnca(),
return nil, err })
} if err != nil {
return nil, err
aalac, err := mp4.ExtractBoxWithPayload(f, &enca[0].Info, }
[]mp4.BoxType{BoxTypeAlac()})
if err != nil || len(aalac) != 1 {
return nil, err
}
extracted := &SongInfo{ aalac, err := mp4.ExtractBoxWithPayload(f, &enca[0].Info,
r: f, []mp4.BoxType{BoxTypeAlac()})
alacParam: aalac[0].Payload.(*Alac), if err != nil || len(aalac) != 1 {
return nil, err
}
extracted = &SongInfo{
r: f,
alacParam: aalac[0].Payload.(*Alac),
}
} else {
extracted = &SongInfo{
r: f,
// alacParam: aalac[0].Payload.(*Alac),
}
} }
moofs, err := mp4.ExtractBox(f, nil, []mp4.BoxType{ moofs, err := mp4.ExtractBox(f, nil, []mp4.BoxType{

Loading…
Cancel
Save