go-common/app/service/live/third_api/bvc/playurl.go
2019-04-22 18:49:16 +08:00

144 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package bvc
import (
"context"
"fmt"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
"math"
"net/url"
"strconv"
)
const livePlayURLHost = "live-playurl.bilibili.co"
const livePlayURLAddr = "http://live-playurl.bilibili.co/room/v1/Room/playUrl"
const livePlayURLMultiAddr = "http://%s/stream/v1/multiplayurl"
type PlayUrlItem struct {
RoomId int64 `json:"room_id"`
CurrentQuality int64 `json:"current_quality"`
AcceptQuality []int64 `json:"accept_quality"`
Url map[string]string `json:"url"`
}
type respPlayUrl struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data []*PlayUrlItem `json:"data"`
}
// 历史原因,单个的接口和视频云@yuanfeng确认数据结构不统一后面统一暂时先不用
// @see http://live-hub.bilibili.co/doc/playurl/
func (c *Client) GetPlayUrl(ctx *bm.Context, cid, quality, ptype, needHttps, unicomFree int64, platform string) (resp *respPlayUrl) {
cli := bm.NewClient(c.getConf())
param := url.Values{}
param.Set("cid", strconv.FormatInt(cid, 10))
param.Set("quality", strconv.FormatInt(quality, 10))
param.Set("platform", platform)
param.Set("ptype", strconv.FormatInt(ptype, 10))
param.Set("https_url_req", strconv.FormatInt(needHttps, 10))
param.Set("unicom_free", strconv.FormatInt(unicomFree, 10))
err := cli.Get(ctx, livePlayURLAddr, "", param, &resp)
if err != nil {
log.Error("call %s error(%v)", livePlayURLAddr, err)
return
}
if resp.Code != ecode.OK.Code() {
log.Error("call %s response error, code(%d) message(%s)", livePlayURLAddr, resp.Code, resp.Msg)
return
}
return
}
// 批量接口一次最好20个
func (c *Client) GetPlayUrlMulti(ctx context.Context, roomIds []int64,
needHttps, quality, build int64, platform string) (result map[int64]*PlayUrlItem) {
cli := bm.NewClient(c.getConf())
result = make(map[int64]*PlayUrlItem)
userIp := metadata.String(ctx, metadata.RemoteIP)
if userIp == "127.0.0.1" || c.mock == "1" {
userIp = "222.73.196.18"
}
bvcHost := c.getBvcHost(livePlayURLHost)
if quality == 0 {
quality = 4
}
chunkSize := 20
lens := len(roomIds)
if lens <= 0 {
return
}
// 批次
chunkNum := int(math.Ceil(float64(lens) / float64(chunkSize)))
wg, _ := errgroup.WithContext(ctx)
// 空间换时间
chunkResult := make([][]*PlayUrlItem, chunkNum)
for i := 1; i <= chunkNum; i++ {
x := i
wg.Go(func() error {
param := url.Values{}
chunkRoomIds := make([]int64, 20)
if x == chunkNum {
chunkRoomIds = roomIds[(x-1)*chunkSize:]
} else {
chunkRoomIds = roomIds[(x-1)*chunkSize : x*chunkSize]
}
param.Set("room_ids", xstr.JoinInts(chunkRoomIds))
param.Set("platform", platform)
param.Set("https_url_req", strconv.FormatInt(needHttps, 10))
param.Set("quality", strconv.FormatInt(quality, 10))
param.Set("build", strconv.FormatInt(build, 10))
param.Set("req_biz", "live-app-interface")
var resp respPlayUrl
bvcUrl := fmt.Sprintf(livePlayURLMultiAddr, bvcHost)
req, err := cli.NewRequest("GET", bvcUrl, userIp, param)
if err != nil {
log.Error("GetPlayUrlMulti client.NewRequest: get error(%v)", err)
return nil
}
//req.Header.Add("x-backend-bili-real-ip", userIp)
if err := cli.Do(ctx, req, &resp); err != nil {
log.Error("GetPlayUrlMulti client.Do: get error(%v)", err)
return nil
}
if resp.Code != 0 {
log.Error("GetPlayUrlMulti call %s response error, code(%d) message(%s) param(%+v) room_ids(%+v)", bvcUrl, resp.Code, resp.Msg, param, chunkRoomIds)
return nil
}
if resp.Data == nil || len(resp.Data) <= 0 {
log.Warn("GetPlayUrlMulti call %s response empty, code(%d) message(%s) param(%+v) room_ids(%+v)", bvcUrl, resp.Code, resp.Msg, param, chunkRoomIds)
return nil
}
//chunkResult = append(chunkResult, resp.Data)
chunkResult[x-1] = resp.Data
return nil
})
}
if err := wg.Wait(); err != nil {
log.Error("GetPlayUrlMulti get playurl wait error(%+v)", err)
return nil
}
// 整理数据
for _, chunkItemList := range chunkResult {
for _, item := range chunkItemList {
if item != nil {
result[item.RoomId] = item
}
}
}
return
}