更新虎牙

pull/37/head
肥羊 3 years ago
parent 99ddb67453
commit 4bbecd392e
  1. 17
      Golang/README.md
  2. 188
      Golang/liveurls/huya.go
  3. 11
      Golang/main.go

@ -60,9 +60,22 @@ http://你的IP:35455/douyu/xxxxx(?stream=flv&cdn=hw-tct)
```
http://你的IP:35455/bilibili/xxxxxx(?platform=h5&line=first&quality=10000)
```
## **虎牙`(huya.com/)xxxxxx`:**
## **虎牙`(huya.com/)xxxxxx`:**
### 1,查看可用CDN:
```
http://你的IP:35455/huya/xxxxx
http://你的IP:35455/huya/xxxxx?type=display
```
### 2,切换媒体类型(默认flv,可选flv、hls):
```
http://你的IP:35455/huya/xxxxx?media=hls
```
### 3,切换CDN(默认hwcdn,可选hycdn、alicdn、txcdn、hwcdn、hscdn、wscdn,具体可先访问1获取):
```
http://你的IP:35455/huya/xxxxx?cdn=alicdn
```
### 4,最后的代理链接示例:
```
http://你的IP:35455/huya/xxxxx(?media=xxx&cdn=xxx)
```
## **YouTube:**
```

@ -8,10 +8,14 @@
package liveurls
import (
"bytes"
"crypto/md5"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"math/rand"
"net/http"
"net/url"
"regexp"
@ -21,48 +25,118 @@ import (
)
type Huya struct {
Rid string
Rid string
Media string
Type string
Cdn string
}
func md5huya(str string) string {
w := md5.New()
io.WriteString(w, str)
md5str := fmt.Sprintf("%x", w.Sum(nil))
return md5str
type Data struct {
}
func format(realstr string) string {
i := strings.Split(realstr, "?")[0]
b := strings.Split(realstr, "?")[1]
r := strings.Split(i, "/")
reg := regexp.MustCompile(".(flv|m3u8)")
s := reg.ReplaceAllString(r[len(r)-1], "")
c := strings.SplitN(b, "&", 4)
cnil := c[:0]
n := make(map[string]string)
for _, v := range c {
if len(v) > 0 {
cnil = append(cnil, v)
narr := strings.Split(v, "=")
n[narr[0]] = narr[1]
type Payload struct {
AppId int `json:"appId"`
ByPass int `json:"byPass"`
Context string `json:"context"`
Version string `json:"version"`
Data Data `json:"data"`
}
type ResponseData struct {
Data struct {
Uid string `json:"uid"`
} `json:"data"`
}
func getContent(apiUrl string) ([]byte, error) {
payload := Payload{
AppId: 5002,
ByPass: 3,
Context: "",
Version: "2.4",
Data: Data{},
}
jsonPayload, err := json.Marshal(payload)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", apiUrl, bytes.NewBuffer(jsonPayload))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Content-Length", fmt.Sprintf("%d", len(jsonPayload)))
req.Header.Set("upgrade-insecure-requests", "1")
req.Header.Set("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
func getUid() string {
content, _ := getContent("https://udblgn.huya.com/web/anonymousLogin")
var responseData ResponseData
json.Unmarshal(content, &responseData)
uid := responseData.Data.Uid
return uid
}
var uid, _ = strconv.Atoi(getUid())
func getUUID() int64 {
now := time.Now().UnixNano() / int64(time.Millisecond)
randNum := rand.Intn(1000)
return ((now % 10000000000 * 1000) + int64(randNum)) % 4294967295
}
func processAntiCode(antiCode string, uid int, streamName string) string {
q, _ := url.ParseQuery(antiCode)
q.Set("ver", "1")
q.Set("sv", "2110211124")
seqId := strconv.Itoa(uid + int(time.Now().UnixNano()/int64(time.Millisecond)))
q.Set("seqid", seqId)
q.Set("uid", strconv.Itoa(uid))
q.Set("uuid", strconv.FormatInt(getUUID(), 10))
h := md5.New()
h.Write([]byte(seqId + "|" + q.Get("ctype") + "|" + q.Get("t")))
ss := hex.EncodeToString(h.Sum(nil))
fm, _ := base64.StdEncoding.DecodeString(q.Get("fm"))
q.Set("fm", strings.Replace(strings.Replace(strings.Replace(strings.Replace(string(fm), "$0", q.Get("uid"), -1), "$1", streamName, -1), "$2", ss, -1), "$3", q.Get("wsTime"), -1))
h.Reset()
h.Write([]byte(q.Get("fm")))
q.Set("wsSecret", hex.EncodeToString(h.Sum(nil)))
q.Del("fm")
if _, ok := q["txyp"]; ok {
q.Del("txyp")
}
return q.Encode()
}
func format(liveArr map[string]any, uid int) map[string]any {
streamInfo := map[string]any{"flv": make(map[string]string), "hls": make(map[string]string)}
cdnType := map[string]string{"HY": "hycdn", "AL": "alicdn", "TX": "txcdn", "HW": "hwcdn", "HS": "hscdn", "WS": "wscdn"}
for _, s := range liveArr["roomInfo"].(map[string]any)["tLiveInfo"].(map[string]any)["tLiveStreamInfo"].(map[string]any)["vStreamInfo"].(map[string]any)["value"].([]any) {
sMap := s.(map[string]any)
if sMap["sFlvUrl"] != nil {
streamInfo["flv"].(map[string]string)[cdnType[sMap["sCdnType"].(string)]] = sMap["sFlvUrl"].(string) + "/" + sMap["sStreamName"].(string) + "." + sMap["sFlvUrlSuffix"].(string) + "?" + processAntiCode(sMap["sFlvAntiCode"].(string), uid, sMap["sStreamName"].(string))
}
if sMap["sHlsUrl"] != nil {
streamInfo["hls"].(map[string]string)[cdnType[sMap["sCdnType"].(string)]] = sMap["sHlsUrl"].(string) + "/" + sMap["sStreamName"].(string) + "." + sMap["sHlsUrlSuffix"].(string) + "?" + processAntiCode(sMap["sHlsAntiCode"].(string), uid, sMap["sStreamName"].(string))
}
}
c = cnil
fm, _ := url.QueryUnescape(n["fm"])
ub64, _ := base64.StdEncoding.DecodeString(fm)
u := string(ub64)
p := strings.Split(u, "_")[0]
f := strconv.FormatInt(time.Now().UnixNano()/100, 10)
l := n["wsTime"]
t := "0"
h := p + "_" + t + "_" + s + "_" + f + "_" + l
m := md5huya(h)
y := c[len(c)-1]
url := fmt.Sprintf("%s?wsSecret=%s&wsTime=%s&u=%s&seqid=%s&%s", i, m, l, t, f, y)
return url
return streamInfo
}
func (h *Huya) GetLiveUrl() any {
var liveArr map[string]any
liveurl := "https://m.huya.com/" + h.Rid
client := &http.Client{}
r, _ := http.NewRequest("GET", liveurl, nil)
@ -72,18 +146,42 @@ func (h *Huya) GetLiveUrl() any {
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
str := string(body)
freg := regexp.MustCompile(`"(?i)liveLineUrl":"([\s\S]*?)",`)
freg := regexp.MustCompile(`(?i)<script> window.HNF_GLOBAL_INIT = (.*) </script>`)
res := freg.FindStringSubmatch(str)
if res == nil || res[1] == "" {
return nil
}
nstr, _ := base64.StdEncoding.DecodeString(res[1])
realstr := string(nstr)
if strings.Contains(realstr, "replay") {
return "https:" + realstr
} else {
liveurl := format(realstr)
realurl := strings.Replace(strings.Replace(strings.Replace(liveurl, "hls", "flv", -1), "m3u8", "flv", -1), "&ctype=tars_mobile", "", -1)
return "https:" + realurl
json.Unmarshal([]byte(res[1]), &liveArr)
var mediaurl any
if roomInfo, ok := liveArr["roomInfo"].(map[string]any); ok {
if liveStatus, ok := roomInfo["eLiveStatus"].(float64); ok && liveStatus == 2 {
realurl := format(liveArr, uid)
if h.Type == "display" {
return realurl
}
for k, v := range realurl {
switch k {
case h.Media:
if urlarr, ok := v.(map[string]string); ok {
for k, v := range urlarr {
switch k {
case h.Cdn:
mediaurl = v
}
}
}
}
}
} else if liveStatus, ok := roomInfo["eLiveStatus"].(float64); ok && liveStatus == 3 {
if roomProfile, ok := liveArr["roomProfile"].(map[string]any); ok {
if liveLineUrl, ok := roomProfile["liveLineUrl"].(string); ok {
decodedLiveLineUrl, _ := base64.StdEncoding.DecodeString(liveLineUrl)
mediaurl = "http:" + string(decodedLiveLineUrl)
}
}
} else {
mediaurl = nil
}
}
return mediaurl
}

@ -1,5 +1,5 @@
// Package Golang
// @Time:2023/02/03 02:29
// @Time:2023/02/03 02:28
// @File:main.go
// @SoftWare:Goland
// @Author:feiyang
@ -53,7 +53,14 @@ func setupRouter(adurl string) *gin.Engine {
case "huya":
huyaobj := &liveurls.Huya{}
huyaobj.Rid = rid
c.Redirect(http.StatusMovedPermanently, duanyan(adurl, huyaobj.GetLiveUrl()))
huyaobj.Cdn = c.DefaultQuery("cdn", "hwcdn")
huyaobj.Media = c.DefaultQuery("media", "flv")
huyaobj.Type = c.DefaultQuery("type", "nodisplay")
if huyaobj.Type == "display" {
c.JSON(200, huyaobj.GetLiveUrl())
} else {
c.Redirect(http.StatusMovedPermanently, duanyan(adurl, huyaobj.GetLiveUrl()))
}
case "bilibili":
biliobj := &liveurls.BiliBili{}
biliobj.Rid = rid

Loading…
Cancel
Save