From 0c5e2b61aae0cf5c28a274d8e1c276ce6ffd42e8 Mon Sep 17 00:00:00 2001 From: ashesofdream <53961395+ashesofdream@users.noreply.github.com> Date: Sun, 25 Feb 2024 18:25:26 +0800 Subject: [PATCH] support bilibili audio only record (#679) * support bilibili audio only record * recovery ffmpeg parameter fix 403 crash,and move bilibili parameter to bilibili.go --- src/cmd/bililive/bililive.go | 2 ++ src/configs/config.go | 1 + src/live/bilibili/bilibili.go | 61 +++++++++++++++++++++++++++++------ src/live/lives.go | 11 +++++-- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/cmd/bililive/bililive.go b/src/cmd/bililive/bililive.go index 0e5c25c6..08b01901 100644 --- a/src/cmd/bililive/bililive.go +++ b/src/cmd/bililive/bililive.go @@ -106,6 +106,8 @@ func main() { opts = append(opts, live.WithKVStringCookies(u, v)) } opts = append(opts, live.WithQuality(room.Quality)) + opts = append(opts, live.WithAudioOnly(room.AudioOnly)) + l, err := live.New(u, inst.Cache, opts...) if err != nil { logger.WithField("url", room).Error(err.Error()) diff --git a/src/configs/config.go b/src/configs/config.go index 7f7b8a51..ab493e3f 100644 --- a/src/configs/config.go +++ b/src/configs/config.go @@ -87,6 +87,7 @@ type LiveRoom struct { IsListening bool `yaml:"is_listening"` LiveId live.ID `yaml:"-"` Quality int `yaml:"quality"` + AudioOnly bool `yaml:"audio_only"` } type liveRoomAlias LiveRoom diff --git a/src/live/bilibili/bilibili.go b/src/live/bilibili/bilibili.go index 809d769c..22c50636 100644 --- a/src/live/bilibili/bilibili.go +++ b/src/live/bilibili/bilibili.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "net/url" + "strconv" "strings" "github.com/hr3lxphr6j/requests" @@ -18,10 +19,13 @@ const ( domain = "live.bilibili.com" cnName = "哔哩哔哩" - roomInitUrl = "https://api.live.bilibili.com/room/v1/Room/room_init" - roomApiUrl = "https://api.live.bilibili.com/room/v1/Room/get_info" - userApiUrl = "https://api.live.bilibili.com/live_user/v1/UserInfo/get_anchor_in_room" - liveApiUrlv2 = "https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo" + roomInitUrl = "https://api.live.bilibili.com/room/v1/Room/room_init" + roomApiUrl = "https://api.live.bilibili.com/room/v1/Room/get_info" + userApiUrl = "https://api.live.bilibili.com/live_user/v1/UserInfo/get_anchor_in_room" + liveApiUrlv2 = "https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo" + appLiveApiUrlv2 = "https://api.live.bilibili.com/xlive/app-room/v2/index/getRoomPlayInfo" + biliAppAgent = "Bilibili Freedoooooom/MarkII BiliDroid/5.49.0 os/android model/MuMu mobi_app/android build/5490400 channel/dw090 innerVer/5490400 osVer/6.0.1 network/2" + biliWebAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" ) func init() { @@ -100,9 +104,10 @@ func (l *Live) GetInfo() (info *live.Info, err error) { } info = &live.Info{ - Live: l, - RoomName: gjson.GetBytes(body, "data.title").String(), - Status: gjson.GetBytes(body, "data.live_status").Int() == 1, + Live: l, + RoomName: gjson.GetBytes(body, "data.title").String(), + Status: gjson.GetBytes(body, "data.live_status").Int() == 1, + AudioOnly: l.Options.AudioOnly, } resp, err = requests.Get(userApiUrl, live.CommonUserAgent, requests.Query("roomid", l.realID)) @@ -135,9 +140,33 @@ func (l *Live) GetStreamUrls() (us []*url.URL, err error) { for _, item := range cookies { cookieKVs[item.Name] = item.Value } + apiUrl := liveApiUrlv2 query := fmt.Sprintf("?room_id=%s&protocol=0,1&format=0,1,2&codec=0,1&qn=10000&platform=web&ptype=8&dolby=5&panorama=1", l.realID) - resp, err := requests.Get(liveApiUrlv2+query, live.CommonUserAgent, requests.Cookies(cookieKVs)) - + agent := live.CommonUserAgent + // for audio only use android api + if l.Options.AudioOnly { + params := map[string]string{"appkey": "iVGUTjsxvpLeuDCf", + "build": "6310200", + "codec": "0,1", + "device": "android", + "device_name": "ONEPLUS", + "dolby": "5", + "format": "0,2", + "only_audio": "1", + "platform": "android", + "protocol": "0,1", + "room_id": l.realID, + "qn": strconv.Itoa(l.Options.Quality), + } + values := url.Values{} + for key, value := range params { + values.Add(key, value) + } + query = "?" + values.Encode() + apiUrl = appLiveApiUrlv2 + agent = requests.UserAgent(biliAppAgent) + } + resp, err := requests.Get(apiUrl+query, agent, requests.Cookies(cookieKVs)) if err != nil { return nil, err } @@ -149,7 +178,6 @@ func (l *Live) GetStreamUrls() (us []*url.URL, err error) { return nil, err } urls := make([]string, 0, 4) - addr := "" if l.Options.Quality == 0 && gjson.GetBytes(body, "data.playurl_info.playurl.stream.1.format.1.codec.#").Int() > 1 { @@ -172,3 +200,16 @@ func (l *Live) GetStreamUrls() (us []*url.URL, err error) { func (l *Live) GetPlatformCNName() string { return cnName } + +func (l *Live) GetHeadersForDownloader() map[string]string { + agent := biliWebAgent + referer := l.GetRawUrl() + if l.Options.AudioOnly { + agent = biliAppAgent + referer = "" + } + return map[string]string{ + "User-Agent": agent, + "Referer": referer, + } +} diff --git a/src/live/lives.go b/src/live/lives.go index 385d189b..441b07a8 100755 --- a/src/live/lives.go +++ b/src/live/lives.go @@ -41,8 +41,9 @@ type InitializingFinishedParam struct { } type Options struct { - Cookies *cookiejar.Jar - Quality int + Cookies *cookiejar.Jar + Quality int + AudioOnly bool } func NewOptions(opts ...Option) (*Options, error) { @@ -90,6 +91,12 @@ func WithQuality(quality int) Option { } } +func WithAudioOnly(audioOnly bool) Option { + return func(opts *Options) { + opts.AudioOnly = audioOnly + } +} + type ID string type StreamUrlInfo struct {