diff --git a/Golang/.idea/.gitignore b/Golang/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/Golang/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/Golang/.idea/Golang.iml b/Golang/.idea/Golang.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/Golang/.idea/Golang.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Golang/.idea/misc.xml b/Golang/.idea/misc.xml
new file mode 100644
index 0000000..3ce3588
--- /dev/null
+++ b/Golang/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Golang/.idea/modules.xml b/Golang/.idea/modules.xml
new file mode 100644
index 0000000..153774d
--- /dev/null
+++ b/Golang/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Golang/.idea/vcs.xml b/Golang/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/Golang/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Golang/go.mod b/Golang/go.mod
index 80524ab..77249d7 100644
--- a/Golang/go.mod
+++ b/Golang/go.mod
@@ -2,13 +2,18 @@ module Golang
go 1.19
-require github.com/gin-gonic/gin v1.8.2
+require (
+ github.com/dop251/goja v0.0.0-20230203172422-5460598cfa32
+ github.com/gin-gonic/gin v1.8.2
+)
require (
+ github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.1 // indirect
+ github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
diff --git a/Golang/go.sum b/Golang/go.sum
index 7aee98d..9d13fb1 100644
--- a/Golang/go.sum
+++ b/Golang/go.sum
@@ -2,6 +2,14 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
+github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
+github.com/dop251/goja v0.0.0-20230203172422-5460598cfa32 h1:audXtK7nV3y4W9ckAxRBE+eQV5Bljf5Non4NTa9kLVE=
+github.com/dop251/goja v0.0.0-20230203172422-5460598cfa32/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs=
+github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
+github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.2 h1:UzKToD9/PoFj/V4rvlKqTRKnQYyz8Sc1MJlv4JHPtvY=
@@ -14,6 +22,8 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
diff --git a/Golang/liveurls/douyu.go b/Golang/liveurls/douyu.go
new file mode 100644
index 0000000..8e21547
--- /dev/null
+++ b/Golang/liveurls/douyu.go
@@ -0,0 +1,132 @@
+// Package liveurls
+// @Time:2023/02/05 06:36
+// @File:douyu.go
+// @SoftWare:Goland
+// @Author:feiyang
+// @Contact:TG@feiyangdigital
+
+package liveurls
+
+import (
+ "crypto/md5"
+ "encoding/json"
+ "fmt"
+ js "github.com/dop251/goja"
+ "io"
+ "net/http"
+ "regexp"
+ "strings"
+ "time"
+)
+
+type Douyu struct {
+ Rid string
+ Stream_type string
+ Cdn_type string
+}
+
+func md5V3(str string) string {
+ w := md5.New()
+ io.WriteString(w, str)
+ md5str := fmt.Sprintf("%x", w.Sum(nil))
+ return md5str
+}
+
+func (d *Douyu) GetRealUrl() any {
+ const did = "10000000000000000000000000001501"
+ var timestamp = time.Now().Unix()
+ liveurl := "https://m.douyu.com/" + d.Rid
+ client := &http.Client{}
+ r, _ := http.NewRequest("GET", liveurl, nil)
+ r.Header.Add("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ r.Header.Add("upgrade-insecure-requests", "1")
+ resp, _ := client.Do(r)
+ defer resp.Body.Close()
+ body, _ := io.ReadAll(resp.Body)
+ reg := regexp.MustCompile(`(?i)(function ub98484234.*)\s(var.*)`)
+ res := reg.FindStringSubmatch(string(body))
+ if res == nil {
+ return nil
+ }
+ nreg := regexp.MustCompile(`(?i)eval.*;}`)
+ strfn := nreg.ReplaceAllString(res[0], "strc;}")
+ vm := js.New()
+ _, err := vm.RunString(strfn)
+ if err != nil {
+ panic(err)
+ }
+ jsfn, ok := js.AssertFunction(vm.Get("ub98484234"))
+ if !ok {
+ panic("这不是一个函数")
+ }
+ result, nerr := jsfn(
+ js.Undefined(),
+ vm.ToValue("ub98484234"),
+ )
+ if nerr != nil {
+ panic(nerr)
+ }
+ nres := fmt.Sprintf("%s", result)
+ nnreg := regexp.MustCompile(`(?i)v=(\d+)`)
+ nnres := nnreg.FindStringSubmatch(nres)
+ unrb := fmt.Sprintf("%v%v%v%v", d.Rid, did, timestamp, nnres[1])
+ rb := md5V3(unrb)
+ nnnreg := regexp.MustCompile(`(?i)return rt;}\);?`)
+ strfn2 := nnnreg.ReplaceAllString(nres, "return rt;}")
+ strfn3 := strings.Replace(strfn2, `(function (`, `function sign(`, -1)
+ strfn4 := strings.Replace(strfn3, `CryptoJS.MD5(cb).toString()`, `"`+rb+`"`, -1)
+ vm2 := js.New()
+ _, nnerr := vm2.RunString(strfn4)
+ if nnerr != nil {
+ panic(nnerr)
+ }
+ jsfn2, nok := js.AssertFunction(vm2.Get("sign"))
+ if !nok {
+ panic("这不是一个函数")
+ }
+ result2, n3err := jsfn2(
+ js.Undefined(),
+ vm2.ToValue(d.Rid),
+ vm2.ToValue(did),
+ vm2.ToValue(timestamp),
+ )
+ if n3err != nil {
+ panic(n3err)
+ }
+ param := fmt.Sprintf("%s", result2)
+ realparam := param + "&ver=219032101&rid=" + d.Rid + "&rate=0"
+ r1, n4err := http.Post("https://m.douyu.com/api/room/ratestream", "application/x-www-form-urlencoded", strings.NewReader(realparam))
+ if n4err != nil {
+ panic(n4err)
+ }
+ defer r1.Body.Close()
+ body1, _ := io.ReadAll(r1.Body)
+ var s1 map[string]any
+ json.Unmarshal(body1, &s1)
+ var hls_url string
+ for k, v := range s1 {
+ if s1[k] == float64(7) {
+ return nil
+ }
+ if v, ok := v.(map[string]any); ok {
+ for k, v := range v {
+ if k == "url" {
+ if urlstr, ok := v.(string); ok {
+ hls_url = urlstr
+ }
+ }
+ }
+ }
+ }
+ n4reg := regexp.MustCompile(`(?i)(\d{1,8}[0-9a-zA-Z]+)_?\d{0,4}(.m3u8|/playlist)`)
+ houzhui := n4reg.FindStringSubmatch(hls_url)
+ var real_url string
+ flv_url := "http://" + d.Cdn_type + ".douyucdn.cn/live/" + houzhui[1] + ".flv?uuid="
+ switch d.Stream_type {
+ case "hls":
+ real_url = hls_url
+ case "flv":
+ real_url = flv_url
+ }
+ return real_url
+}
diff --git a/Golang/main.go b/Golang/main.go
index 281d914..d282f8a 100644
--- a/Golang/main.go
+++ b/Golang/main.go
@@ -49,6 +49,19 @@ func setupRouter(adurl string) *gin.Engine {
dyliveurl = adurl
}
c.Redirect(http.StatusMovedPermanently, dyliveurl)
+ case "douyu":
+ var douyuurl string
+ douyuobj := &liveurls.Douyu{}
+ douyuobj.Rid = rid
+ douyuobj.Stream_type = c.DefaultQuery("stream", "flv")
+ douyuobj.Cdn_type = c.DefaultQuery("cdn", "akm-tct")
+ douyuliveurl := douyuobj.GetRealUrl()
+ if str, ok := douyuliveurl.(string); ok {
+ douyuurl = str
+ } else {
+ douyuurl = adurl
+ }
+ c.Redirect(http.StatusMovedPermanently, douyuurl)
}
})
return r