download.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package download
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "os"
  8. "os/exec"
  9. "regexp"
  10. "strings"
  11. "github.com/gocolly/colly"
  12. "github.com/joho/godotenv"
  13. )
  14. var ()
  15. const (
  16. HOST_URL = "https://www.bilibili.com"
  17. API_PREURL = "https://api.bilibili.com/x/web-interface/view?bvid="
  18. VID_PREURL = "https://www.bilibili.com/video/"
  19. )
  20. func MusicUrl(bv string) (url_list []string) {
  21. collector := colly.NewCollector()
  22. collector.OnResponse(func(r *colly.Response) {
  23. var (
  24. rtext string
  25. rtemp string
  26. rjson map[string]interface{}
  27. re *regexp.Regexp
  28. // url_list []string
  29. )
  30. rtext = string(r.Body)
  31. re, _ = regexp.Compile(`<script>window.__playinfo__=(.*?)</script>`)
  32. rtemp = re.FindAllString(rtext, 1)[0]
  33. re, _ = regexp.Compile(`<script>window.__playinfo__=|</script>`)
  34. rtemp = re.ReplaceAllString(rtemp, "")
  35. json.Unmarshal([]byte(rtemp), &rjson)
  36. 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)))
  37. 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)))
  38. for _, url := range rjson["data"].(map[string]interface{})["dash"].(map[string]interface{})["audio"].([]interface{})[0].(map[string]interface{})["backupUrl"].([]interface{}) {
  39. url_list = append(url_list, fmt.Sprintf("%v", url))
  40. }
  41. // fmt.Println(len(url_list))
  42. })
  43. collector.Visit(VID_PREURL + bv)
  44. return url_list
  45. }
  46. func MusicDownload(url_list []string, title string) bool {
  47. godotenv.Load()
  48. result := false
  49. title = strings.Replace(title, "/", "&", -1)
  50. title = strings.Replace(title, "\"", "'", -1)
  51. for _, url := range url_list {
  52. var (
  53. response *http.Response
  54. m4afile *os.File
  55. )
  56. var (
  57. err1 error
  58. err2 error
  59. err3 error
  60. )
  61. for i := 0; i < 3; i++ {
  62. req, _ := http.NewRequest("GET", url, nil)
  63. 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")
  64. req.Header.Set("Referer", HOST_URL)
  65. client := &http.Client{}
  66. response, err1 = client.Do(req)
  67. if err1 != nil {
  68. // fmt.Println("Get url error")
  69. continue
  70. }
  71. break
  72. }
  73. defer response.Body.Close()
  74. if _, direrr := os.Stat("temp/"); os.IsNotExist(direrr) {
  75. os.Mkdir("temp/", 0755)
  76. }
  77. if _, direrr := os.Stat("music/"); os.IsNotExist(direrr) {
  78. os.Mkdir("music/", 0755)
  79. }
  80. os.Chdir("temp/")
  81. m4afile, err2 = os.Create(title + ".m4a")
  82. // return true
  83. if err2 != nil {
  84. fmt.Println("Create file error")
  85. }
  86. defer m4afile.Close()
  87. _, err3 = io.Copy(m4afile, response.Body)
  88. if err3 != nil {
  89. fmt.Println("Copy file error")
  90. continue
  91. }
  92. fmt.Println(title)
  93. // cmd := exec.Command(`ffmpeg`, `-i`, "\""+title+".m4a"+"\"", `-vn`, `-ar`, `44100`, `-ac`, `2`, `-ab`, `192k`, `-f`, `mp3`, "\""+"../music"+title+".mp3"+"\"")
  94. cmd := exec.Command("bash", "../download/convert.sh", title, os.Getenv("DOWNLOAD_PATH"))
  95. err := cmd.Run()
  96. if err != nil {
  97. fmt.Println("Convert error")
  98. fmt.Println(err)
  99. os.Remove(title + ".m4a")
  100. break
  101. }
  102. os.Remove(title + ".m4a")
  103. result = true
  104. break
  105. }
  106. os.Chdir("../")
  107. return result
  108. }
  109. func MusicInfo(bv string) (info map[string]interface{}) {
  110. info = make(map[string]interface{})
  111. collector := colly.NewCollector()
  112. collector.OnResponse(func(r *colly.Response) {
  113. var (
  114. rtext string
  115. rjson map[string]interface{}
  116. )
  117. rtext = string(r.Body)
  118. json.Unmarshal([]byte(rtext), &rjson)
  119. // fmt.Println(rjson)
  120. page := int(rjson["data"].(map[string]interface{})["videos"].(float64))
  121. if page == 1 {
  122. info["isSingle"] = true
  123. info["videos"] = make(map[int]interface{})
  124. 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))}
  125. } else {
  126. info["isSingle"] = false
  127. info["videos"] = make(map[int]interface{})
  128. pages := rjson["data"].(map[string]interface{})["pages"].([]interface{})
  129. for page, videoInfo := range pages {
  130. 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))}
  131. }
  132. }
  133. })
  134. collector.Visit(API_PREURL + bv)
  135. return info
  136. }