mirror of
https://github.com/ihmily/DouyinLiveRecorder.git
synced 2025-12-25 21:36:46 +08:00
feat: add migu live record
This commit is contained in:
parent
952eeb9b7c
commit
ae8200e01c
@ -31,30 +31,30 @@ mp4格式重新编码为h264 = 否
|
||||
|
||||
[推送配置]
|
||||
# 可选微信|钉钉|tg|邮箱|bark|ntfy 可填多个
|
||||
直播状态推送渠道 =
|
||||
钉钉推送接口链接 =
|
||||
微信推送接口链接 =
|
||||
bark推送接口链接 =
|
||||
直播状态推送渠道 =
|
||||
钉钉推送接口链接 =
|
||||
微信推送接口链接 =
|
||||
bark推送接口链接 =
|
||||
bark推送中断级别 = active
|
||||
bark推送铃声 =
|
||||
钉钉通知@对象(填手机号) =
|
||||
bark推送铃声 =
|
||||
钉钉通知@对象(填手机号) =
|
||||
钉钉通知@全体(是/否) = 否
|
||||
tgapi令牌 =
|
||||
tg聊天id(个人或者群组id) =
|
||||
smtp邮件服务器 =
|
||||
是否使用SMTP服务SSL加密(是/否) =
|
||||
SMTP邮件服务器端口 =
|
||||
邮箱登录账号 =
|
||||
发件人密码(授权码) =
|
||||
发件人邮箱 =
|
||||
发件人显示昵称 =
|
||||
收件人邮箱 =
|
||||
tgapi令牌 =
|
||||
tg聊天id(个人或者群组id) =
|
||||
smtp邮件服务器 =
|
||||
是否使用SMTP服务SSL加密(是/否) =
|
||||
SMTP邮件服务器端口 =
|
||||
邮箱登录账号 =
|
||||
发件人密码(授权码) =
|
||||
发件人邮箱 =
|
||||
发件人显示昵称 =
|
||||
收件人邮箱 =
|
||||
ntfy推送地址 = https://ntfy.sh/xxxx
|
||||
ntfy推送标签 = tada
|
||||
ntfy推送邮箱 =
|
||||
自定义推送标题 =
|
||||
自定义开播推送内容 =
|
||||
自定义关播推送内容 =
|
||||
ntfy推送邮箱 =
|
||||
自定义推送标题 =
|
||||
自定义开播推送内容 =
|
||||
自定义关播推送内容 =
|
||||
只推送通知不录制(是/否) = 否
|
||||
直播推送检测频率(秒) = 1800
|
||||
开播推送开启(是/否) = 是
|
||||
@ -63,63 +63,64 @@ ntfy推送邮箱 =
|
||||
[Cookie]
|
||||
# 录制抖音必填
|
||||
抖音cookie = ttwid=1%7CB1qls3GdnZhUov9o2NxOMxxYS2ff6OSvEWbv0ytbES4%7C1680522049%7C280d802d6d478e3e78d0c807f7c487e7ffec0ae4e5fdd6a0fe74c3c6af149511; my_rd=1; passport_csrf_token=3ab34460fa656183fccfb904b16ff742; passport_csrf_token_default=3ab34460fa656183fccfb904b16ff742; d_ticket=9f562383ac0547d0b561904513229d76c9c21; n_mh=hvnJEQ4Q5eiH74-84kTFUyv4VK8xtSrpRZG1AhCeFNI; store-region=cn-fj; store-region-src=uid; LOGIN_STATUS=1; __security_server_data_status=1; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%7D; pwa2=%223%7C0%7C3%7C0%22; download_guide=%223%2F20230729%2F0%22; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Afalse%2C%22volume%22%3A0.6%7D; strategyABtestKey=%221690824679.923%22; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1536%2C%5C%22screen_height%5C%22%3A864%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A8%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A150%7D%22; VIDEO_FILTER_MEMO_SELECT=%7B%22expireTime%22%3A1691443863751%2C%22type%22%3Anull%7D; home_can_add_dy_2_desktop=%221%22; __live_version__=%221.1.1.2169%22; device_web_cpu_core=8; device_web_memory_size=8; xgplayer_user_id=346045893336; csrf_session_id=2e00356b5cd8544d17a0e66484946f28; odin_tt=724eb4dd23bc6ffaed9a1571ac4c757ef597768a70c75fef695b95845b7ffcd8b1524278c2ac31c2587996d058e03414595f0a4e856c53bd0d5e5f56dc6d82e24004dc77773e6b83ced6f80f1bb70627; __ac_nonce=064caded4009deafd8b89; __ac_signature=_02B4Z6wo00f01HLUuwwAAIDBh6tRkVLvBQBy9L-AAHiHf7; ttcid=2e9619ebbb8449eaa3d5a42d8ce88ec835; webcast_leading_last_show_time=1691016922379; webcast_leading_total_show_times=1; webcast_local_quality=sd; live_can_add_dy_2_desktop=%221%22; msToken=1JDHnVPw_9yTvzIrwb7cQj8dCMNOoesXbA_IooV8cezcOdpe4pzusZE7NB7tZn9TBXPr0ylxmv-KMs5rqbNUBHP4P7VBFUu0ZAht_BEylqrLpzgt3y5ne_38hXDOX8o=; msToken=jV_yeN1IQKUd9PlNtpL7k5vthGKcHo0dEh_QPUQhr8G3cuYv-Jbb4NnIxGDmhVOkZOCSihNpA2kvYtHiTW25XNNX_yrsv5FN8O6zm3qmCIXcEe0LywLn7oBO2gITEeg=; tt_scid=mYfqpfbDjqXrIGJuQ7q-DlQJfUSG51qG.KUdzztuGP83OjuVLXnQHjsz-BRHRJu4e986
|
||||
快手cookie =
|
||||
tiktok_cookie =
|
||||
虎牙cookie =
|
||||
斗鱼cookie =
|
||||
yy_cookie =
|
||||
b站cookie =
|
||||
小红书cookie =
|
||||
bigo_cookie =
|
||||
blued_cookie =
|
||||
sooplive_cookie =
|
||||
netease_cookie =
|
||||
千度热播_cookie =
|
||||
pandatv_cookie =
|
||||
猫耳fm_cookie =
|
||||
winktv_cookie =
|
||||
flextv_cookie =
|
||||
look_cookie =
|
||||
twitcasting_cookie =
|
||||
baidu_cookie =
|
||||
weibo_cookie =
|
||||
kugou_cookie =
|
||||
twitch_cookie =
|
||||
liveme_cookie =
|
||||
huajiao_cookie =
|
||||
liuxing_cookie =
|
||||
showroom_cookie =
|
||||
acfun_cookie =
|
||||
changliao_cookie =
|
||||
快手cookie =
|
||||
tiktok_cookie =
|
||||
虎牙cookie =
|
||||
斗鱼cookie =
|
||||
yy_cookie =
|
||||
b站cookie =
|
||||
小红书cookie =
|
||||
bigo_cookie =
|
||||
blued_cookie =
|
||||
sooplive_cookie =
|
||||
netease_cookie =
|
||||
千度热播_cookie =
|
||||
pandatv_cookie =
|
||||
猫耳fm_cookie =
|
||||
winktv_cookie =
|
||||
flextv_cookie =
|
||||
look_cookie =
|
||||
twitcasting_cookie =
|
||||
baidu_cookie =
|
||||
weibo_cookie =
|
||||
kugou_cookie =
|
||||
twitch_cookie =
|
||||
liveme_cookie =
|
||||
huajiao_cookie =
|
||||
liuxing_cookie =
|
||||
showroom_cookie =
|
||||
acfun_cookie =
|
||||
changliao_cookie =
|
||||
yinbo_cookie =
|
||||
yingke_cookie =
|
||||
zhihu_cookie =
|
||||
chzzk_cookie =
|
||||
haixiu_cookie =
|
||||
vvxqiu_cookie =
|
||||
17live_cookie =
|
||||
langlive_cookie =
|
||||
pplive_cookie =
|
||||
6room_cookie =
|
||||
lehaitv_cookie =
|
||||
huamao_cookie =
|
||||
shopee_cookie =
|
||||
youtube_cookie =
|
||||
taobao_cookie =
|
||||
jd_cookie =
|
||||
faceit_cookie =
|
||||
yingke_cookie =
|
||||
zhihu_cookie =
|
||||
chzzk_cookie =
|
||||
haixiu_cookie =
|
||||
vvxqiu_cookie =
|
||||
17live_cookie =
|
||||
langlive_cookie =
|
||||
pplive_cookie =
|
||||
6room_cookie =
|
||||
lehaitv_cookie =
|
||||
huamao_cookie =
|
||||
shopee_cookie =
|
||||
youtube_cookie =
|
||||
taobao_cookie =
|
||||
jd_cookie =
|
||||
faceit_cookie =
|
||||
migu_cookie =
|
||||
|
||||
[Authorization]
|
||||
popkontv_token =
|
||||
popkontv_token =
|
||||
|
||||
[账号密码]
|
||||
sooplive账号 =
|
||||
sooplive密码 =
|
||||
flextv账号 =
|
||||
flextv密码 =
|
||||
popkontv账号 =
|
||||
sooplive账号 =
|
||||
sooplive密码 =
|
||||
flextv账号 =
|
||||
flextv密码 =
|
||||
popkontv账号 =
|
||||
partner_code = P-00001
|
||||
popkontv密码 =
|
||||
popkontv密码 =
|
||||
twitcasting账号类型 = normal
|
||||
twitcasting账号 =
|
||||
twitcasting密码 =
|
||||
twitcasting账号 =
|
||||
twitcasting密码 =
|
||||
5
demo.py
5
demo.py
@ -190,6 +190,10 @@ LIVE_STREAM_CONFIG = {
|
||||
"faceit": {
|
||||
"url": "https://www.faceit.com/zh/players/Compl1/stream",
|
||||
"func": spider.get_faceit_stream_data,
|
||||
},
|
||||
"migu": {
|
||||
"url": "https://www.miguvideo.com/p/live/120000541321",
|
||||
"func": spider.get_migu_stream_url,
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,3 +213,4 @@ def test_live_stream(platform_name: str, proxy_addr=None, cookies=None) -> None:
|
||||
if __name__ == "__main__":
|
||||
platform = "douyin"
|
||||
test_live_stream(platform)
|
||||
|
||||
21
main.py
21
main.py
@ -4,7 +4,7 @@
|
||||
Author: Hmily
|
||||
GitHub: https://github.com/ihmily
|
||||
Date: 2023-07-17 23:52:05
|
||||
Update: 2025-06-14 12:19:00
|
||||
Update: 2025-07-04 17:23:00
|
||||
Copyright (c) 2023-2025 by Hmily, All Rights Reserved.
|
||||
Function: Record live stream video.
|
||||
"""
|
||||
@ -38,9 +38,9 @@ from ffmpeg_install import (
|
||||
check_ffmpeg, ffmpeg_path, current_env_path
|
||||
)
|
||||
|
||||
version = "v4.0.3"
|
||||
version = "v4.0.5"
|
||||
platforms = ("\n国内站点:抖音|快手|虎牙|斗鱼|YY|B站|小红书|bigo|blued|网易CC|千度热播|猫耳FM|Look|TwitCasting|百度|微博|"
|
||||
"酷狗|花椒|流星|Acfun|畅聊|映客|音播|知乎|嗨秀|VV星球|17Live|浪Live|漂漂|六间房|乐嗨|花猫|淘宝|京东"
|
||||
"酷狗|花椒|流星|Acfun|畅聊|映客|音播|知乎|嗨秀|VV星球|17Live|浪Live|漂漂|六间房|乐嗨|花猫|淘宝|京东|咪咕"
|
||||
"\n海外站点:TikTok|SOOP|PandaTV|WinkTV|FlexTV|PopkonTV|TwitchTV|LiveMe|ShowRoom|CHZZK|Shopee|"
|
||||
"Youtube|Faceit")
|
||||
|
||||
@ -92,7 +92,7 @@ def display_info() -> None:
|
||||
time.sleep(5)
|
||||
while True:
|
||||
try:
|
||||
sys.stdout.flush() # 强制刷新输出缓冲区
|
||||
sys.stdout.flush()
|
||||
time.sleep(5)
|
||||
if Path(sys.executable).name != 'pythonw.exe':
|
||||
os.system(clear_command)
|
||||
@ -925,6 +925,12 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None:
|
||||
else:
|
||||
logger.error("错误信息: 网络异常,请检查本网络是否能正常访问faceit直播平台")
|
||||
|
||||
elif record_url.find("www.miguvideo.com") > -1 or record_url.find("m.miguvideo.com") > -1:
|
||||
platform = '咪咕直播'
|
||||
with semaphore:
|
||||
port_info = asyncio.run(spider.get_migu_stream_url(
|
||||
url=record_url, proxy_addr=proxy_address, cookies=migu_cookie))
|
||||
|
||||
elif record_url.find(".m3u8") > -1 or record_url.find(".flv") > -1:
|
||||
platform = '自定义录制直播'
|
||||
port_info = {
|
||||
@ -1765,6 +1771,7 @@ while True:
|
||||
taobao_cookie = read_config_value(config, 'Cookie', 'taobao_cookie', '')
|
||||
jd_cookie = read_config_value(config, 'Cookie', 'jd_cookie', '')
|
||||
faceit_cookie = read_config_value(config, 'Cookie', 'faceit_cookie', '')
|
||||
migu_cookie = read_config_value(config, 'Cookie', 'migu_cookie', '')
|
||||
|
||||
video_save_type_list = ("FLV", "MKV", "TS", "MP4", "MP3音频", "M4A音频")
|
||||
if video_save_type and video_save_type.upper() in video_save_type_list:
|
||||
@ -1882,7 +1889,9 @@ while True:
|
||||
'e.tb.cn',
|
||||
'huodong.m.taobao.com',
|
||||
'3.cn',
|
||||
'eco.m.jd.com'
|
||||
'eco.m.jd.com',
|
||||
'www.miguvideo.com',
|
||||
'm.miguvideo.com'
|
||||
]
|
||||
overseas_platform_host = [
|
||||
'www.tiktok.com',
|
||||
@ -1986,4 +1995,4 @@ while True:
|
||||
t2.start()
|
||||
first_run = False
|
||||
|
||||
time.sleep(3)
|
||||
time.sleep(3)
|
||||
143
src/javascript/migu.js
Normal file
143
src/javascript/migu.js
Normal file
@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Function to get the ddCalcu parameter value
|
||||
* @param {string} inputUrl - The original URL before encryption
|
||||
* @returns {Promise<string>} - Returns the calculated ddCalcu value
|
||||
*/
|
||||
async function getDdCalcu(inputUrl) {
|
||||
let wasmInstance = null;
|
||||
let memory_p = null; // Uint8Array view
|
||||
let memory_h = null; // Uint32Array view
|
||||
|
||||
// Fixed parameter
|
||||
const f = 'PBTxuWiTEbUPPFcpyxs0ww==';
|
||||
|
||||
// Utility function: Convert string to UTF-8 in memory
|
||||
function stringToUTF8(string, offset) {
|
||||
const encoder = new TextEncoder();
|
||||
const encoded = encoder.encode(string);
|
||||
for (let i = 0; i < encoded.length; i++) {
|
||||
memory_p[offset + i] = encoded[i];
|
||||
}
|
||||
memory_p[offset + encoded.length] = 0; // Null-terminate
|
||||
}
|
||||
|
||||
// Utility function: Read UTF-8 string from memory address
|
||||
function UTF8ToString(offset) {
|
||||
let s = '';
|
||||
let i = 0;
|
||||
while (memory_p[offset + i]) {
|
||||
s += String.fromCharCode(memory_p[offset + i]);
|
||||
i++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// WASM import function stubs
|
||||
function a(e, t, r, n) {
|
||||
let s = 0;
|
||||
for (let i = 0; i < r; i++) {
|
||||
const d = memory_h[t + 4 >> 2];
|
||||
t += 8;
|
||||
s += d;
|
||||
}
|
||||
memory_h[n >> 2] = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function b() {}
|
||||
|
||||
function c() {}
|
||||
|
||||
// Step 1: Retrieve playerVersion
|
||||
const settingsResp = await fetch('https://app-sc.miguvideo.com/common/v1/settings/H5_DetailPage');
|
||||
const settingsData = await settingsResp.json();
|
||||
const playerVersion = JSON.parse(settingsData.body.paramValue).playerVersion;
|
||||
|
||||
// Step 2: Load WASM module
|
||||
const wasmUrl = `https://www.miguvideo.com/mgs/player/prd/${playerVersion}/dist/mgprtcl.wasm`;
|
||||
const wasmResp = await fetch(wasmUrl);
|
||||
if (!wasmResp.ok) throw new Error("Failed to download WASM");
|
||||
const wasmBuffer = await wasmResp.arrayBuffer();
|
||||
|
||||
const importObject = {
|
||||
a: { a, b, c }
|
||||
};
|
||||
|
||||
const { instance } = await WebAssembly.instantiate(wasmBuffer, importObject);
|
||||
wasmInstance = instance;
|
||||
|
||||
const memory = wasmInstance.exports.d;
|
||||
memory_p = new Uint8Array(memory.buffer);
|
||||
memory_h = new Uint32Array(memory.buffer);
|
||||
|
||||
const exports = {
|
||||
CallInterface1: wasmInstance.exports.h,
|
||||
CallInterface2: wasmInstance.exports.i,
|
||||
CallInterface3: wasmInstance.exports.j,
|
||||
CallInterface4: wasmInstance.exports.k,
|
||||
CallInterface6: wasmInstance.exports.m,
|
||||
CallInterface7: wasmInstance.exports.n,
|
||||
CallInterface8: wasmInstance.exports.o,
|
||||
CallInterface9: wasmInstance.exports.p,
|
||||
CallInterface10: wasmInstance.exports.q,
|
||||
CallInterface11: wasmInstance.exports.r,
|
||||
CallInterface14: wasmInstance.exports.t,
|
||||
malloc: wasmInstance.exports.u,
|
||||
};
|
||||
|
||||
const parsedUrl = new URL(inputUrl);
|
||||
const query = Object.fromEntries(parsedUrl.searchParams);
|
||||
|
||||
const o = query.userid || '';
|
||||
const a_val = query.timestamp || '';
|
||||
const s = query.ProgramID || '';
|
||||
const u = query.Channel_ID || '';
|
||||
const v = query.puData || '';
|
||||
|
||||
// Allocate memory
|
||||
const d = exports.malloc(o.length + 1);
|
||||
const h = exports.malloc(a_val.length + 1);
|
||||
const y = exports.malloc(s.length + 1);
|
||||
const m = exports.malloc(u.length + 1);
|
||||
const g = exports.malloc(v.length + 1);
|
||||
const b_val = exports.malloc(f.length + 1);
|
||||
const E = exports.malloc(128);
|
||||
const T = exports.malloc(128);
|
||||
|
||||
// Write data to memory
|
||||
stringToUTF8(o, d);
|
||||
stringToUTF8(a_val, h);
|
||||
stringToUTF8(s, y);
|
||||
stringToUTF8(u, m);
|
||||
stringToUTF8(v, g);
|
||||
stringToUTF8(f, b_val);
|
||||
|
||||
// Call interface functions
|
||||
const S = exports.CallInterface6(); // Create context
|
||||
exports.CallInterface1(S, y, s.length);
|
||||
exports.CallInterface10(S, h, a_val.length);
|
||||
exports.CallInterface9(S, d, o.length);
|
||||
exports.CallInterface3(S, 0, 0);
|
||||
exports.CallInterface11(S, 0, 0);
|
||||
exports.CallInterface8(S, g, v.length);
|
||||
exports.CallInterface2(S, m, u.length);
|
||||
exports.CallInterface14(S, b_val, f.length, T, 128);
|
||||
|
||||
const w = UTF8ToString(T);
|
||||
const I = exports.malloc(w.length + 1);
|
||||
stringToUTF8(w, I);
|
||||
|
||||
exports.CallInterface7(S, I, w.length);
|
||||
exports.CallInterface4(S, E, 128);
|
||||
|
||||
return UTF8ToString(E);
|
||||
}
|
||||
|
||||
const url = process.argv[2];
|
||||
|
||||
getDdCalcu(url).then(result => {
|
||||
console.log(result);
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@ -4,14 +4,16 @@
|
||||
Author: Hmily
|
||||
GitHub: https://github.com/ihmily
|
||||
Date: 2023-07-15 23:15:00
|
||||
Update: 2025-06-14 12:19:00
|
||||
Update: 2025-07-04 17:23:00
|
||||
Copyright (c) 2023-2025 by Hmily, All Rights Reserved.
|
||||
Function: Get live stream data.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import random
|
||||
import subprocess
|
||||
import time
|
||||
import uuid
|
||||
from operator import itemgetter
|
||||
import urllib.parse
|
||||
import urllib.error
|
||||
@ -3016,4 +3018,77 @@ async def get_faceit_stream_data(url: str, proxy_addr: OptionalStr = None, cooki
|
||||
result['anchor_name'] = anchor_name
|
||||
else:
|
||||
result = {'anchor_name': anchor_name, 'is_live': False}
|
||||
return result
|
||||
return result
|
||||
|
||||
|
||||
@trace_error_decorator
|
||||
async def get_migu_stream_url(url: str, proxy_addr: OptionalStr = None, cookies: OptionalStr = None) -> dict:
|
||||
headers = {
|
||||
'origin': 'https://www.miguvideo.com',
|
||||
'referer': 'https://www.miguvideo.com/',
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
|
||||
'Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0',
|
||||
'appCode': 'miguvideo_default_www',
|
||||
'appId': 'miguvideo',
|
||||
'channel': 'H5',
|
||||
}
|
||||
|
||||
if cookies:
|
||||
headers['Cookie'] = cookies
|
||||
|
||||
web_id = url.split('?')[0].rsplit('/')[-1]
|
||||
api = f'https://vms-sc.miguvideo.com/vms-match/v6/staticcache/basic/basic-data/{web_id}/miguvideo'
|
||||
json_str = await async_req(api, proxy_addr=proxy_addr, headers=headers)
|
||||
json_data = json.loads(json_str)
|
||||
room_id = json_data['body']['pId']
|
||||
anchor_name = json_data['body']['title']
|
||||
live_title = json_data['body'].get('title') + '-' + json_data['body'].get('detailPageTitle', '')
|
||||
|
||||
result = {"anchor_name": anchor_name, "is_live": False}
|
||||
if not room_id:
|
||||
raise RuntimeError("Room ID fetch error")
|
||||
params = {
|
||||
'contId': room_id,
|
||||
'rateType': '3',
|
||||
'clientId': str(uuid.uuid4()),
|
||||
'timestamp': int(time.time() * 1000),
|
||||
'flvEnable': 'true',
|
||||
'xh265': 'false',
|
||||
'chip': 'mgwww',
|
||||
'channelId': '',
|
||||
}
|
||||
|
||||
api = f'https://webapi.miguvideo.com/gateway/playurl/v3/play/playurl?{urllib.parse.urlencode(params)}'
|
||||
json_str = await async_req(api, proxy_addr=proxy_addr, headers=headers)
|
||||
json_data = json.loads(json_str)
|
||||
live_status = json_data['body']['content']['currentLive']
|
||||
if live_status != '1':
|
||||
return result
|
||||
else:
|
||||
result['title'] = live_title
|
||||
source_url = json_data['body']['urlInfo']['url']
|
||||
|
||||
async def _get_dd_calcu(url):
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["node", f"{JS_SCRIPT_PATH}/migu.js", url],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except execjs.ProgramError:
|
||||
raise execjs.ProgramError('Failed to execute JS code. Please check if the Node.js environment')
|
||||
|
||||
ddCalcu = await _get_dd_calcu(source_url)
|
||||
real_source_url = f'{source_url}&ddCalcu={ddCalcu}&sv=10010'
|
||||
if '.m3u8' in real_source_url:
|
||||
m3u8_url = await async_req(
|
||||
real_source_url, proxy_addr=proxy_addr, headers=headers, redirect_url=True)
|
||||
result['m3u8_url'] = m3u8_url
|
||||
result['record_url'] = m3u8_url
|
||||
else:
|
||||
result['flv_url'] = real_source_url
|
||||
result['record_url'] = real_source_url
|
||||
result['is_live'] = True
|
||||
return result
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user