This commit is contained in:
zhaarey 2025-02-14 11:30:05 +08:00
parent 42ca991329
commit ac937f8076
2 changed files with 85 additions and 77 deletions

44
main.go
View File

@ -22,16 +22,15 @@ import (
"time" "time"
"main/utils/runv2" "main/utils/runv2"
"main/utils/structs"
"main/utils/runv3" "main/utils/runv3"
"main/utils/structs"
"github.com/spf13/pflag"
"github.com/zhaarey/go-mp4tag"
"gopkg.in/yaml.v2"
"github.com/beevik/etree" "github.com/beevik/etree"
"github.com/grafov/m3u8" "github.com/grafov/m3u8"
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
"github.com/spf13/pflag"
"github.com/zhaarey/go-mp4tag"
"gopkg.in/yaml.v2"
) )
var ( var (
@ -228,7 +227,7 @@ func checkArtist(artistUrl string, token string, relationship string) ([]string,
table := tablewriter.NewWriter(os.Stdout) table := tablewriter.NewWriter(os.Stdout)
if relationship == "albums" { if relationship == "albums" {
table.SetHeader([]string{"", "Album Name", "Date", "Album ID"}) table.SetHeader([]string{"", "Album Name", "Date", "Album ID"})
}else if relationship == "music-videos" { } else if relationship == "music-videos" {
table.SetHeader([]string{"", "MV Name", "Date", "MV ID"}) table.SetHeader([]string{"", "MV Name", "Date", "MV ID"})
} }
//table.SetFooter([]string{"", "", "Total", "$146.93"}) //table.SetFooter([]string{"", "", "Total", "$146.93"})
@ -744,7 +743,7 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
} }
if needCheck { if needCheck {
fullM3u8Url, err := checkM3u8(track.ID, "song") fullM3u8Url, err := checkM3u8(track.ID, "song")
if err == nil && strings.HasSuffix(fullM3u8Url, ".m3u8"){ if err == nil && strings.HasSuffix(fullM3u8Url, ".m3u8") {
m3u8Url = fullM3u8Url m3u8Url = fullM3u8Url
} else { } else {
fmt.Println("Failed to get best quality m3u8 from device m3u8 port, will use m3u8 from Web API") fmt.Println("Failed to get best quality m3u8 from device m3u8 port, will use m3u8 from Web API")
@ -1001,7 +1000,7 @@ func rip(albumId string, token string, storefront string, mediaUserToken string,
//table.SetFooter([]string{"", "", "Footer", "Footer4"}) //table.SetFooter([]string{"", "", "Footer", "Footer4"})
table.SetRowLine(false) table.SetRowLine(false)
//table.SetAutoMergeCells(true) //table.SetAutoMergeCells(true)
table.SetCaption(meta.Data[0].Type == "albums", fmt.Sprintf("Storefront: %s, %d tracks missing", strings.ToUpper(storefront), meta.Data[0].Attributes.TrackCount -trackTotal)) table.SetCaption(meta.Data[0].Type == "albums", fmt.Sprintf("Storefront: %s, %d tracks missing", strings.ToUpper(storefront), meta.Data[0].Attributes.TrackCount-trackTotal))
table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor}, table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor},
tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor}, tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor},
tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor}, tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor},
@ -1369,6 +1368,9 @@ func mvDownloader(adamID string, saveDir string, token string, storefront string
} }
mvm3u8url, _, _ := runv3.GetWebplayback(adamID, token, mediaUserToken, true) mvm3u8url, _, _ := runv3.GetWebplayback(adamID, token, mediaUserToken, true)
if mvm3u8url == "" {
return errors.New("media-user-token may wrong or expired.")
}
os.MkdirAll(saveDir, os.ModePerm) os.MkdirAll(saveDir, os.ModePerm)
//video //video
@ -1428,17 +1430,6 @@ func mvDownloader(adamID string, saveDir string, token string, storefront string
//tags = append(tags, fmt.Sprintf("album_artist=%s", MVInfo.Data[0].Attributes.ArtistName)) //tags = append(tags, fmt.Sprintf("album_artist=%s", MVInfo.Data[0].Attributes.ArtistName))
tags = append(tags, fmt.Sprintf("performer=%s", MVInfo.Data[0].Attributes.ArtistName)) tags = append(tags, fmt.Sprintf("performer=%s", MVInfo.Data[0].Attributes.ArtistName))
} }
//mux and add tag
tagsString := strings.Join(tags, ":")
muxCmd := exec.Command("MP4Box", "-itags", tagsString, "-quiet", "-add", vidPath, "-add", audPath, "-keep-utc", "-new", mvOutPath)
fmt.Printf("MV Remuxing...")
if err := muxCmd.Run(); err != nil {
fmt.Printf("MV mux failed: %v\n", err)
return err
}
fmt.Printf("\rMV Remuxed. \n")
defer os.Remove(vidPath)
defer os.Remove(audPath)
// Extract and save thumbnail if enabled // Extract and save thumbnail if enabled
if Config.SaveThumbnailImage { if Config.SaveThumbnailImage {
@ -1455,9 +1446,22 @@ func mvDownloader(adamID string, saveDir string, token string, storefront string
fmt.Println("Failed to save MV thumbnail:", err) fmt.Println("Failed to save MV thumbnail:", err)
} else { } else {
fmt.Println("MV thumbnail saved successfully") fmt.Println("MV thumbnail saved successfully")
tags = append(tags, fmt.Sprintf("cover=%s/%s.%s", saveDir, baseThumbName, Config.CoverFormat))
} }
} }
//mux and add tag
tagsString := strings.Join(tags, ":")
muxCmd := exec.Command("MP4Box", "-itags", tagsString, "-quiet", "-add", vidPath, "-add", audPath, "-keep-utc", "-new", mvOutPath)
fmt.Printf("MV Remuxing...")
if err := muxCmd.Run(); err != nil {
fmt.Printf("MV mux failed: %v\n", err)
return err
}
fmt.Printf("\rMV Remuxed. \n")
defer os.Remove(vidPath)
defer os.Remove(audPath)
return nil return nil
} }
@ -1785,7 +1789,7 @@ func extractMedia(b string, more_mode bool) (string, string, error) {
} }
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 {

View File

@ -4,25 +4,29 @@ import (
"context" "context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"github.com/gospider007/requests" "github.com/gospider007/requests"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
//"log/slog" //"log/slog"
"os"
cdm "main/utils/runv3/cdm" cdm "main/utils/runv3/cdm"
key "main/utils/runv3/key" key "main/utils/runv3/key"
"os"
"bytes"
"errors"
"io"
"github.com/Eyevinn/mp4ff/mp4" "github.com/Eyevinn/mp4ff/mp4"
"bytes"
"io"
"errors"
//"io/ioutil" //"io/ioutil"
"net/http"
"encoding/json" "encoding/json"
"github.com/grafov/m3u8" "net/http"
"strings"
"github.com/schollz/progressbar/v3"
"os/exec" "os/exec"
"strings"
"github.com/grafov/m3u8"
"github.com/schollz/progressbar/v3"
) )
type PlaybackLicense struct { type PlaybackLicense struct {
@ -49,7 +53,7 @@ type PlaybackLicense struct {
// } // }
// logger := slog.New(slog.NewJSONHandler(os.Stdout, &opts)) // logger := slog.New(slog.NewJSONHandler(os.Stdout, &opts))
// slog.SetDefault(logger) // slog.SetDefault(logger)
//} // }
func getPSSH(contentId string, kidBase64 string) (string, error) { func getPSSH(contentId string, kidBase64 string) (string, error) {
kidBytes, err := base64.StdEncoding.DecodeString(kidBase64) kidBytes, err := base64.StdEncoding.DecodeString(kidBase64)
if err != nil { if err != nil {
@ -145,10 +149,10 @@ func GetWebplayback(adamId string, authtoken string, mutoken string, mvmode bool
fmt.Println("json err:", err) fmt.Println("json err:", err)
return "", "", err return "", "", err
} }
if len(obj.List) > 0 {
if mvmode { if mvmode {
return obj.List[0].HlsPlaylistUrl, "", nil return obj.List[0].HlsPlaylistUrl, "", nil
} }
if len(obj.List) > 0 {
// 遍历 Assets // 遍历 Assets
for i, _ := range obj.List[0].Assets { for i, _ := range obj.List[0].Assets {
if obj.List[0].Assets[i].Flavor == "28:ctrp256" { if obj.List[0].Assets[i].Flavor == "28:ctrp256" {
@ -163,6 +167,7 @@ func GetWebplayback(adamId string, authtoken string, mutoken string, mvmode bool
} }
return "", "", nil return "", "", nil
} }
type Songlist struct { type Songlist struct {
List []struct { List []struct {
Hlsurl string `json:"hls-key-cert-url"` Hlsurl string `json:"hls-key-cert-url"`
@ -170,8 +175,8 @@ type Songlist struct {
Assets []struct { Assets []struct {
Flavor string `json:"flavor"` Flavor string `json:"flavor"`
URL string `json:"URL"` URL string `json:"URL"`
}`json:"assets"` } `json:"assets"`
}`json:"songList"` } `json:"songList"`
Status int `json:"status"` Status int `json:"status"`
} }
@ -227,7 +232,7 @@ func extractKidBase64(b string, mvmode bool) (string, string, error) {
} }
return kidbase64, urlBuilder.String(), nil return kidbase64, urlBuilder.String(), nil
} }
func extsong(b string)(bytes.Buffer){ func extsong(b string) bytes.Buffer {
resp, err := http.Get(b) resp, err := http.Get(b)
if err != nil { if err != nil {
fmt.Printf("下载文件失败: %v\n", err) fmt.Printf("下载文件失败: %v\n", err)
@ -255,7 +260,7 @@ func extsong(b string)(bytes.Buffer){
io.Copy(io.MultiWriter(&buffer, bar), resp.Body) io.Copy(io.MultiWriter(&buffer, bar), resp.Body)
return buffer return buffer
} }
func Run(adamId string, trackpath string, authtoken string, mutoken string, mvmode bool)(string, error) { func Run(adamId string, trackpath string, authtoken string, mutoken string, mvmode bool) (string, error) {
var keystr string //for mv key var keystr string //for mv key
var fileurl string var fileurl string
var kidBase64 string var kidBase64 string
@ -330,7 +335,7 @@ func Run(adamId string, trackpath string, authtoken string, mutoken string, mvmo
return "", nil return "", nil
} }
func ExtMvData (keyAndUrls string, savePath string)(error) { func ExtMvData(keyAndUrls string, savePath string) error {
segments := strings.Split(keyAndUrls, ";") segments := strings.Split(keyAndUrls, ";")
key := segments[0] key := segments[0]
//fmt.Println(key) //fmt.Println(key)
@ -384,7 +389,6 @@ func ExtMvData (keyAndUrls string, savePath string)(error) {
return nil return nil
} }
// DecryptMP4 decrypts a fragmented MP4 file with keys from widevice license. Supports CENC and CBCS schemes. // DecryptMP4 decrypts a fragmented MP4 file with keys from widevice license. Supports CENC and CBCS schemes.
func DecryptMP4(r io.Reader, key []byte, w io.Writer) error { func DecryptMP4(r io.Reader, key []byte, w io.Writer) error {
// Initialization // Initialization