Hevc and quality options (#428)

* 默认获取B站原画PRO的直播源(如果有)

* 录制hevc直播源

* 增加画质选项

* 增加画质选项

* 默认画质为0

* 还原

* flag默认画质为0

* 删除了获取直播源v1版本

* 格式

* 还原

* 删除ffmpeg指定格式的参数

* 删除了liveApiUrl

* 格式

* 格式
This commit is contained in:
dlxqfmx99 authored and GitHub committed 2023-03-25 17:18:53 +09:00
1 parent 64699e6444
commit 32a0aecafe
7 files changed
+47 -13

No files matched your search

+7
View File
@@ -11,8 +11,15 @@ log:
feature:
use_native_flv_parser: false
live_rooms:
# qulity参数目前仅B站启用,默认为0
# (B站)0代表原画PRO(HEVC)优先, 其他数值为原画(AVC)
# 原画PRO会保存为.ts文件, 原画为.flv
# HEVC相比AVC体积更小, 减少35%体积, 画质相当, 但是B站转码有时候会崩
- url: https://www.lang.live/room/5664344
is_listening: false
- url: https://live.bilibili.com/22603245
is_listening: true
quality: 0
out_put_tmpl: ""
video_split_strategies:
on_room_name_changed: false
+1
View File
@@ -108,6 +108,7 @@ func main() {
if v, ok := inst.Config.Cookies[u.Host]; ok {
opts = append(opts, live.WithKVStringCookies(u, v))
}
opts = append(opts, live.WithQuality(room.Quality))
l, err := live.New(u, inst.Cache, opts...)
if err != nil {
logger.WithField("url", room).Error(err.Error())
+2
View File
@@ -83,6 +83,7 @@ type LiveRoom struct {
Url string `yaml:"url"`
IsListening bool `yaml:"is_listening"`
LiveId live.ID `yaml:"-"`
Quality int `yaml:"quality"`
}
type liveRoomAlias LiveRoom
@@ -112,6 +113,7 @@ func NewLiveRoomsWithStrings(strings []string) []LiveRoom {
for index, url := range strings {
liveRooms[index].Url = url
liveRooms[index].IsListening = true
liveRooms[index].Quality = 0
}
return liveRooms
}
+23 -11
View File
@@ -1,6 +1,7 @@
package bilibili
import (
"fmt"
"net/http"
"net/url"
"strings"
@@ -17,10 +18,10 @@ 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"
liveApiUrl = "https://api.live.bilibili.com/room/v1/Room/playUrl"
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"
)
func init() {
@@ -134,11 +135,9 @@ func (l *Live) GetStreamUrls() (us []*url.URL, err error) {
for _, item := range cookies {
cookieKVs[item.Name] = item.Value
}
resp, err := requests.Get(liveApiUrl, live.CommonUserAgent, requests.Queries(map[string]string{
"cid": l.realID,
"quality": "4",
"platform": "web",
}), requests.Cookies(cookieKVs))
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))
if err != nil {
return nil, err
}
@@ -150,10 +149,23 @@ func (l *Live) GetStreamUrls() (us []*url.URL, err error) {
return nil, err
}
urls := make([]string, 0, 4)
gjson.GetBytes(body, "data.durl.#.url").ForEach(func(_, value gjson.Result) bool {
urls = append(urls, value.String())
addr := ""
if l.Options.Quality == 0 && gjson.GetBytes(body, "data.playurl_info.playurl.stream.1.format.1.codec.#").Int() > 1 {
addr = "data.playurl_info.playurl.stream.1.format.1.codec.1" // hevc m3u8
} else {
addr = "data.playurl_info.playurl.stream.0.format.0.codec.0" // avc flv
}
baseURL := gjson.GetBytes(body, addr+".base_url").String()
gjson.GetBytes(body, addr+".url_info").ForEach(func(_, value gjson.Result) bool {
hosts := gjson.Get(value.String(), "host").String()
queries := gjson.Get(value.String(), "extra").String()
urls = append(urls, hosts+baseURL+queries)
return true
})
return utils.GenUrls(urls...)
}
+8 -1
View File
@@ -31,6 +31,7 @@ type Builder interface {
type Options struct {
Cookies *cookiejar.Jar
Quality int
}
func NewOptions(opts ...Option) (*Options, error) {
@@ -38,7 +39,7 @@ func NewOptions(opts ...Option) (*Options, error) {
if err != nil {
return nil, err
}
options := &Options{Cookies: cookieJar}
options := &Options{Cookies: cookieJar, Quality: 0}
for _, opt := range opts {
opt(options)
}
@@ -72,6 +73,12 @@ func WithKVStringCookies(u *url.URL, cookies string) Option {
}
}
func WithQuality(quality int) Option {
return func(opts *Options) {
opts.Quality = quality
}
}
type ID string
type Live interface {
-1
View File
@@ -138,7 +138,6 @@ func (p *Parser) ParseLiveStream(ctx context.Context, url *url.URL, live live.Li
"-i", url.String(),
"-c", "copy",
"-bsf:a", "aac_adtstoasc",
"-f", "flv",
file,
)
if p.cmdStdIn, err = p.cmd.StdinPipe(); err != nil {
+6
View File
@@ -120,6 +120,7 @@ func (r *recorder) tryRecord(ctx context.Context) {
tmpl = _tmpl
}
}
buf := new(bytes.Buffer)
if err = tmpl.Execute(buf, info); err != nil {
panic(fmt.Sprintf("failed to render filename, err: %v", err))
@@ -127,6 +128,11 @@ func (r *recorder) tryRecord(ctx context.Context) {
fileName := filepath.Join(r.OutPutPath, buf.String())
outputPath, _ := filepath.Split(fileName)
url := urls[0]
if strings.Contains(url.Path, "m3u8") {
fileName = fileName[:len(fileName)-4]+".ts"
}
if err = mkdir(outputPath); err != nil {
r.getLogger().WithError(err).Errorf("failed to create output path[%s]", outputPath)
return