package download import ( "encoding/json" "fmt" "io" "net/http" "os" "os/exec" "regexp" "strings" "github.com/gocolly/colly" "github.com/joho/godotenv" ) var () const ( HOST_URL = "https://www.bilibili.com" API_PREURL = "https://api.bilibili.com/x/web-interface/view?bvid=" VID_PREURL = "https://www.bilibili.com/video/" ) func MusicUrl(bv string) (url_list []string) { collector := colly.NewCollector() collector.OnResponse(func(r *colly.Response) { var ( rtext string rtemp string rjson map[string]interface{} re *regexp.Regexp // url_list []string ) rtext = string(r.Body) re, _ = regexp.Compile(``) rtemp = re.FindAllString(rtext, 1)[0] re, _ = regexp.Compile(``) rtemp = re.ReplaceAllString(rtemp, "") json.Unmarshal([]byte(rtemp), &rjson) url_list = append(url_list, fmt.Sprintf("%v", rjson["data"].(map[string]interface{})["dash"].(map[string]interface{})["audio"].([]interface{})[0].(map[string]interface{})["baseUrl"].(string))) url_list = append(url_list, fmt.Sprintf("%v", rjson["data"].(map[string]interface{})["dash"].(map[string]interface{})["audio"].([]interface{})[0].(map[string]interface{})["base_url"].(string))) for _, url := range rjson["data"].(map[string]interface{})["dash"].(map[string]interface{})["audio"].([]interface{})[0].(map[string]interface{})["backupUrl"].([]interface{}) { url_list = append(url_list, fmt.Sprintf("%v", url)) } // fmt.Println(len(url_list)) }) collector.Visit(VID_PREURL + bv) return url_list } func MusicDownload(url_list []string, title string) bool { godotenv.Load() result := false title = strings.Replace(title, "/", "&", -1) title = strings.Replace(title, "\"", "'", -1) for _, url := range url_list { var ( response *http.Response m4afile *os.File ) var ( err1 error err2 error err3 error ) for i := 0; i < 3; i++ { req, _ := http.NewRequest("GET", url, nil) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3") req.Header.Set("Referer", HOST_URL) client := &http.Client{} response, err1 = client.Do(req) if err1 != nil { // fmt.Println("Get url error") continue } break } defer response.Body.Close() if _, direrr := os.Stat("temp/"); os.IsNotExist(direrr) { os.Mkdir("temp/", 0755) } if _, direrr := os.Stat("music/"); os.IsNotExist(direrr) { os.Mkdir("music/", 0755) } os.Chdir("temp/") m4afile, err2 = os.Create(title + ".m4a") // return true if err2 != nil { fmt.Println("Create file error") } defer m4afile.Close() _, err3 = io.Copy(m4afile, response.Body) if err3 != nil { fmt.Println("Copy file error") continue } fmt.Println(title) // cmd := exec.Command(`ffmpeg`, `-i`, "\""+title+".m4a"+"\"", `-vn`, `-ar`, `44100`, `-ac`, `2`, `-ab`, `192k`, `-f`, `mp3`, "\""+"../music"+title+".mp3"+"\"") cmd := exec.Command("bash", "../download/convert.sh", title, os.Getenv("DOWNLOAD_PATH")) err := cmd.Run() if err != nil { fmt.Println("Convert error") fmt.Println(err) os.Remove(title + ".m4a") break } os.Remove(title + ".m4a") result = true break } os.Chdir("../") return result } func MusicInfo(bv string) (info map[string]interface{}) { info = make(map[string]interface{}) collector := colly.NewCollector() collector.OnResponse(func(r *colly.Response) { var ( rtext string rjson map[string]interface{} ) rtext = string(r.Body) json.Unmarshal([]byte(rtext), &rjson) // fmt.Println(rjson) page := int(rjson["data"].(map[string]interface{})["videos"].(float64)) if page == 1 { info["isSingle"] = true info["videos"] = make(map[int]interface{}) info["videos"].(map[int]interface{})[1] = map[string]interface{}{"title": rjson["data"].(map[string]interface{})["title"].(string), "cover": rjson["data"].(map[string]interface{})["pic"].(string), "duration": int(rjson["data"].(map[string]interface{})["duration"].(float64))} } else { info["isSingle"] = false info["videos"] = make(map[int]interface{}) pages := rjson["data"].(map[string]interface{})["pages"].([]interface{}) for page, videoInfo := range pages { info["videos"].(map[int]interface{})[page+1] = map[string]interface{}{"title": videoInfo.(map[string]interface{})["part"].(string), "cover": rjson["data"].(map[string]interface{})["pic"].(string), "duration": int(videoInfo.(map[string]interface{})["duration"].(float64))} } } }) collector.Visit(API_PREURL + bv) return info }