Skip to content

Commit

Permalink
更新 CC 平台 (#936)
Browse files Browse the repository at this point in the history
* 更新 CC 平台

* 清理调试代码

* 更新虎牙线路,CC直播标题

* 修复虎牙线路屏蔽
  • Loading branch information
xxxxuanran committed May 20, 2024
1 parent f3c01e6 commit 58833f1
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 54 deletions.
3 changes: 3 additions & 0 deletions app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import styles from "../styles/dashboard.module.scss";
import Global from "../ui/plugins/global";
import Cookie from "../ui/plugins/cookie";
import Bilibili from "../ui/plugins/bilibili";
import CC from "../ui/plugins/cc";
import Douyin from "../ui/plugins/douyin";
import Douyu from "../ui/plugins/douyu";
import Huya from "../ui/plugins/huya";
Expand Down Expand Up @@ -209,6 +210,8 @@ const Dashboard: React.FC = () => {
<Collapse keepDOM style={{ width: '100%' }}>
{/* 哔哩哔哩 */}
<Bilibili />
{/* CC直播 */}
<CC />
{/* 抖音 */}
<Douyin />
{/* 斗鱼 */}
Expand Down
36 changes: 36 additions & 0 deletions app/ui/plugins/cc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use client";
import React from "react";
import { Form, Select, Collapse } from "@douyinfe/semi-ui";


const CC: React.FC = () => {
return (
<>
<Collapse.Panel header="CC" itemKey="cc">
<Form.Select
field="cc_protocol"
extraText={
<div style={{ fontSize: "14px" }}>
CC直播流协议。
<br />
如果录制经常分段,尝试切换。
</div>
}
label="直播流协议(cc_protocol)"
placeholder="hls(默认)"
style={{ width: "100%" }}
fieldStyle={{
alignSelf: "stretch",
padding: 0,
}}
showClear={true}
>
<Select.Option value="flv">flv</Select.Option>
<Select.Option value="hls">hls(默认)</Select.Option>
</Form.Select>
</Collapse.Panel>
</>
);
};

export default CC;
7 changes: 3 additions & 4 deletions app/ui/plugins/global.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,15 @@ const Global: React.FC = () => {
<Form.Select
label="下载插件(downloader)"
field="downloader"
placeholder="stream-gears"
placeholder="stream-gears(默认)"
maxTagCount={3}
// initValue="stream-gears"
extraText={
<div style={{ fontSize: "14px" }}>
选择全局默认的下载插件, 可选:
<br />
1.
streamlink(streamlink配合ffmpeg混合下载模式,适合用于下载hls_fmp4与hls_ts流,因为streamlink支持多线程拉取,
使用该模式下载flv流时,将会仅使用ffmpeg。请手动安装streamlink以及ffmpeg)
streamlink(streamlink 用于多线程下载 hls 流,对于 FLV 流将仅使用 ffmpeg。请手动安装ffmpeg)
<br />
2. ffmpeg(纯ffmpeg下载。请手动安装ffmpeg)
<br />
Expand All @@ -51,7 +50,7 @@ const Global: React.FC = () => {
showClear={true}
>
<Select.Option value="streamlink">
streamlink(混合模式
streamlink(hls多线程下载
</Select.Option>
<Select.Option value="ffmpeg">ffmpeg</Select.Option>
<Select.Option value="stream-gears">
Expand Down
7 changes: 4 additions & 3 deletions app/ui/plugins/huya.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Huya: React.FC = () => {
]}
showClear={true}
>
<Select.Option value={0}>最高画质(0)</Select.Option>
<Select.Option value={0}>原画(0)</Select.Option>
<Select.Option value={20000}>蓝光20M(20000)</Select.Option>
<Select.Option value={10000}>蓝光10M(10000)</Select.Option>
<Select.Option value={8000}>蓝光8M(8000)</Select.Option>
Expand All @@ -48,9 +48,9 @@ const Huya: React.FC = () => {
<div style={{ fontSize: "14px" }}>
如遇到虎牙录制卡顿可以尝试切换线路。可选以下线路
<br />
AL(阿里云 - 直播线路3), TX(腾讯云 - 直播线路5), HW(华为云 - 直播线路6), WS(网宿), HS(火山引擎 - 直播线路14), AL13(阿里云), HW16(华为云)
AL(阿里云 - 直播线路3), TX(腾讯云 - 直播线路5), HW(华为云 - 直播线路6), WS(网宿), HS(火山引擎 - 直播线路14), AL13(阿里云), TX15(腾讯云), HW16(华为云)
<br />
HY(星域云 - 直播线路66) 该线路为 PCDN,已被屏蔽,不要设置该线路
HYZJ(虎牙自建 - 直播线路66) 该线路已被屏蔽,不要设置该线路
</div>
}
label="访问线路(huya_cdn)"
Expand All @@ -73,6 +73,7 @@ const Huya: React.FC = () => {
{/* <Select.Option value="WS">网宿(WS)</Select.Option> */}
<Select.Option value="AL13">直播线路13(AL13)</Select.Option>
<Select.Option value="HS">直播线路14(HS)</Select.Option>
<Select.Option value="TX15">直播线路15(TX15)</Select.Option>
<Select.Option value="HW16">直播线路16(HW16)</Select.Option>
</Form.Select>
<Form.Switch
Expand Down
6 changes: 3 additions & 3 deletions biliup/engine/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,11 @@ def download_cover(self, fmtname):
except:
logger.exception(f'封面下载失败:{self.__class__.__name__} - {self.fname}')

@staticmethod
async def acheck_url_healthy(url):
async def acheck_url_healthy(self, url):
timeout = 60 if '.flv' in url else 5

async def __client_get(url, stream: bool = False):
client.headers.update(self.fake_headers)
if stream:
async with client.stream("GET", url, timeout=timeout, follow_redirects=False) as response:
pass
Expand Down Expand Up @@ -451,7 +451,7 @@ async def __client_get(url, stream: bool = False):
except HTTPStatusError as e:
logger.error(f'url {url}: status_code-{e.response.status_code}')
except:
logger.exception(f'url {url} is not healthy')
logger.exception(f'url {url}: ')
return None

def gen_download_filename(self, is_fmt=False):
Expand Down
49 changes: 30 additions & 19 deletions biliup/plugins/cc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import json
import re

import biliup.common.util
from . import logger
from biliup.common.util import client
from biliup.config import config
from . import logger, match1
from ..common import tools
from ..engine.decorators import Plugin
from ..engine.download import DownloadBase
Expand All @@ -14,23 +12,36 @@ def __init__(self, fname, url, suffix='flv'):
super().__init__(fname, url, suffix)

async def acheck_stream(self, is_check=False):
logger.debug(self.fname)
rid = re.search(r"[0-9]{4,}", self.url).group(0)
res = await biliup.common.util.client.get(
rid = match1(self.url, r"(\d{4,})")
room_info = (await client.get(
f"https://api.cc.163.com/v1/activitylives/anchor/lives?anchor_ccid={rid}",
timeout=5,
headers=self.fake_headers
)
# res.close()
jsons = json.loads(res.text)
if jsons["data"]:
channel_id = jsons["data"][rid]["channel_id"]
res = await biliup.common.util.client.get(
)).json()
if len(room_info["data"][rid]) <= 1:
logger.debug(f"{self.plugin_msg}: 未开播")
return False

if is_check:
return True

try:
channel_id = room_info["data"][rid]["channel_id"]
channel_info = (await client.get(
f"https://cc.163.com/live/channel/?channelids={channel_id}",
timeout=5,
headers=self.fake_headers
)
# res.close()
jsons = json.loads(res.text)
self.raw_stream_url = jsons["data"][0]["sharefile"]
return True
)).json()["data"][0]
self.room_title = channel_info["title"]
if config.get("cc_protocol", "hls") == "hls":
self.raw_stream_url = channel_info["sharefile"]
else:
original = {"vbr": 0}
for level in channel_info["quickplay"]["resolution"].values():
original = level if level["vbr"] > original["vbr"] else original
self.raw_stream_url = list(original["cdn"].values())[0]
except:
logger.exception(f"{self.plugin_msg}: ")
return False

return True
49 changes: 25 additions & 24 deletions biliup/plugins/huya.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import time
from urllib.parse import parse_qs, unquote

import biliup.common.util
from biliup.common.util import client
from biliup.config import config
from biliup.plugins.Danmaku import DanmakuClient
from ..common import tools
Expand Down Expand Up @@ -70,26 +70,25 @@ async def acheck_stream(self, is_check=False):
return False

# 虎牙直播流只允许连接一次,非常丑陋的代码
# if cdn_fallback:
# # with requests.Session() as s:
# biliup.common.util.client.headers = self.fake_headers.copy()
# url_health, _ = self.acheck_url_healthy(stream_url)
# if not url_health:
# logger.debug(f"{plugin_msg}: {list(sCdns.keys())}")
# for sCdn in sCdns.keys():
# if sCdn == perf_cdn:
# continue
# logger.warning(f"{plugin_msg}: {perf_cdn} 无法连接,尝试 {sCdn}")
# stream_url, _ = await _build_stream_url(room_id, sCdn, self.fake_headers)
# url_health, _ = await self.acheck_url_healthy(stream_url)
# if url_health:
# perf_cdn = sCdn
# logger.warning(f"{plugin_msg}: CDN 切换为 {perf_cdn}")
# stream_url, _ = await _build_stream_url(room_id, perf_cdn, self.fake_headers)
# logger.debug(f"{plugin_msg}: {stream_url}")
# break
# else:
# return False
if cdn_fallback:
_url = self.acheck_url_healthy(stream_url)
if _url is None:
logger.info(f"{plugin_msg}: {list(sCdns.keys())}")
for sCdn in sCdns.keys():
if sCdn == perf_cdn:
continue
logger.warning(f"{plugin_msg}: cdn_fallback 尝试 {sCdn}")
stream_url, _ = await _build_stream_url(room_id, sCdn, self.fake_headers)
if (await self.acheck_url_healthy(stream_url)) is None:
continue
perf_cdn = sCdn
logger.info(f"{plugin_msg}: CDN 切换为 {perf_cdn}")
stream_url, _ = await _build_stream_url(room_id, perf_cdn, self.fake_headers)
logger.debug(f"{plugin_msg}: {stream_url}")
break
else:
logger.error(f"{self.plugin_msg}: cdn_fallback 所有链接无法使用")
return False

self.room_title = html_info['data'][0]['gameLiveInfo']['introduction']
self.raw_stream_url = stream_url
Expand All @@ -105,7 +104,7 @@ def danmaku_init(self):

async def _get_info_in_html(room_id, fake_headers):
try:
html = (await biliup.common.util.client.get(f"https://www.huya.com/{room_id}", timeout=5, headers=fake_headers)).text
html = (await client.get(f"https://www.huya.com/{room_id}", timeout=5, headers=fake_headers)).text
if '找不到这个主播' in html:
logger.error(f"Huya - {room_id}: 找不到这个主播")
return {}
Expand All @@ -115,7 +114,7 @@ async def _get_info_in_html(room_id, fake_headers):
return json.loads(html.split('stream: ')[1].split('};')[0])


async def _build_stream_url(room_id, perf_cdn, fake_headers):
async def _build_stream_url(room_id, perf_cdn, fake_headers, allow_imgplus=True):
html_info = await _get_info_in_html(room_id, fake_headers)
try:
streamInfo = html_info['data'][0]['gameStreamInfoList']
Expand All @@ -125,7 +124,9 @@ async def _build_stream_url(room_id, perf_cdn, fake_headers):
stream = streamInfo[0]
sFlvUrlSuffix, sStreamName, sFlvAntiCode = \
stream['sFlvUrlSuffix'], stream['sStreamName'], stream['sFlvAntiCode']
sCdns = {item['sCdnType']: item['sFlvUrl'] for item in streamInfo if item['sCdnType'] != 'HY'}
if not allow_imgplus:
sStreamName = sStreamName.replace('-imgplus', '')
sCdns = {item['sCdnType']: item['sFlvUrl'] for item in streamInfo if 'HY' not in item['sCdnType']}
sFlvUrl = sCdns.get(perf_cdn)
_stream_url = f'{sFlvUrl}/{sStreamName}.{sFlvUrlSuffix}?{_make_query(sStreamName, sFlvAntiCode)}'
return _stream_url, sCdns
Expand Down
2 changes: 1 addition & 1 deletion biliup/plugins/twitcasting.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
class Twitcasting(DownloadBase):
def __init__(self, fname, url, suffix='flv'):
super().__init__(fname, url, suffix)
self.twitcasting_danmaku = config.get('twitcasting_danmaku', True)
self.twitcasting_danmaku = config.get('twitcasting_danmaku', False)
self.twitcasting_password = config.get('twitcasting_password', '')
self.fake_headers['referer'] = "https://twitcasting.tv/"
if self.twitcasting_password:
Expand Down

0 comments on commit 58833f1

Please sign in to comment.