Hevc and quality options (#428)
* 默认获取B站原画PRO的直播源(如果有) * 录制hevc直播源 * 增加画质选项 * 增加画质选项 * 默认画质为0 * 还原 * flag默认画质为0 * 删除了获取直播源v1版本 * 格式 * 还原 * 删除ffmpeg指定格式的参数 * 删除了liveApiUrl * 格式 * 格式
This commit is contained in:
1 parent
64699e6444
commit
32a0aecafe
7 files changed
+47
-13
No files matched your search
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user