Optimize the plugin code of Douyu and Bilibili (#386)

* Optimize the plugin code of Douyu and Bilibili

* Fix some wrong

* Fix some wrong

* fix some wrong
This commit is contained in:
XuanRan_Nyan authored and GitHub committed 2023-03-19 02:48:47 +00:00
1 parent 8a7ee5fbfc
commit edd760cc46
6 files changed
+153 -188

No files matched your search

+2 -1
View File
@@ -7,7 +7,7 @@
*.part
backup
venv./
config.yaml
config*.yaml
!public/config.yaml
/configlog.ini
ds_update.log*
@@ -16,6 +16,7 @@ ds_update.log*
*.egg-info
dist/
build/
cover/
*.back
bili.cookie.json
+21 -4
View File
@@ -39,7 +39,7 @@ class DownloadBase:
'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',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:60.1) Gecko/20100101 Firefox/60.1'
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
self.default_output_args = [
@@ -68,7 +68,7 @@ class DownloadBase:
if self.downloader == 'stream-gears':
stream_gears_download(self.raw_stream_url, self.fake_headers, filename, config.get('segment_time'),
config.get('file_size'))
elif self.downloader == 'streamlink':
elif self.downloader == 'streamlink':
parsed_url = urlparse(self.raw_stream_url)
path = parsed_url.path
if '.flv' in path: #streamlink无法处理flv,所以回退到ffmpeg
@@ -77,7 +77,24 @@ class DownloadBase:
self.streamlink_download(fmtname)
else:
self.ffmpeg_download(fmtname)
def get_live_cover(self, uname, room_id, filename, timestamp, cover_url):
import requests
headers = self.fake_headers.copy()
response = requests.get(cover_url, headers=headers, timeout=5)
save_dir = f'cover/{uname}_{room_id}/'
local_time = time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime(timestamp))
if not os.path.exists(save_dir):
os.makedirs(save_dir)
cover_file_name = get_valid_filename(f'{filename}_{local_time}.png')
live_cover_path = f'{save_dir}{cover_file_name}'
if os.path.exists(live_cover_path):
return live_cover_path
else:
with open(live_cover_path, 'wb') as f:
f.write(response.content)
return live_cover_path
def streamlink_download(self, filename): #streamlink+ffmpeg混合下载模式,适用于下载hls流
streamlink_input_args = ['--stream-segment-threads', '5']
streamlink_cmd = ['streamlink', *streamlink_input_args, self.raw_stream_url, 'best', '-O']
@@ -93,7 +110,7 @@ class DownloadBase:
ffmpeg_proc = subprocess.Popen(ffmpeg_cmd, stdin=streamlink_proc.stdout, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
try:
with ffmpeg_proc.stdout as stdout:
for line in iter(stdout.readline, b''):
for line in iter(stdout.readline, b''):
decode_line = line.decode(errors='ignore')
print(decode_line, end='', file=sys.stderr)
logger.debug(decode_line.rstrip())
+75 -128
View File
@@ -1,5 +1,3 @@
import os
import random
import re
import time
import requests
@@ -15,135 +13,121 @@ from ..engine.download import DownloadBase
class Bilibili(DownloadBase):
def __init__(self, fname, url, suffix='flv'):
super().__init__(fname, url, suffix)
self.fake_headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64; rv:60.1) Gecko/20100101 Firefox/60.1'
self.fake_headers['Referer'] = 'https://live.bilibili.com'
if config.get('user', {}).get('bili_cookie'):
self.fake_headers['cookie'] = config.get('user', {}).get('bili_cookie')
self.customAPI_use_cookie = config.get('user', {}).get('customAPI_use_cookie')
self.bili_cdn_fallback = config.get('bili_cdn_fallback', True)
self.customAPI_use_cookie = config.get('user', {}).get('customAPI_use_cookie', False)
self.use_live_cover = config.get('use_live_cover', False)
self.bilibili_danmaku = config.get('bilibili_danmaku', False)
if config.get('user', {}).get('bili_cookie') is not None:
self.fake_headers['cookie'] = config.get('user', {}).get('bili_cookie')
def check_stream(self):
# 预读配置
params = {
'room_id': match1(self.url, r'/(\d+)'),
'protocol': '0,1',
'format': '0,1,2',
'codec': '0,1',
'protocol': '0,1',# 0: http_stream, 1: http_hls
'format': '0,1,2',# 0: flv, 1: ts, 2: fmp4
'codec': '0', # 0: avc, 1: hevc
'qn': '10000',
'platform': config.get('biliplatform', 'web'),
# 'ptype': '8',
'dolby': '5',
'panorama': '1'
}
protocol = config.get('bili_protocol', 'stream')
perf_cdn = config.get('bili_perfCDN')
force_source = config.get('bili_force_source')
force_ov05_ip = config.get('bili_force_ov05_ip')
force_cn01_domain = config.get('bili_force_cn01_domains')
bili_cdn_fallback = config.get('bili_cdn_fallback', True)
force_source = config.get('bili_force_source', False)
ov05_ip = config.get('bili_force_ov05_ip')
cn01_domains = config.get('bili_force_cn01_domains', '').split(",")
official_api_host = "https://api.live.bilibili.com"
with requests.Session() as s:
s.headers = self.fake_headers.copy()
# 获取直播状态与房间标题
info_by_room_url = f"{official_api_host}/xlive/web-room/v1/index/getInfoByRoom?room_id={params['room_id']}"
try:
room_info = s.get(info_by_room_url, timeout=5).json()
room_info = s.get(info_by_room_url, timeout=3).json()
except requests.exceptions.ConnectionError:
logger.error(f"在连接到 {info_by_room_url} 时出现错误")
return False
if room_info['code'] != 0 or room_info['data']['room_info']['live_status'] != 1:
logger.debug(room_info['message'])
return False
room_id = room_info['data']['room_info']['room_id']
cover_url = room_info['data']['room_info']['cover']
live_start_time = room_info['data']['room_info']['live_start_time']
uname = room_info['data']['anchor_info']['base_info']['uname']
room_title = room_info['data']['room_info']['title']
self.room_title = room_info['data']['room_info']['title']
if self.use_live_cover is True: # 获取直播封面并保存到cover目录下
try:
self.live_cover_path = get_live_cover(uname, room_id, room_title, live_start_time, cover_url)
self.live_cover_path = \
super().get_live_cover(uname, params['room_id'], self.room_title, live_start_time, cover_url)
except:
logger.error(f"获取直播封面失败")
params['room_id'] = room_info['data']['room_info']['room_id']
self.room_title = room_info['data']['room_info']['title']
custom_api = config.get('bili_liveapi') is not None
# 当 Cookie 存在,并且自定义APi使用Cookie开关关闭时,仅使用官方 Api
if config.get('user', {}).get('bili_cookie') and self.customAPI_use_cookie is not True:
if config.get('user', {}).get('bili_cookie') and self.customAPI_use_cookie:
custom_api = False
play_info = get_play_info(s, custom_api, official_api_host, params)
if play_info['code'] != 0:
logger.debug(play_info['message'])
if play_info['code'] != 0:
logger.debug(play_info['message'])
return False
streams = play_info['data']['playurl_info']['playurl']['stream']
stream = streams[1] if protocol.startswith('hls') else streams[0]
if protocol == "hls_fmp4":
if len(stream['format']) > 1:
stream_info = stream['format'][1]['codec'][0]
elif int(time.time()) - live_start_time <= 45: # 等待45s,如果还没有fmp4流就回退到flv流
return False
streams = play_info['data']['playurl_info']['playurl']['stream']
live_start_time = room_info['data']['room_info']['live_start_time']
if protocol == "stream":
stream = streams[0]
stream_info = stream['format'][0]['codec'][0]
elif protocol == "hls_ts" or protocol == "hls":
stream = streams[1]
stream_info = stream['format'][0]['codec'][0]
elif protocol == "hls_fmp4":
try:
stream = streams[1]
stream_info = stream['format'][1]['codec'][0]
logger.debug(f"获取到{uname}房间的fmp4流")
except:
now_timestamp = int(time.time())
if now_timestamp - live_start_time <= 45: # 等待45s,如果还没有fmp4流就回退到flv流
return False
else:
stream = streams[0]
stream_info = stream['format'][0]['codec'][0]
logger.debug(f"获取{uname}房间fmp4流失败,回退到flv流")
found_perf_cdn = False #优选CDN节点
for url_info in stream_info['url_info']:
if perf_cdn and perf_cdn in url_info['extra']:
found_perf_cdn = True
logger.debug(f"找到了perfCDN{url_info['extra']}")
break
if not found_perf_cdn: #没找到优选CDN就回到第一个节点
url_info['host'] = stream_info['url_info'][0]['host']
url_info['extra'] = stream_info['url_info'][0]['extra']
logger.debug(f"没找到perfCDN哦")
# 哔哩哔哩直播强制原画(仅限HLS_ts流的 cn-gotcha01 CDN). 并且仅当主播有二压的时候才自动去掉m3u8的_bluray前缀,避免stream-gears的疯狂分段bug
if force_source is True and "cn-gotcha01" in url_info['extra'] and "_bluray.m3u8" in stream_info['base_url']:
stream_info['base_url'] = re.sub(r'_bluray(?=.*m3u8)', "", stream_info['base_url'])
# 强制替换cn-gotcha01的节点为指定节点 注意:只有大陆ip才能获取到cn-gotcha01的节点。
if force_cn01_domain and "cn-gotcha01" in url_info['extra']:
i = 0
while i < 6: # 测试随机到的节点是否可用
random_choice = random.choice(force_cn01_domain.split(","))
i += 1
try: # 发起 GET 请求,并获取响应状态码
status_code = s.get(f"https://{random_choice}{stream_info['base_url']}{url_info['extra']}",
stream=True).status_code
if status_code == 200: # 如果响应状态码是 200,跳出循环
break
except requests.exceptions.ConnectionError: # 如果发生连接异常,继续下一次循环
logger.debug(f"随机到的域名 {random_choice} 无法访问,尝试重新发起随机。")
continue
else:
logger.error(f"强制替换hls流的cn-gotcha01的节点为指定节点失败啦")
return False
logger.debug(f"随机到的域名 {random_choice} 返回了 200 状态码。")
url_info['host'] = "https://" + random_choice
# 强制替换ov05 302redirect之后的真实地址为指定的域名或ip达到自选ov05节点的目的
if force_ov05_ip and "ov-gotcha05" in url_info['host']:
response = requests.get(url_info['host'] + stream_info['base_url'] + url_info['extra'])
self.raw_stream_url = re.sub(r"https://([a-z0-9]+)\.ourdvsss\.com", f"http://{force_ov05_ip}",
response.url)
logger.debug(f"将ov-gotcha05的节点ip替换为了{force_ov05_ip}")
self.raw_stream_url = url_info['host'] + stream_info['base_url'] + url_info['extra']
if self.bili_cdn_fallback is False:
return True
stream_info['url_info'].reverse()
# 检查直播流是否可用以倒叙尝试回退
for stream_url in stream_info['url_info']:
self.raw_stream_url = stream_url['host'] + stream_info['base_url'] + stream_url['extra']
if s.get(self.raw_stream_url, stream=True).status_code == 404:
continue
break
stream = streams[0]
logger.debug(f"获取{uname}房间fmp4流失败,回退到flv流")
stream_info = stream['format'][0]['codec'][0]
stream_url = {'base_url': stream_info['base_url']}
if perf_cdn is not None:
for url_info in stream_info['url_info']:
if perf_cdn in url_info['extra']:
stream_url['host'] = url_info['host']
stream_url['extra'] = url_info['extra']
logger.debug(f"找到了perfCDN{stream_url['host']}")
else:
stream_url['host'] = stream_info['url_info'][-1]['host']
stream_url['extra'] = stream_info['url_info'][-1]['extra']
if "cn-gotcha01" in stream_url['extra']:
# 强制替换cn-gotcha01的节点为指定节点 注意:只有大陆ip才能获取到cn-gotcha01的节点。
if cn01_domains[0] != '':
import random
i = len(cn01_domains)
while i: # 测试节点是否可用
i-=1
host = cn01_domains[i]
try:
if s.get(f"https://{host}{stream_url['base_url']}{stream_url['extra']}",
stream=True).status_code == 200: # 如果响应状态码是 200,跳出循环
break
except requests.exceptions.ConnectionError: # 如果发生连接异常,继续下一次循环
logger.debug(f"节点 {host} 无法访问,尝试下一个节点。")
continue
else:
logger.error(f"配置文件中的cn-gotcha01节点均不可用")
logger.debug(f"节点 {host} 可用,替换为该节点")
stream_url['host'] = "https://" + host
# 强制去除 hls_ts 的 _bluray 文件名
if force_source:
stream_url['base_url'] = re.sub(r'_bluray(?=\.m3u8)?', "", stream_url['base_url'], 1)
self.raw_stream_url = stream_url['host'] + stream_url['base_url'] + stream_url['extra']
# 强制替换ov05 302redirect之后的真实地址为指定的域名或ip达到自选ov05节点的目的
if ov05_ip and "ov-gotcha05" in stream_url['host']:
r = s.get(self.raw_stream_url, stream=True)
self.raw_stream_url = re.sub(r".*(?=/d1--ov-gotcha05)", f"http://{ov05_ip}", r.url, 1)
logger.debug(f"将ov-gotcha05的节点ip替换为了{ov05_ip}")
if bili_cdn_fallback:
try:
if s.get(self.raw_stream_url, stream=True).status_code == 404:
stream_info['url_info'].reverse()
for url_info in stream_info['url_info']:
self.raw_stream_url = url_info['host'] + stream_info['base_url'] + url_info['extra']
if s.get(self.raw_stream_url, stream=True).status_code == 200:
break
except Exception:
logger.error('')
return True
async def danmaku_download_start(self, filename):
@@ -164,46 +148,9 @@ def get_play_info(s, custom_api, official_api_host, params):
custom_api_host = \
(lambda a: a if a.startswith(('http://', 'https://')) else 'http://' + a)(config.get('bili_liveapi')
.rstrip('/'))
# 尝试获取直播流
try:
return s.get(custom_api_host + '/xlive/web-room/v2/index/getRoomPlayInfo', params=params,
timeout=5).json()
except requests.exceptions.ConnectionError:
logger.error(f"{custom_api_host}连接失败,尝试回退至官方Api")
return s.get(official_api_host + '/xlive/web-room/v2/index/getRoomPlayInfo', params=params, timeout=5).json()
def get_live_cover(uname, room_id, room_title, live_start_time, cover_url):
headers = {
"origin": "https://www.bilibili.com",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.41"
}
response = requests.get(cover_url, headers=headers, timeout=5)
save_dir = f'cover/{uname}_{room_id}/'
local_time = time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime(live_start_time))
if not os.path.exists(save_dir):
os.makedirs(save_dir)
cover_file_name = f'{room_title}_{local_time}.png'
cover_file_name = get_valid_filename(cover_file_name)
live_cover_path = f'{save_dir}{cover_file_name}'
if os.path.exists(live_cover_path):
return live_cover_path
else:
with open(live_cover_path, 'wb') as f:
f.write(response.content)
return live_cover_path
def get_valid_filename(name):
"""
Return the given string converted to a string that can be used for a clean
filename. Remove leading and trailing spaces; convert other spaces to
underscores; and remove anything that is not an alphanumeric, dash,
underscore, or dot.
# >>> get_valid_filename("john's portrait in 2004.jpg")
>>> get_valid_filename("{self.fname}%Y-%m-%dT%H_%M_%S")
'{self.fname}%Y-%m-%dT%H_%M_%S'
"""
# s = str(name).strip().replace(" ", "_") #因为有些人会在主播名中间加入空格,为了避免和录播完毕自动改名冲突,所以注释掉
s = re.sub(r"(?u)[^-\w.%{}\[\]【】「」\s]", "", str(name))
if s in {"", ".", ".."}:
raise RuntimeError("Could not derive file name from '%s'" % name)
return s
+28 -19
View File
@@ -17,10 +17,9 @@ class Douyu(DownloadBase):
self.douyu_danmaku = config.get('douyu_danmaku', False)
def check_stream(self):
logger.debug(self.fname)
from ykdl.extractors.douyu.util import ub98484234
if len(self.url.split("douyu.com/")) < 2:
logger.debug("直播间地址:" + self.url + " 错误")
logger.error("直播间地址:" + self.url + " 错误")
return False
html = requests.get(self.url).text
vid = match1(html, r'\$ROOM\.room_id\s*=\s*(\d+)',
@@ -28,34 +27,28 @@ class Douyu(DownloadBase):
r'"room_id.?":(\d+)',
r'data-onlineid=(\d+)')
if not vid:
logger.debug("直播间" + vid + ":被关闭或不存在")
logger.error("直播间" + vid + ":被关闭或不存在")
return False
roominfo = requests.get(f"https://www.douyu.com/betard/{vid}").json()['room']
videoloop = roominfo['videoLoop']
show_status = roominfo['show_status']
if show_status != 1 or videoloop != 0:
logger.debug("直播间" + vid + ":未开播或正在放录播")
if roominfo['show_status'] != 1 or roominfo['videoLoop'] != 0:
logger.error("直播间" + vid + ":未开播或正在放录播")
return False
# tct-h5
douyucdn = config.get('douyucdn') if config.get('douyucdn') else ''
self.room_title = roominfo['room_name']
html_h5enc = requests.get(f'https://www.douyu.com/swf_api/homeH5Enc?rids={vid}').json()
js_enc = html_h5enc['data']['room' + vid]
params = {
'cdn': douyucdn,
'cdn': config.get('douyucdn', ''),
'iar': 0,
'ive': 0,
'rate': 0,
}
# print(js_enc)
Extractor = namedtuple('Extractor', ['vid', 'logger'])
ub98484234(js_enc, Extractor(vid, logger), params)
params['rate'] = 0
html_content = requests.post(f'https://www.douyu.com/lapi/live/getH5Play/{vid}', headers=self.fake_headers,
params=params).json()
live_data = html_content["data"]
if type(live_data) is dict:
self.raw_stream_url = f"{live_data.get('rtmp_url')}/{live_data.get('rtmp_live')}"
self.room_title = roominfo['room_name']
return True
live_data = get_play_info(vid, self.fake_headers, params)
if type(live_data) is not dict:
return False
self.raw_stream_url = f"{live_data.get('rtmp_url')}/{live_data.get('rtmp_live')}"
return True
async def danmaku_download_start(self, filename):
if self.douyu_danmaku:
@@ -67,3 +60,19 @@ class Douyu(DownloadBase):
if self.douyu_danmaku:
self.danmaku.stop()
logger.info("结束弹幕录制")
def get_play_info(vid, fake_headers, params):
import random
try:
html_content = requests.post(f'https://www.douyu.com/lapi/live/getH5Play/{vid}', headers=fake_headers,
params=params).json()
live_data = html_content["data"]
# 尝试规避斗鱼自建scdn
# scdn 仅在该省市的ISP首次访问上方API后才会新增,且在新增后两分钟内无流可用(404)
if not live_data['rtmp_cdn'].endswith('h5'):
while not params['cdn'].endswith('h5'):
params['cdn'] = random.choice(live_data['cdnsWithName']).get('cdn')
return get_play_info(vid, fake_headers, params)
except Exception:
return None
return live_data
+15 -13
View File
@@ -45,22 +45,25 @@ check_sourcecode = 15
#########各平台分设置#########
### 使用直播间封面作为投稿封面。此封面优先级低于单个主播指定的自定义封面。(直播封面将会保存于cover文件夹下,请自行定期删除)
#use_live_cover = true
#------斗鱼------#
# 如遇到斗鱼录制卡顿可以尝试切换线路,tct-h5(备用线路5),ali-h5(备用线路6),akm-h5(主线路1)
### 如遇到斗鱼录制卡顿可以尝试切换线路。
### tctc-h5(备用线路4), tct-h5(备用线路5), ali-h5(备用线路6), hw-h5(备用线路7), hs-h5(备用线路13)
#douyucdn = "tct-h5"
# 录制斗鱼弹幕,只有使用FFMPEG作为下载器才支持,默认关闭
#douyu_danmaku = false
#------虎牙------#
### 如遇到虎牙录制卡顿可以尝试切换线路,AL, HW, TX, WS
### 如遇到虎牙录制卡顿可以尝试切换线路。可选以下线路
### AL(阿里云), HW(华为云), TX(腾讯云), WS(网宿), HS(火山引擎), AL13(阿里云), HW16(华为云)
#huyacdn = "AL"
### 录制虎牙弹幕,只有使用FFMPEG作为下载器才支持,默认关闭
#huya_danmaku = false
#------哔哩哔哩------#
### 获取BILIBILI直播间封面并作为投稿封面。此封面优先级低于单个主播指定的自定义封面。(直播封面将会保存于cover文件夹下,请自行定期删除)
#use_live_cover = true
### 录制BILIBILI弹幕,目前暂时不支持视频按时长分段下的弹幕文件自动分段,默认关闭
# bilibili_danmaku = false
### 哔哩哔哩直播流协议.可选 stream(flv流),hls_ts(ts流)与hls_fmp4(fmp4流),默认为stream
@@ -72,13 +75,12 @@ check_sourcecode = 15
### 哔哩哔哩直播优选CDN,默认无
#bili_perfCDN = "cn-gotcha01"
### 哔哩哔哩直播强制原画(仅限HLS流的 cn-gotcha01 CDN),默认为关闭
#bili_forceScoure = false
#bili_force_source = false
### 自定义哔哩哔哩直播api,默认无
#bili_liveapi = "https://api.live.bilibili.com"
### CDN自动Fallback开关,默认为开启
#bili_cdn_fallback = true
### 强制替换ov-gotcha05的下载地址为指定的自选IP
#bili_force_ov05 = true
#bili_force_ov05_ip = "163.171.197.234"
### 强制替换cn-gotcha01(叔叔自建,理论上最稳定)为指定的自选域名组(可多个域名,请用逗号分隔)
### 完整CDN列表请参考 https://rec.danmuji.org/dev/bilibili-cdn/ 中"B站视频云"的部分
@@ -86,10 +88,10 @@ check_sourcecode = 15
### 此功能目前会和stream-gears冲突导致很多分段,请考虑使用ffmpeg录制
### 如果海外机器需要使用此功能,需要在bili_liveapi中指定国内的反代API来获取cn-gotcha01的节点信息。
### 海外机的玩法:配合一个国内的机器(例如便宜的腾讯云,阿里云等等)自建反代api.live.bilibili.com
### 如果海外机到联通或者移动网络线路还不错,就可以参考https://rec.danmuji.org/dev/bilibili-cdn/ 选取一些联通或者移动的节点并填入下面
### 如果海外机到联通或者移动网络线路还不错,就可以参考***完整CDN列表***选取一些联通或者移动的节点并填入下面
### 每次会随机返回填入的其中一个线路,并且会自动判断所填入的节点是否可用
#bili_force_cn01 = true
#bili_force_cn01_domains = "cn-gdst-cm-01-15.bilivideo.com,cn-gdst-cm-01-06.bilivideo.com,cn-fjqz-cm-01-06.bilivideo.com,cn-jssz-cm-01-02.bilivideo.com,cn-jxnc-cm-01-02.bilivideo.com"
#bili_force_cn01_domains = "cn-jxnc-cm-01-16.bilivideo.com,cn-gddg-cm-01-06.bilivideo.com,cn-fjqz-cm-01-06.bilivideo.com,cn-jssz-cm-01-02.bilivideo.com,cn-gddg-ct-01-12.bilivideo.com"
#------YouTube------#
### 设置偏好的YouTube下载封装格式
@@ -102,7 +104,7 @@ check_sourcecode = 15
#youtube_prefer_acodec = "opus|mp4a" ### 可用opus,mp4a
### 设置偏好的YouTube下载最高纵向分辨率
### 最高纵向分辨率,也就是xxxxP.如果youtube_prefer_format指定为mp4,将最高只能下载1080p的视频。
#youtube_max_resolution = "440"
#youtube_max_resolution = "440"
### 限制单个视频的最大大小。
### 注意:此参数优先级高于分辨率设置,并且不包括音频部分的大小,仅仅只是视频部分的大小。
### 如果某个视频实在没有低于此大小的分辨率版本,将会选择最低画质的版本下载。
@@ -152,8 +154,9 @@ tags = [ "biliup", "视频标签" ]
[user]
#------哔哩哔哩------#
#------哔哩哔哩获取直播流用COOKIE------#
### 参照https://github.com/BililiveRecorder/BililiveRecorder/issues/263
#bili_cookie = ""
### 可参照https://github.com/BililiveRecorder/BililiveRecorder/issues/263.
### 也可使用biliup-rs来获取以下项目.
#bili_cookie: 'SESSDATA=none;bili_jct=none;DedeUserID__ckMd5=none;DedeUserID=none;access_token=none;'
### 重要!!!
###是否将cookie传入第三方API。将Cookie传入未知的第三方API有几率泄露帐号登录信息。
###在开启了自定义Cookie(bili_cookie)又同时设置了第三方API(bili_liveapi)的情况下,如果打开了允许第三方API使用Cookie,那么就使用第三方API,如果没有允许(默认),那么设置的第三方API就不生效
@@ -170,9 +173,8 @@ douyin_cookie = '__ac_nonce=123456; __ac_signature=123456;'
#twitch_cookie = 'asdiouo2h987r23hf2893fh923y7'
#------YouTube------#
### 使用Cookies登陆YouTube帐号,可用于下载会限,私享等未登录账号无法访问的内容。请使用Netscape 格式的 Cookies 文本路径。
### 使用Cookies登陆YouTube帐号,可用于下载会限,私享等未登录账号无法访问的内容。请使用 Netscape 格式的 Cookies 文本路径。
### 可以使用Chrome插件Get cookies.txt来生成txt文件。
# Netscape 格式的 Cookies 文本路径
#youtube_cookie = 'cookiejar.txt'
# 日志输出配置
+12 -23
View File
@@ -43,22 +43,24 @@ pool2_size: 3
check_sourcecode: 15
#########各平台分设置#########
### 使用直播间封面作为投稿封面。此封面优先级低于单个主播指定的自定义封面。(直播封面将会保存于cover文件夹下,请自行定期删除)
#use_live_cover: true
#------斗鱼------#
### 如遇到斗鱼录制卡顿可以尝试切换线路,tct-h5(备用线路5),ali-h5(备用线路6),akm-h5(主线路1)
### 如遇到斗鱼录制卡顿可以尝试切换线路。可选以下线路
### tctc-h5(备用线路4), tct-h5(备用线路5), ali-h5(备用线路6), hw-h5(备用线路7), hs-h5(备用线路13)
#douyucdn: tct-h5
# 录制斗鱼弹幕,目前暂时不支持视频按时长分段下的弹幕文件自动分段,只有使用ffmpeg(包括streamlink混合模式)作为下载器才支持,默认关闭默认关闭
#douyu_danmaku: false
#------虎牙------#
### 如遇到虎牙录制卡顿可以尝试切换线路,AL, HW, TX, WS
### 如遇到虎牙录制卡顿可以尝试切换线路。可选以下线路
### AL(阿里云), HW(华为云), TX(腾讯云), WS(网宿), HS(火山引擎), AL13(阿里云), HW16(华为云)
#huyacdn: AL
### 录制虎牙弹幕,目前暂时不支持视频按时长分段下的弹幕文件自动分段,只有使用ffmpeg(包括streamlink混合模式)作为下载器才支持,默认关闭默认关闭
#huya_danmaku: false
#------哔哩哔哩------#
### 获取BILIBILI直播间封面并作为投稿封面。此封面优先级低于单个主播指定的自定义封面。(直播封面将会保存于cover文件夹下,请自行定期删除)
#use_live_cover: true
### 录制BILIBILI弹幕,目前暂时不支持视频按时长分段下的弹幕文件自动分段,只有使用ffmpeg(包括streamlink混合模式)作为下载器才支持,默认关闭默认关闭
# bilibili_danmaku: false
### 哔哩哔哩直播流协议.可选 stream(flv流),hls_ts(ts流)与hls_fmp4(fmp4流),默认为stream
@@ -70,7 +72,7 @@ check_sourcecode: 15
### 哔哩哔哩直播优选CDN,默认无
#bili_perfCDN: cn-gotcha01
### 哔哩哔哩直播强制原画(仅限HLS流的 cn-gotcha01 CDN),默认为关闭
#bili_forceScoure: false
#bili_force_source: false
### 自定义哔哩哔哩直播api,默认无
#bili_liveapi: 'https://api.live.bilibili.com'
### CDN自动Fallback开关,默认为开启
@@ -83,9 +85,9 @@ check_sourcecode: 15
### 此功能目前会和stream-gears冲突导致很多分段,请考虑使用ffmpeg录制
### 如果海外机器需要使用此功能,需要在bili_liveapi中指定国内的反代API来获取cn-gotcha01的节点信息。
### 海外机的玩法:配合一个国内的机器(例如便宜的腾讯云,阿里云等等)自建反代api.live.bilibili.com
### 如果海外机到联通或者移动网络线路还不错,就可以参考https://rec.danmuji.org/dev/bilibili-cdn/ 选取一些联通或者移动的节点并填入下面
### 如果海外机到联通或者移动网络线路还不错,就可以参考***完整CDN列表***选取一些联通或者移动的节点并填入下面
### 每次会随机返回填入的其中一个线路,并且会自动判断所填入的节点是否可用
#bili_force_cn01_domains: 'cn-gdst-cm-01-15.bilivideo.com,cn-gdst-cm-01-06.bilivideo.com,cn-fjqz-cm-01-06.bilivideo.com,cn-jssz-cm-01-02.bilivideo.com,cn-jxnc-cm-01-02.bilivideo.com'
#bili_force_cn01_domains: 'cn-jxnc-cm-01-16.bilivideo.com,cn-gddg-cm-01-06.bilivideo.com,cn-fjqz-cm-01-06.bilivideo.com,cn-jssz-cm-01-02.bilivideo.com,cn-gddg-ct-01-12.bilivideo.com'
#------YouTube------#
### 设置偏好的YouTube下载封装格式
@@ -99,7 +101,7 @@ check_sourcecode: 15
### 设置偏好的YouTube下载最高纵向分辨率
### 最高纵向分辨率,也就是xxxxP。如果youtube_prefer_vcodec指定AVC,将最高只能下载1080p的视频。
#youtube_max_videosize: "5G"
#youtube_max_resolution: 1440
#youtube_max_resolution: 1440
### 限制单个视频的最大大小。
### 注意:此参数优先级高于分辨率设置,并且不包括音频部分的大小,仅仅只是视频部分的大小。
### 如果某个视频实在没有低于此大小的分辨率版本,将会选择最低画质的版本下载。
@@ -153,26 +155,13 @@ streamers:
#user:
#------哔哩哔哩------#
#------哔哩哔哩获取直播流用COOKIE------#
### 参照https://github.com/BililiveRecorder/BililiveRecorder/issues/263
#bili_cookie: ''
### 参照https://github.com/BililiveRecorder/BililiveRecorder/issues/263. 请至少填入以下项目.
#bili_cookie: 'SESSDATA=none; bili_jct=none;DedeUserID__ckMd5=none;DedeUserID=123;access_token=none;'
### 重要!!!
###是否将cookie传入第三方API。将Cookie传入未知的第三方API有几率泄露帐号登录信息。
###在开启了自定义Cookie(bili_cookie)又同时设置了第三方API(bili_liveapi)的情况下,如果打开了允许第三方API使用Cookie,那么就使用第三方API,如果没有允许(默认),那么设置的第三方API就不生效
#customAPI_use_cookie : False
#------bili-web用(已过时,无视我)------#
# cookies:
# SESSDATA: your SESSDATA
# bili_jct: your bili_jct
# DedeUserID__ckMd5: your ckMd5
# DedeUserID: your DedeUserID
# access_token: your access_key
# account:
# username: your usrname
# password: your password
# app_key: bca7e84c2d947ac6 ### 若账号密码方式无法登录可尝试更改此值
# appsec: 60698ba2f68e01ce44738920a0ffe768
#------抖音------#
### 如需要录制抖音请在此填入cookie需要__ac_nonce与__ac_signature的值
#douyin_cookie: '__ac_nonce=123456; __ac_signature=123456;'