Skip to content

Commit

Permalink
修复虎牙录制;给ffmpeg增加自定义header (#637)
Browse files Browse the repository at this point in the history
* 修复虎牙录制;给ffmpeg增加自定义header

* 查缺补漏
  • Loading branch information
kira1928 authored Dec 28, 2023
1 parent 981d95a commit f43ce30
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 23 deletions.
65 changes: 45 additions & 20 deletions src/live/huya/huya.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ import (

"github.com/hr3lxphr6j/requests"
uuid "github.com/satori/go.uuid"
"github.com/tidwall/gjson"

"github.com/hr3lxphr6j/bililive-go/src/live"
"github.com/hr3lxphr6j/bililive-go/src/live/internal"
"github.com/hr3lxphr6j/bililive-go/src/pkg/utils"
)

const (
domain = "www.huya.com"
cnName = "虎牙"
domain = "www.huya.com"
cnName = "虎牙"
userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1"
)

func init() {
Expand All @@ -39,6 +41,7 @@ func (b *builder) Build(url *url.URL, opt ...live.Option) (live.Live, error) {

type Live struct {
internal.BaseLive
lastCdnIndex int
}

func (l *Live) GetInfo() (info *live.Info, err error) {
Expand Down Expand Up @@ -104,20 +107,25 @@ func parseAntiCode(anticode string, uid int64, streamName string) (string, error
uuid, _ := uuid.NewV4()
qr.Set("uuid", uuid.String())
ss := GetMD5Hash(fmt.Sprintf("%s|%s|%s", qr.Get("seqid"), qr.Get("ctype"), qr.Get("t")))
wsTime := strconv.FormatInt(time.Now().Add(6*time.Hour).Unix(), 16)

decodeString, _ := base64.StdEncoding.DecodeString(qr.Get("fm"))
fm := string(decodeString)
fm = strings.ReplaceAll(fm, "$0", qr.Get("uid"))
fm = strings.ReplaceAll(fm, "$1", streamName)
fm = strings.ReplaceAll(fm, "$2", ss)
fm = strings.ReplaceAll(fm, "$3", qr.Get("wsTime"))
fm = strings.ReplaceAll(fm, "$3", wsTime)

qr.Set("wsSecret", GetMD5Hash(fm))
qr.Set("ratio", "0")
qr.Set("wsTime", wsTime)
return qr.Encode(), nil
}

func (l *Live) GetStreamUrls() (us []*url.URL, err error) {
resp, err := requests.Get(l.Url.String(), live.CommonUserAgent)
roomId := strings.Split(strings.Split(l.Url.Path, "/")[1], "?")[0]
mobileUrl := fmt.Sprintf("https://m.huya.com/%s", roomId)
resp, err := requests.Get(mobileUrl, requests.UserAgent(userAgent))
if err != nil {
return nil, err
}
Expand All @@ -129,16 +137,31 @@ func (l *Live) GetStreamUrls() (us []*url.URL, err error) {
return nil, err
}

// Decode stream part.
streamStr := utils.Match1(`(?m)stream: (.*?)$`, body)
liveInfoJson := gjson.Parse(strings.Split(strings.Split(body, `"tLiveInfo":`)[1], `,"_classname":"LiveRoom.LiveInfo"}`)[0] + "}")
if !liveInfoJson.Exists() {
return nil, fmt.Errorf("liveInfo not found")
}

streamInfoJsons := liveInfoJson.Get("tLiveStreamInfo.vStreamInfo.value").Array()
if len(streamInfoJsons) == 0 {
return nil, fmt.Errorf("streamInfoJsons not found")
}

index := l.lastCdnIndex + 1
if index >= len(streamInfoJsons) {
index = 0
}
l.lastCdnIndex = index
gameStreamInfo := streamInfoJsons[index]
// get streamName
sStreamName := gameStreamInfo.Get("sStreamName").String()
// get sFlvAntiCode
sFlvAntiCode := gameStreamInfo.Get("sFlvAntiCode").String()
// get sFlvUrl
sFlvUrl := gameStreamInfo.Get("sFlvUrl").String()
// get random uid
uid := rand.Int63n(99999999999) + 1400000000000

var (
sStreamName = utils.Match1(`"sStreamName":"([^"]*)"`, streamStr)
sFlvUrl = strings.ReplaceAll(utils.Match1(`"sFlvUrl":"([^"]*)"`, streamStr), `\/`, `/`)
sFlvAntiCode = utils.Match1(`"sFlvAntiCode":"([^"]*)"`, streamStr)
// iLineIndex = utils.Match1(`"iLineIndex":(\d*),`, streamStr)
uid = (time.Now().Unix()%1e7*1e6 + int64(1e3*rand.Float64())) % 4294967295
)
query, err := parseAntiCode(sFlvAntiCode, uid, sStreamName)
if err != nil {
return nil, err
Expand All @@ -147,16 +170,18 @@ func (l *Live) GetStreamUrls() (us []*url.URL, err error) {
if err != nil {
return nil, err
}
// value := url.Values{}
// value.Add("line", iLineIndex)
// value.Add("p2p", "0")
// value.Add("type", "web")
// value.Add("ver", "1805071653")
// value.Add("uid", fmt.Sprintf("%d", uid))
// u.RawQuery = fmt.Sprintf("%s&%s", value.Encode(), utils.UnescapeHTMLEntity(sFlvAntiCode))
return []*url.URL{u}, nil
}

func (l *Live) GetPlatformCNName() string {
return cnName
}

func (l *Live) GetHeadersForDownloader() map[string]string {
return map[string]string{
"User-Agent": userAgent,
"Accept": `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`,
"Accept-Encoding": `gzip, deflate`,
"Accept-Language": `zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3`,
}
}
4 changes: 4 additions & 0 deletions src/live/internal/base_live.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ func (a *BaseLive) GetLastStartTime() time.Time {
func (a *BaseLive) SetLastStartTime(time time.Time) {
a.LastStartTime = time
}

func (a *BaseLive) GetHeadersForDownloader() map[string]string {
return make(map[string]string)
}
1 change: 1 addition & 0 deletions src/live/lives.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ type Live interface {
GetPlatformCNName() string
GetLastStartTime() time.Time
SetLastStartTime(time.Time)
GetHeadersForDownloader() map[string]string
}

type WrappedLive struct {
Expand Down
14 changes: 14 additions & 0 deletions src/live/mock/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 23 additions & 3 deletions src/pkg/parser/ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,32 @@ func (p *Parser) ParseLiveStream(ctx context.Context, url *url.URL, live live.Li
if err != nil {
return err
}
headers := live.GetHeadersForDownloader()
ffUserAgent, exists := headers["User-Agent"]
if !exists {
ffUserAgent = userAgent
}
referer, exists := headers["Referer"]
if !exists {
referer = live.GetRawUrl()
}
args := []string{
"-nostats",
"-progress", "-",
"-y", "-re",
"-user_agent", userAgent,
"-referer", live.GetRawUrl(),
"-user_agent", ffUserAgent,
"-referer", referer,
"-rw_timeout", p.timeoutInUs,
"-i", url.String(),
"-c", "copy",
"-bsf:a", "aac_adtstoasc",
"-http_proxy", "http://localhost:8888",
}
for k, v := range headers {
if k == "User-Agent" || k == "Referer" {
continue
}
args = append(args, "-headers", k+": "+v)
}

inst := instance.GetInstance(ctx)
Expand All @@ -165,7 +181,11 @@ func (p *Parser) ParseLiveStream(ctx context.Context, url *url.URL, live live.Li
return err
}
go p.scheduler()
return p.cmd.Wait()
err = p.cmd.Wait()
if err != nil {
return err
}
return nil
}

func (p *Parser) Stop() error {
Expand Down

0 comments on commit f43ce30

Please sign in to comment.