Merge pull request #55 from itouakirai/main
fix:歌手链接无mv时程序退出;debug模式未使用满血m3u8;Quality标签错误
This commit is contained in:
commit
459c2f0dc9
266
main.go
266
main.go
@ -40,7 +40,6 @@ var (
|
|||||||
dl_aac bool
|
dl_aac bool
|
||||||
dl_select bool
|
dl_select bool
|
||||||
dl_song bool
|
dl_song bool
|
||||||
dl_cover bool
|
|
||||||
artist_select bool
|
artist_select bool
|
||||||
debug_mode bool
|
debug_mode bool
|
||||||
alac_max *int
|
alac_max *int
|
||||||
@ -530,7 +529,7 @@ func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, tr
|
|||||||
} else if needDlAacLc {
|
} else if needDlAacLc {
|
||||||
Quality = fmt.Sprintf("256kbps")
|
Quality = fmt.Sprintf("256kbps")
|
||||||
} else {
|
} else {
|
||||||
Quality, err = extractMediaQuality(manifest.Attributes.ExtendedAssetUrls.EnhancedHls)
|
_, Quality, err = extractMedia(manifest.Attributes.ExtendedAssetUrls.EnhancedHls, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to extract quality from manifest.\n", err)
|
fmt.Println("Failed to extract quality from manifest.\n", err)
|
||||||
counter.Error++
|
counter.Error++
|
||||||
@ -626,7 +625,7 @@ func downloadTrack(trackNum int, trackTotal int, meta *structs.AutoGenerated, tr
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
trackM3u8Url, err := extractMedia(manifest.Attributes.ExtendedAssetUrls.EnhancedHls)
|
trackM3u8Url, _, err := extractMedia(manifest.Attributes.ExtendedAssetUrls.EnhancedHls, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("\u26A0 Failed to extract info from manifest:", err)
|
fmt.Println("\u26A0 Failed to extract info from manifest:", err)
|
||||||
counter.Unavailable++
|
counter.Unavailable++
|
||||||
@ -703,25 +702,25 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var m3u8Url string
|
var m3u8Url string
|
||||||
|
//Web端m3u8
|
||||||
if manifest.Attributes.ExtendedAssetUrls.EnhancedHls != "" {
|
if manifest.Attributes.ExtendedAssetUrls.EnhancedHls != "" {
|
||||||
m3u8Url = manifest.Attributes.ExtendedAssetUrls.EnhancedHls
|
m3u8Url = manifest.Attributes.ExtendedAssetUrls.EnhancedHls
|
||||||
} else if mediaUserToken != "" && len(mediaUserToken) > 10 {
|
}
|
||||||
// Try to get m3u8 from device if media-user-token is set
|
//设备端满血m3u8
|
||||||
|
needCheck := false
|
||||||
|
if Config.GetM3u8Mode == "all" {
|
||||||
|
needCheck = true
|
||||||
|
} else if Config.GetM3u8Mode == "hires" && contains(track.Attributes.AudioTraits, "hi-res-lossless") {
|
||||||
|
needCheck = true
|
||||||
|
}
|
||||||
|
if needCheck {
|
||||||
m3u8Url, err = checkM3u8(track.ID, "song")
|
m3u8Url, err = checkM3u8(track.ID, "song")
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to get m3u8 from device for track %d: %v\n", trackNum, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if m3u8Url != "" {
|
_, _, err = extractMedia(m3u8Url, true)
|
||||||
_, err = extractMediaQuality(m3u8Url)
|
if err != nil {
|
||||||
if err != nil {
|
fmt.Printf("Failed to extract quality info for track %d: %v\n", trackNum, err)
|
||||||
fmt.Printf("Failed to extract quality info for track %d: %v\n", trackNum, err)
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println("\nNo audio formats available - valid media-user-token may be required")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil // Return directly without showing statistics
|
return nil // Return directly without showing statistics
|
||||||
@ -795,7 +794,7 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
|
|||||||
manifest1.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8
|
manifest1.Attributes.ExtendedAssetUrls.EnhancedHls = EnhancedHls_m3u8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Quality, err = extractMediaQuality(manifest1.Attributes.ExtendedAssetUrls.EnhancedHls)
|
_, Quality, err = extractMedia(manifest1.Attributes.ExtendedAssetUrls.EnhancedHls, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to extract quality from manifest.\n", err)
|
fmt.Println("Failed to extract quality from manifest.\n", err)
|
||||||
}
|
}
|
||||||
@ -852,95 +851,6 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
|
|||||||
sanAlbumFolder := filepath.Join(singerFolder, forbiddenNames.ReplaceAllString(albumFolder, "_"))
|
sanAlbumFolder := filepath.Join(singerFolder, forbiddenNames.ReplaceAllString(albumFolder, "_"))
|
||||||
os.MkdirAll(sanAlbumFolder, os.ModePerm)
|
os.MkdirAll(sanAlbumFolder, os.ModePerm)
|
||||||
fmt.Println(albumFolder)
|
fmt.Println(albumFolder)
|
||||||
|
|
||||||
// If cover-only mode is enabled, just download covers and animated artwork
|
|
||||||
if dl_cover {
|
|
||||||
fmt.Println("Cover only mode - downloading artwork")
|
|
||||||
counter.Total++
|
|
||||||
|
|
||||||
// Download album cover
|
|
||||||
err = writeCover(sanAlbumFolder, "cover", meta.Data[0].Attributes.Artwork.URL)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to write cover.")
|
|
||||||
counter.Error++
|
|
||||||
} else {
|
|
||||||
fmt.Println("Album cover downloaded successfully")
|
|
||||||
counter.Success++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Download artist cover if enabled
|
|
||||||
if Config.SaveArtistCover && !(strings.Contains(albumId, "pl.")) {
|
|
||||||
if len(meta.Data[0].Relationships.Artists.Data) > 0 {
|
|
||||||
err = writeCover(singerFolder, "folder", meta.Data[0].Relationships.Artists.Data[0].Attributes.Artwork.Url)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to write artist cover.")
|
|
||||||
counter.Error++
|
|
||||||
} else {
|
|
||||||
fmt.Println("Artist cover downloaded successfully")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Download animated artwork if available and enabled
|
|
||||||
if Config.SaveAnimatedArtwork && meta.Data[0].Attributes.EditorialVideo.MotionDetailSquare.Video != "" {
|
|
||||||
fmt.Println("Found Animation Artwork.")
|
|
||||||
|
|
||||||
// Download square version
|
|
||||||
motionvideoUrlSquare, err := extractVideo(meta.Data[0].Attributes.EditorialVideo.MotionDetailSquare.Video)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("No motion video square:", err)
|
|
||||||
} else {
|
|
||||||
exists, err := fileExists(filepath.Join(sanAlbumFolder, "animated_artwork_square.mp4"))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to check if animated artwork square exists.")
|
|
||||||
}
|
|
||||||
if exists {
|
|
||||||
fmt.Println("Animated artwork square already exists locally.")
|
|
||||||
} else {
|
|
||||||
fmt.Println("Animation Artwork Square Downloading...")
|
|
||||||
cmd := exec.Command("ffmpeg", "-loglevel", "quiet", "-y", "-i", motionvideoUrlSquare, "-c", "copy", filepath.Join(sanAlbumFolder, "animated_artwork_square.mp4"))
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
fmt.Printf("Animated artwork square download failed: %v\n", err)
|
|
||||||
} else {
|
|
||||||
fmt.Println("Animation Artwork Square Downloaded")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if Config.EmbyAnimatedArtwork {
|
|
||||||
// Convert square version to gif
|
|
||||||
cmd3 := exec.Command("ffmpeg", "-i", filepath.Join(sanAlbumFolder, "animated_artwork_square.mp4"), "-vf", "scale=440:-1", "-r", "24", "-f", "gif", filepath.Join(sanAlbumFolder, "folder.jpg"))
|
|
||||||
if err := cmd3.Run(); err != nil {
|
|
||||||
fmt.Printf("Animated artwork square to gif conversion failed: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Download tall version
|
|
||||||
motionvideoUrlTall, err := extractVideo(meta.Data[0].Attributes.EditorialVideo.MotionDetailTall.Video)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("No motion video tall:", err)
|
|
||||||
} else {
|
|
||||||
exists, err := fileExists(filepath.Join(sanAlbumFolder, "animated_artwork_tall.mp4"))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to check if animated artwork tall exists.")
|
|
||||||
}
|
|
||||||
if exists {
|
|
||||||
fmt.Println("Animated artwork tall already exists locally.")
|
|
||||||
} else {
|
|
||||||
fmt.Println("Animation Artwork Tall Downloading...")
|
|
||||||
cmd := exec.Command("ffmpeg", "-loglevel", "quiet", "-y", "-i", motionvideoUrlTall, "-c", "copy", filepath.Join(sanAlbumFolder, "animated_artwork_tall.mp4"))
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
fmt.Printf("Animated artwork tall download failed: %v\n", err)
|
|
||||||
} else {
|
|
||||||
fmt.Println("Animation Artwork Tall Downloaded")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//get artist cover
|
//get artist cover
|
||||||
if Config.SaveArtistCover && !(strings.Contains(albumId, "pl.")) {
|
if Config.SaveArtistCover && !(strings.Contains(albumId, "pl.")) {
|
||||||
if len(meta.Data[0].Relationships.Artists.Data) > 0 {
|
if len(meta.Data[0].Relationships.Artists.Data) > 0 {
|
||||||
@ -1082,7 +992,6 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
|
|||||||
downloadTrack(trackNum, trackTotal, meta, track, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec, &counter)
|
downloadTrack(trackNum, trackTotal, meta, track, albumId, token, storefront, mediaUserToken, sanAlbumFolder, Codec, &counter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1187,11 +1096,10 @@ func main() {
|
|||||||
pflag.BoolVar(&dl_song, "song", false, "Enable single song download mode")
|
pflag.BoolVar(&dl_song, "song", false, "Enable single song download mode")
|
||||||
pflag.BoolVar(&artist_select, "all-album", false, "Download all artist albums")
|
pflag.BoolVar(&artist_select, "all-album", false, "Download all artist albums")
|
||||||
pflag.BoolVar(&debug_mode, "debug", false, "Enable debug mode to show audio quality information")
|
pflag.BoolVar(&debug_mode, "debug", false, "Enable debug mode to show audio quality information")
|
||||||
pflag.BoolVar(&dl_cover, "cover", false, "Download only album covers and animated artwork")
|
|
||||||
alac_max = pflag.Int("alac-max", Config.AlacMax, "Specify the max quality for download alac")
|
alac_max = pflag.Int("alac-max", Config.AlacMax, "Specify the max quality for download alac")
|
||||||
atmos_max = pflag.Int("atmos-max", Config.AtmosMax, "Specify the max quality for download atmos")
|
atmos_max = pflag.Int("atmos-max", Config.AtmosMax, "Specify the max quality for download atmos")
|
||||||
aac_type = pflag.String("aac-type", Config.AacType, "Select AAC type: aac, aac-binaural, aac-downmix")
|
aac_type = pflag.String("aac-type", Config.AacType, "Select AAC type, aac aac-binaural aac-downmix")
|
||||||
mv_audio_type = pflag.String("mv-audio-type", Config.MVAudioType, "Select MV audio type: atmos, ac3, aac")
|
mv_audio_type = pflag.String("mv-audio-type", Config.MVAudioType, "Select MV audio type, atmos ac3 aac")
|
||||||
mv_max = pflag.Int("mv-max", Config.MVMax, "Specify the max quality for download MV")
|
mv_max = pflag.Int("mv-max", Config.MVMax, "Specify the max quality for download MV")
|
||||||
|
|
||||||
// Custom usage message for help
|
// Custom usage message for help
|
||||||
@ -1235,7 +1143,7 @@ func main() {
|
|||||||
mvArgs, err := checkArtist(os.Args[0], token, "music-videos")
|
mvArgs, err := checkArtist(os.Args[0], token, "music-videos")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to get artist music-videos.")
|
fmt.Println("Failed to get artist music-videos.")
|
||||||
return
|
//return
|
||||||
}
|
}
|
||||||
os.Args = append(albumArgs, mvArgs...)
|
os.Args = append(albumArgs, mvArgs...)
|
||||||
}
|
}
|
||||||
@ -1733,29 +1641,41 @@ func checkM3u8(b string, f string) (string, error) {
|
|||||||
return EnhancedHls, nil
|
return EnhancedHls, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractMediaQuality(b string) (string, error) {
|
func formatAvailability(available bool, quality string) string {
|
||||||
|
if !available {
|
||||||
|
return "Not Available"
|
||||||
|
}
|
||||||
|
return quality
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractMedia(b string, more_mode bool) (string, string, error) {
|
||||||
|
masterUrl, err := url.Parse(b)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
resp, err := http.Get(b)
|
resp, err := http.Get(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", "",err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return "", errors.New(resp.Status)
|
return "", "", errors.New(resp.Status)
|
||||||
}
|
}
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
masterString := string(body)
|
masterString := string(body)
|
||||||
from, listType, err := m3u8.DecodeFrom(strings.NewReader(masterString), true)
|
from, listType, err := m3u8.DecodeFrom(strings.NewReader(masterString), true)
|
||||||
if err != nil || listType != m3u8.MASTER {
|
if err != nil || listType != m3u8.MASTER {
|
||||||
return "", errors.New("m3u8 not of master type")
|
return "", "", errors.New("m3u8 not of master type")
|
||||||
}
|
}
|
||||||
master := from.(*m3u8.MasterPlaylist)
|
master := from.(*m3u8.MasterPlaylist)
|
||||||
|
var streamUrl *url.URL
|
||||||
sort.Slice(master.Variants, func(i, j int) bool {
|
sort.Slice(master.Variants, func(i, j int) bool {
|
||||||
return master.Variants[i].AverageBandwidth > master.Variants[j].AverageBandwidth
|
return master.Variants[i].AverageBandwidth > master.Variants[j].AverageBandwidth
|
||||||
})
|
})
|
||||||
if debug_mode {
|
if debug_mode && more_mode {
|
||||||
fmt.Println("\nDebug: All Available Variants:")
|
fmt.Println("\nDebug: All Available Variants:")
|
||||||
fmt.Println("-----------------------------")
|
fmt.Println("-----------------------------")
|
||||||
for _, variant := range master.Variants {
|
for _, variant := range master.Variants {
|
||||||
@ -1836,90 +1756,13 @@ func extractMediaQuality(b string) (string, error) {
|
|||||||
fmt.Printf("Dolby Audio : %s\n", formatAvailability(hasDolbyAudio, dolbyAudioQuality))
|
fmt.Printf("Dolby Audio : %s\n", formatAvailability(hasDolbyAudio, dolbyAudioQuality))
|
||||||
fmt.Println("------------------------")
|
fmt.Println("------------------------")
|
||||||
|
|
||||||
return "", nil
|
return "", "", nil
|
||||||
}
|
}
|
||||||
var Quality string
|
var Quality string
|
||||||
for _, variant := range master.Variants {
|
for _, variant := range master.Variants {
|
||||||
if dl_atmos {
|
if dl_atmos {
|
||||||
if variant.Codecs == "ec-3" && strings.Contains(variant.Audio, "atmos") {
|
if variant.Codecs == "ec-3" && strings.Contains(variant.Audio, "atmos") {
|
||||||
split := strings.Split(variant.Audio, "-")
|
if debug_mode && !more_mode {
|
||||||
if len(split) > 0 {
|
|
||||||
Quality = fmt.Sprintf("%s kbps", split[len(split)-1])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if variant.Codecs == "ac-3" { // Add Dolby Audio support for --atmos flag
|
|
||||||
split := strings.Split(variant.Audio, "-")
|
|
||||||
if len(split) > 0 {
|
|
||||||
Quality = fmt.Sprintf("%s kbps", split[len(split)-1])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if dl_aac {
|
|
||||||
if variant.Codecs == "mp4a.40.2" {
|
|
||||||
split := strings.Split(variant.Audio, "-")
|
|
||||||
if len(split) >= 3 {
|
|
||||||
Quality = fmt.Sprintf("%s kbps", split[2])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if variant.Codecs == "alac" {
|
|
||||||
split := strings.Split(variant.Audio, "-")
|
|
||||||
if len(split) >= 3 {
|
|
||||||
bitDepth := split[len(split)-1]
|
|
||||||
sampleRate := split[len(split)-2]
|
|
||||||
HZ, err := strconv.Atoi(sampleRate)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
KHZ := float64(HZ) / 1000.0
|
|
||||||
Quality = fmt.Sprintf("%sB-%.1fkHz", bitDepth, KHZ)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Quality, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatAvailability(available bool, quality string) string {
|
|
||||||
if !available {
|
|
||||||
return "Not Available"
|
|
||||||
}
|
|
||||||
return quality
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractMedia(b string) (string, error) {
|
|
||||||
masterUrl, err := url.Parse(b)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
resp, err := http.Get(b)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return "", errors.New(resp.Status)
|
|
||||||
}
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
masterString := string(body)
|
|
||||||
from, listType, err := m3u8.DecodeFrom(strings.NewReader(masterString), true)
|
|
||||||
if err != nil || listType != m3u8.MASTER {
|
|
||||||
return "", errors.New("m3u8 not of master type")
|
|
||||||
}
|
|
||||||
master := from.(*m3u8.MasterPlaylist)
|
|
||||||
var streamUrl *url.URL
|
|
||||||
sort.Slice(master.Variants, func(i, j int) bool {
|
|
||||||
return master.Variants[i].AverageBandwidth > master.Variants[j].AverageBandwidth
|
|
||||||
})
|
|
||||||
for _, variant := range master.Variants {
|
|
||||||
if dl_atmos {
|
|
||||||
if variant.Codecs == "ec-3" && strings.Contains(variant.Audio, "atmos") {
|
|
||||||
if debug_mode {
|
|
||||||
fmt.Printf("Debug: Found Dolby Atmos variant - %s (Bitrate: %d kbps)\n",
|
fmt.Printf("Debug: Found Dolby Atmos variant - %s (Bitrate: %d kbps)\n",
|
||||||
variant.Audio, variant.Bandwidth/1000)
|
variant.Audio, variant.Bandwidth/1000)
|
||||||
}
|
}
|
||||||
@ -1927,40 +1770,43 @@ func extractMedia(b string) (string, error) {
|
|||||||
length := len(split)
|
length := len(split)
|
||||||
length_int, err := strconv.Atoi(split[length-1])
|
length_int, err := strconv.Atoi(split[length-1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
if length_int <= Config.AtmosMax {
|
if length_int <= Config.AtmosMax {
|
||||||
if !debug_mode {
|
if !debug_mode && !more_mode {
|
||||||
fmt.Printf("%s\n", variant.Audio)
|
fmt.Printf("%s\n", variant.Audio)
|
||||||
}
|
}
|
||||||
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
streamUrl = streamUrlTemp
|
streamUrl = streamUrlTemp
|
||||||
|
Quality = fmt.Sprintf("%s kbps", split[len(split)-1])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if variant.Codecs == "ac-3" { // Add Dolby Audio support
|
} else if variant.Codecs == "ac-3" { // Add Dolby Audio support
|
||||||
if debug_mode {
|
if debug_mode && !more_mode {
|
||||||
fmt.Printf("Debug: Found Dolby Audio variant - %s (Bitrate: %d kbps)\n",
|
fmt.Printf("Debug: Found Dolby Audio variant - %s (Bitrate: %d kbps)\n",
|
||||||
variant.Audio, variant.Bandwidth/1000)
|
variant.Audio, variant.Bandwidth/1000)
|
||||||
}
|
}
|
||||||
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
streamUrl = streamUrlTemp
|
streamUrl = streamUrlTemp
|
||||||
|
split := strings.Split(variant.Audio, "-")
|
||||||
|
Quality = fmt.Sprintf("%s kbps", split[len(split)-1])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if dl_aac {
|
} else if dl_aac {
|
||||||
if variant.Codecs == "mp4a.40.2" {
|
if variant.Codecs == "mp4a.40.2" {
|
||||||
if debug_mode {
|
if debug_mode && !more_mode {
|
||||||
fmt.Printf("Debug: Found AAC variant - %s (Bitrate: %d)\n", variant.Audio, variant.Bandwidth)
|
fmt.Printf("Debug: Found AAC variant - %s (Bitrate: %d)\n", variant.Audio, variant.Bandwidth)
|
||||||
}
|
}
|
||||||
aacregex := regexp.MustCompile(`audio-stereo-\d+`)
|
aacregex := regexp.MustCompile(`audio-stereo-\d+`)
|
||||||
replaced := aacregex.ReplaceAllString(variant.Audio, "aac")
|
replaced := aacregex.ReplaceAllString(variant.Audio, "aac")
|
||||||
if replaced == Config.AacType {
|
if replaced == Config.AacType {
|
||||||
if !debug_mode {
|
if !debug_mode && !more_mode {
|
||||||
fmt.Printf("%s\n", variant.Audio)
|
fmt.Printf("%s\n", variant.Audio)
|
||||||
}
|
}
|
||||||
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
||||||
@ -1968,6 +1814,8 @@ func extractMedia(b string) (string, error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
streamUrl = streamUrlTemp
|
streamUrl = streamUrlTemp
|
||||||
|
split := strings.Split(variant.Audio, "-")
|
||||||
|
Quality = fmt.Sprintf("%s kbps", split[2])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1977,10 +1825,10 @@ func extractMedia(b string) (string, error) {
|
|||||||
length := len(split)
|
length := len(split)
|
||||||
length_int, err := strconv.Atoi(split[length-2])
|
length_int, err := strconv.Atoi(split[length-2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
if length_int <= Config.AlacMax {
|
if length_int <= Config.AlacMax {
|
||||||
if !debug_mode {
|
if !debug_mode && !more_mode {
|
||||||
fmt.Printf("%s-bit / %s Hz\n", split[length-1], split[length-2])
|
fmt.Printf("%s-bit / %s Hz\n", split[length-1], split[length-2])
|
||||||
}
|
}
|
||||||
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
streamUrlTemp, err := masterUrl.Parse(variant.URI)
|
||||||
@ -1988,15 +1836,17 @@ func extractMedia(b string) (string, error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
streamUrl = streamUrlTemp
|
streamUrl = streamUrlTemp
|
||||||
|
KHZ := float64(length_int) / 1000.0
|
||||||
|
Quality = fmt.Sprintf("%sB-%.1fkHz", split[length-1], KHZ)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if streamUrl == nil {
|
if streamUrl == nil {
|
||||||
return "", errors.New("no codec found")
|
return "", "", errors.New("no codec found")
|
||||||
}
|
}
|
||||||
return streamUrl.String(), nil
|
return streamUrl.String(), Quality, nil
|
||||||
}
|
}
|
||||||
func extractVideo(c string) (string, error) {
|
func extractVideo(c string) (string, error) {
|
||||||
MediaUrl, err := url.Parse(c)
|
MediaUrl, err := url.Parse(c)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user