fix(Plugins.Huya): Update HuYaUA (#1291)
* fix(Plugins.Huya): HuYaUA * add options to disable wup headers * cleanup * Update __init__.py --------- Co-authored-by: ForgQi <34411314+ForgQi@users.noreply.github.com>
This commit is contained in:
1 parent
b61ff5ed08
commit
45839c7e88
4 files changed
+78
-26
No files matched your search
+12
-2
@@ -120,8 +120,18 @@ const Huya: React.FC<Props> = props => {
|
||||
/>
|
||||
<Form.Switch
|
||||
field="huya_mobile_api"
|
||||
extraText="使用移动端API可以绕过 PCWEB 端对原画的时长限制"
|
||||
label="虎牙使用移动端API(huya_mobile_api)"
|
||||
extraText="移动端 API 请求直播间信息,可能解决部分直播分区 2 分钟分段问题"
|
||||
label="使用移动端 API(huya_mobile_api)"
|
||||
fieldStyle={{
|
||||
alignSelf: 'stretch',
|
||||
padding: 0,
|
||||
}}
|
||||
/>
|
||||
<Form.Switch
|
||||
field="huya_use_wup"
|
||||
extraText="使用 WUP 协议的请求头,可能解决部分直播分区 2 分钟分段问题"
|
||||
label="使用 WUP 协议(huya_use_wup)"
|
||||
initValue={entity?.hasOwnProperty('huya_use_wup') ? entity['huya_use_wup'] : true}
|
||||
fieldStyle={{
|
||||
alignSelf: 'stretch',
|
||||
padding: 0,
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import logging
|
||||
import platform
|
||||
import sys
|
||||
|
||||
__version__ = "0.4.97"
|
||||
__version__ = "0.4.98"
|
||||
|
||||
LOG_CONF = {
|
||||
'version': 1,
|
||||
|
||||
@@ -104,13 +104,16 @@ class DownloadBase(ABC):
|
||||
return True
|
||||
|
||||
def download(self):
|
||||
logger.info(f"{self.plugin_msg}: Start downloading {self.raw_stream_url}")
|
||||
# print(f"{self.plugin_msg}: Plugin settings - {self.__dict__}")
|
||||
logger.info(f"{self.plugin_msg}: Plugin settings - {self.__dict__}")
|
||||
# logger.info(f"{self.plugin_msg}: Request headers - {self.fake_headers}")
|
||||
logger.info(f"{self.plugin_msg}: Request url - {self.raw_stream_url}")
|
||||
# 调试使用边录边上传功能
|
||||
# self.downloader = 'sync-downloader'
|
||||
if self.is_download:
|
||||
if not shutil.which("ffmpeg"):
|
||||
logger.error("未安装 FFMpeg 或不存在于 PATH 内")
|
||||
logger.debug("Current user's PATH is:" + os.getenv("PATH"))
|
||||
logger.info("Current user's PATH is:" + os.getenv("PATH"))
|
||||
return False
|
||||
else:
|
||||
return self.ffmpeg_segment_download()
|
||||
@@ -119,7 +122,7 @@ class DownloadBase(ABC):
|
||||
if self.downloader != 'stream-gears':
|
||||
if not shutil.which("ffmpeg"):
|
||||
logger.error("未安装 FFMpeg 或不存在于 PATH 内,本次下载使用 stream-gears")
|
||||
logger.debug("Current user's PATH is:" + os.getenv("PATH"))
|
||||
logger.info("Current user's PATH is:" + os.getenv("PATH"))
|
||||
else:
|
||||
# 同步下载上传器
|
||||
if self.downloader == 'sync-downloader':
|
||||
|
||||
+59
-20
@@ -37,8 +37,10 @@ class Huya(DownloadBase):
|
||||
self.huya_cdn_fallback = config.get('huya_cdn_fallback', False)
|
||||
self.huya_mobile_api = config.get('huya_mobile_api', False)
|
||||
self.huya_codec = config.get('huya_codec', '264')
|
||||
self.huya_use_wup = config.get('huya_use_wup', True)
|
||||
|
||||
async def acheck_stream(self, is_check=False):
|
||||
|
||||
try:
|
||||
if not self.__room_id.isdigit():
|
||||
client.headers.update(self.fake_headers)
|
||||
@@ -67,14 +69,17 @@ class Huya(DownloadBase):
|
||||
|
||||
# self.room_title = room_profile['room_title']
|
||||
|
||||
is_xingxiu = (room_profile['gid'] == 1663)
|
||||
stream_urls = self.build_stream_urls(room_profile['streams_info'], is_xingxiu)
|
||||
# is_xingxiu = (room_profile['gid'] == 1663)
|
||||
gid_blacklist = [1663, ]
|
||||
skip_query_build = self.huya_imgplus and (self.huya_mobile_api or room_profile['gid'] in gid_blacklist)
|
||||
stream_urls = self.build_stream_urls(room_profile['streams_info'], skip_query_build)
|
||||
cdn_list = list(stream_urls.keys())
|
||||
if not self.huya_cdn or self.huya_cdn not in cdn_list:
|
||||
self.huya_cdn = cdn_list[0]
|
||||
|
||||
# Thx stream-rec
|
||||
self.update_user_agent(self.fake_headers)
|
||||
if self.huya_use_wup:
|
||||
self.update_headers(self.fake_headers)
|
||||
|
||||
try:
|
||||
self.raw_stream_url = self.add_ratio(
|
||||
@@ -86,7 +91,7 @@ class Huya(DownloadBase):
|
||||
logger.error(f"{self.plugin_msg}: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
# 虎牙直播流只允许连接一次
|
||||
# HTTPS的直播流只允许连接一次
|
||||
if self.huya_cdn_fallback:
|
||||
_url = await self.acheck_url_healthy(self.raw_stream_url)
|
||||
if _url is None:
|
||||
@@ -107,7 +112,7 @@ class Huya(DownloadBase):
|
||||
if not room_profile['live']:
|
||||
logger.debug(f"{self.plugin_msg}: {room_profile['message']}")
|
||||
return False
|
||||
stream_urls = self.build_stream_urls(room_profile['streams_info'], is_xingxiu)
|
||||
stream_urls = self.build_stream_urls(room_profile['streams_info'], skip_query_build)
|
||||
|
||||
self.raw_stream_url = self.add_ratio(
|
||||
stream_urls[self.huya_cdn],
|
||||
@@ -181,10 +186,11 @@ class Huya(DownloadBase):
|
||||
stream_name = self.get_stream_name(stream['sStreamName'])
|
||||
cdn = stream['sCdnType']
|
||||
suffix = stream[f's{proto}UrlSuffix']
|
||||
anti_code = stream[f's{proto}AntiCode'] + f"&codec={self.huya_codec}"
|
||||
anti_code = stream[f's{proto}AntiCode']
|
||||
if not skip_query_build:
|
||||
anti_code = self.build_query(stream_name, anti_code, stream['lPresenterUid'])
|
||||
base_url = stream[f's{proto}Url'].replace('http://', 'https://')
|
||||
anti_code = self.build_query(stream_name, anti_code, self.get_uid(stream['lPresenterUid']))
|
||||
anti_code = f"{anti_code}&codec={self.huya_codec}"
|
||||
base_url = stream[f's{proto}Url'].replace('http://', 'https://') # 强制https
|
||||
streams[cdn] = f"{base_url}/{stream_name}.{suffix}?{anti_code}"
|
||||
weights[cdn] = priority
|
||||
return self.__weight_sorting(streams, weights)
|
||||
@@ -305,7 +311,7 @@ class Huya(DownloadBase):
|
||||
"u": convert_uid,
|
||||
"uuid": str(int((ct % 1e10 + random.random()) * 1e3 % 0xffffffff)),
|
||||
"sdk_sid": str(int(time.time() * 1000)),
|
||||
"codec": self.huya_codec,
|
||||
# "codec": self.huya_codec,
|
||||
}
|
||||
return '&'.join([f"{k}={v}" for k, v in anti_code.items()])
|
||||
|
||||
@@ -319,6 +325,16 @@ class Huya(DownloadBase):
|
||||
return {}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_uid(uid: Union[str, int, None] = None) -> int:
|
||||
try:
|
||||
if isinstance(uid, str):
|
||||
uid = int(uid)
|
||||
except ValueError:
|
||||
pass
|
||||
return uid or random.randint(1400000000000, 1499999999999)
|
||||
|
||||
|
||||
async def get_anonymous_uid(self) -> int:
|
||||
try:
|
||||
rsp = await client.post(
|
||||
@@ -332,21 +348,44 @@ class Huya(DownloadBase):
|
||||
"data": {},
|
||||
}
|
||||
)
|
||||
data = json_loads(rsp.text)
|
||||
rsp = json_loads(rsp.text)
|
||||
except:
|
||||
return random.randint(1400000000000, 1499999999999)
|
||||
else:
|
||||
return data['data']['uid']
|
||||
rsp = {}
|
||||
return rsp.get('data', {}).get('uid', self.get_uid())
|
||||
|
||||
|
||||
@staticmethod
|
||||
def update_user_agent(headers: dict):
|
||||
# copied from stream-rec commit b48c9cd
|
||||
valid_ts = 20000308
|
||||
current_ts = int(time.time())
|
||||
version = str(current_ts)[-8:]
|
||||
version = version if int(version) > valid_ts else (valid_ts + (current_ts / 100))
|
||||
headers['user-agent'] = f"HYSDK(Windows, {version})"
|
||||
def get_hyapp_ua() -> str:
|
||||
hyapp_platform = 'huya_nftv' # adr or huya_nftv, pc_exe, webh5
|
||||
hyapp_version = '2.5.1.3141' # adr/nftv: LocalVersion or "0.0.0" + hotfix_version, pc_exe: 6070100, ws: 2505091506
|
||||
hyapp_channel = 'official' # adr: live, nftv/pc_exe: official, websocket
|
||||
android_api_level = random.randint(28, 35) # Build.VERSION.SDK_INT
|
||||
ua = f"{hyapp_platform}&{hyapp_version}&{hyapp_channel}"
|
||||
return ua if hyapp_platform in {'pc_exe', 'webh5'} else f"{ua}&{android_api_level}"
|
||||
|
||||
@staticmethod
|
||||
def get_hysdk_ua() -> str:
|
||||
hysdk_platform = 'Android' # Android, Windows
|
||||
hysdk_version = '30000002' # 30000002
|
||||
return f"HYSDK({hysdk_platform}, {hysdk_version})"
|
||||
|
||||
@staticmethod
|
||||
def get_hy_media_player_ua() -> str:
|
||||
hy_mp_platform = 'android' # android
|
||||
hy_mp_version = '20000313' # 20000313
|
||||
return f"{hy_mp_platform}, {hy_mp_version}"
|
||||
|
||||
@staticmethod
|
||||
def get_hy_trans_mod_ua() -> str:
|
||||
hy_trans_mod_name = 'trans' # trans
|
||||
hy_trans_mod_version = '1.24.99-rel-tv' # nftv: 1.24.99-rel-tv, adr: 2.22.13-rel, win: 2.21.0.4784
|
||||
return f"{hy_trans_mod_name}&{hy_trans_mod_version}"
|
||||
|
||||
@staticmethod
|
||||
def update_headers(headers: dict):
|
||||
user_agent = f"{Huya.get_hy_media_player_ua()}_APP({Huya.get_hyapp_ua()})_SDK({Huya.get_hy_trans_mod_ua()})"
|
||||
# user_agent = f"{Huya.get_hysdk_ua()}_APP({Huya.get_hyapp_ua()})_SDK({Huya.get_hy_trans_mod_ua()})"
|
||||
headers['user-agent'] = user_agent
|
||||
headers['origin'] = HUYA_WEB_BASE_URL
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user