123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- 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(`<script>window.__playinfo__=(.*?)</script>`)
- rtemp = re.FindAllString(rtext, 1)[0]
- re, _ = regexp.Compile(`<script>window.__playinfo__=|</script>`)
- 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
- }
|