From 45406567af72f9b993f3420aefe5031900a36089 Mon Sep 17 00:00:00 2001 From: ankikong Date: Thu, 5 Mar 2020 20:53:03 +0800 Subject: [PATCH] add bilibili --- provider/bilibili/videoapi.go | 78 ++++++++++++++++++++++++++++-- provider/bilibili/videoapi_test.go | 13 ++++- 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/provider/bilibili/videoapi.go b/provider/bilibili/videoapi.go index b1c10e1..5605631 100644 --- a/provider/bilibili/videoapi.go +++ b/provider/bilibili/videoapi.go @@ -1,8 +1,13 @@ package bilibili import ( + "bufio" + "encoding/json" "fmt" + "os" + "regexp" "sort" + "strconv" "strings" "github.com/ankikong/goMusic/tool" @@ -15,7 +20,17 @@ const ( params = "otype=json&qn=80&quality=80&type=&platform=flash&cid=%s&appkey=%s" ) -type pages struct { +// Pages 记录一个av下有分p的信息 +type Pages struct { + CID int64 `json:"cid"` + Page int32 `json:"page"` + Name string `json:"part"` +} +type cidRes struct { + Code int `json:"code"` + Data struct { + Pgs []Pages `json:"pages"` + } `json:"data"` } func getSign(param string) string { @@ -27,15 +42,70 @@ func getSign(param string) string { return param + "&sign=" + tool.MD5(param+secretKey) } +type durl struct { + URL string `json:"url"` + Size float64 `json:"size"` +} +type bilibiliRet struct { + Format string `json:"format"` + URLs []durl `json:"durl"` +} + // GetVideoURL 根据所给CID获取视频链接 func GetVideoURL(CID string) string { ps := fmt.Sprintf(params, CID, appkey) ps = getSign(ps) - return url + ps + rs, _ := tool.DoHTTP("GET", url+ps, "", "", "", "") + var data bilibiliRet + json.Unmarshal([]byte(rs), &data) + + return data.URLs[0].URL } // GetCID 根据aid获取视频所有分P的cid -func GetCID(aid string) string { +func GetCID(aid string) []Pages { url := "https://api.bilibili.com/x/web-interface/view?aid=" + aid - rs := tool.DoHTTP("GET", ) + rs, err := tool.DoHTTP("GET", url, "", "", "", "") + if err != nil { + panic("contact develop to fix(or retry):" + err.Error()) + } + var data cidRes + err = json.Unmarshal([]byte(rs), &data) + if err != nil { + panic("contact develop to fix(or retry):" + err.Error()) + } + if data.Code != 0 { + panic("contact develop to fix(or retry):" + err.Error()) + } + return data.Data.Pgs +} + +// Deal 处理链接并询问下载 +func Deal(url string) { + reg := regexp.MustCompile(`av(\d+)`) + aid := string(reg.Find([]byte(url))) + cid := GetCID(aid[2:]) + fmt.Printf("Get %d P video:\n", len(cid)) + for j, i := range cid { + fmt.Printf("\t%3d: %s\n", j, i.Name) + } + fmt.Println("which page to download?(-1 for all, use space to split cids, none to quit):") + reader := bufio.NewReader(os.Stdin) + inbuf, _ := reader.ReadBytes([]byte("\n")[0]) + in := string(inbuf) + in = strings.TrimSpace(in) + cids := strings.Split(in, " ") + if len(cids) == 0 { + return + } + fmt.Println(cids) + for _, i := range cids { + if ind, err := strconv.Atoi(i); err == nil && ind < len(cid) { + url := GetVideoURL(fmt.Sprint(cid[ind].CID)) + fmt.Println(url) + tool.Download(url, fmt.Sprintf("%s-%d.%s", aid, ind, "flv"), "") + } else { + fmt.Printf("error input, no a digit: \"%s\", skip", i) + } + } } diff --git a/provider/bilibili/videoapi_test.go b/provider/bilibili/videoapi_test.go index ce9fa68..00fd4fb 100644 --- a/provider/bilibili/videoapi_test.go +++ b/provider/bilibili/videoapi_test.go @@ -4,12 +4,21 @@ import "testing" func TestGetURL(t *testing.T) { var ( - input = "135463335" + input = "135463335" output = "https://interface.bilibili.com/v2/playurl?appkey=iVGUTjsxvpLeuDCf" + - "&cid=135463335&otype=json&platform=flash&qn=80&quality=80&type=&sign=2b90191093ff9712e448b54ee0749007" + "&cid=135463335&otype=json&platform=flash&qn=80&quality=80&type=&sign=2b90191093ff9712e448b54ee0749007" ) url := GetVideoURL(input) if url != output { t.Error("GetURL error", url, output) } } + +func TestGetCID(t *testing.T) { + rs := GetCID("58417317") + t.Error(rs) +} + +func TestDeal(t *testing.T) { + Deal("https://www.bilibili.com/video/av93895674") +} \ No newline at end of file