mirror of
https://gh-proxy.org/https://github.com/tiajinsha/JKVideo
synced 2026-07-07 23:18:38 +08:00
1
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
import axios from 'axios';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { Platform } from 'react-native';
|
||||
import pako from 'pako';
|
||||
import type { VideoItem, Comment, PlayUrlResponse, QRCodeInfo, VideoShotData, HeatmapResponse, DanmakuItem } from './types';
|
||||
import { signWbi } from '../utils/wbi';
|
||||
import { parseDanmakuXml } from '../utils/danmaku';
|
||||
|
||||
const isWeb = Platform.OS === 'web';
|
||||
const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
||||
const BASE = isWeb ? 'http://localhost:3001/bilibili-api' : 'https://api.bilibili.com';
|
||||
const BASE = isWeb ? 'http://localhost:3001/bilibili-api' : 'https://api.bilibili.com';
|
||||
const PASSPORT = isWeb ? 'http://localhost:3001/bilibili-passport' : 'https://passport.bilibili.com';
|
||||
const COMMENT_BASE = isWeb
|
||||
? 'http://localhost:3001/bilibili-comment'
|
||||
@@ -32,13 +33,13 @@ const api = axios.create({
|
||||
baseURL: BASE,
|
||||
timeout: 10000,
|
||||
headers: isWeb ? {
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||
} : {
|
||||
'User-Agent': UA,
|
||||
'Referer': 'https://www.bilibili.com',
|
||||
'Origin': 'https://www.bilibili.com',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'User-Agent': UA,
|
||||
'Referer': 'https://www.bilibili.com',
|
||||
'Origin': 'https://www.bilibili.com',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||
},
|
||||
});
|
||||
@@ -50,7 +51,7 @@ api.interceptors.request.use(async (config) => {
|
||||
]);
|
||||
if (isWeb) {
|
||||
// Browsers block Cookie/Referer/Origin headers; relay via custom headers to proxy
|
||||
if (buvid3) config.headers['X-Buvid3'] = buvid3;
|
||||
if (buvid3) config.headers['X-Buvid3'] = buvid3;
|
||||
if (sessdata) config.headers['X-Sessdata'] = sessdata;
|
||||
} else {
|
||||
const cookies: string[] = [`buvid3=${buvid3}`];
|
||||
@@ -75,7 +76,7 @@ async function getWbiKeys(): Promise<{ imgKey: string; subKey: string }> {
|
||||
export async function getRecommendFeed(freshIdx = 0): Promise<VideoItem[]> {
|
||||
const { imgKey, subKey } = await getWbiKeys();
|
||||
const signed = signWbi(
|
||||
{ fresh_type: 3, fresh_idx: freshIdx, fresh_idx_1h: freshIdx, ps: 12, feed_version: 'V8' },
|
||||
{ fresh_type: 3, fresh_idx: freshIdx, fresh_idx_1h: freshIdx, ps: 21, feed_version: 'V8' },
|
||||
imgKey,
|
||||
subKey,
|
||||
);
|
||||
@@ -87,8 +88,7 @@ export async function getRecommendFeed(freshIdx = 0): Promise<VideoItem[]> {
|
||||
aid: item.id ?? item.aid,
|
||||
pic: item.pic ?? item.cover,
|
||||
owner: item.owner ?? { mid: 0, name: item.owner_info?.name ?? '', face: item.owner_info?.face ?? '' },
|
||||
}))
|
||||
.filter((item: any) => item.bvid && (item.pic || item.cover) && item.duration > 0) as VideoItem[];
|
||||
})) as VideoItem[];
|
||||
}
|
||||
|
||||
export async function getPopularVideos(pn = 1): Promise<VideoItem[]> {
|
||||
@@ -172,12 +172,44 @@ export async function pollQRCode(qrcode_key: string): Promise<{ code: number; co
|
||||
return { code, cookie };
|
||||
}
|
||||
|
||||
|
||||
export async function getDanmaku(cid: number): Promise<DanmakuItem[]> {
|
||||
try {
|
||||
if (isWeb) {
|
||||
// web 走代理,代理已解压,直接拿文本
|
||||
const res = await axios.get(`${COMMENT_BASE}/${cid}.xml`, {
|
||||
headers: {},
|
||||
responseType: 'text',
|
||||
});
|
||||
return parseDanmakuXml(res.data);
|
||||
}
|
||||
|
||||
// Native 策略 1:responseType: 'text',依赖 OkHttp 自动解压
|
||||
const res = await axios.get(`${COMMENT_BASE}/${cid}.xml`, {
|
||||
headers: isWeb ? {} : { Referer: 'https://www.bilibili.com', 'User-Agent': UA },
|
||||
headers: { Referer: 'https://www.bilibili.com', 'User-Agent': UA },
|
||||
responseType: 'text',
|
||||
});
|
||||
return parseDanmakuXml(res.data as string);
|
||||
} catch { return []; }
|
||||
|
||||
if (typeof res.data === 'string' && res.data.includes('<d ')) {
|
||||
return parseDanmakuXml(res.data);
|
||||
}
|
||||
|
||||
// 策略 2 回退:arraybuffer + pako 手动解压
|
||||
const res2 = await axios.get(`${COMMENT_BASE}/${cid}.xml`, {
|
||||
headers: { Referer: 'https://www.bilibili.com', 'User-Agent': UA },
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
|
||||
const bytes = new Uint8Array(res2.data as ArrayBuffer);
|
||||
let xmlText: string;
|
||||
if (bytes[0] === 0x1f && bytes[1] === 0x8b) {
|
||||
xmlText = pako.inflate(bytes, { to: 'string' });
|
||||
} else {
|
||||
xmlText = new TextDecoder('utf-8').decode(bytes);
|
||||
}
|
||||
return parseDanmakuXml(xmlText);
|
||||
} catch (e) {
|
||||
console.warn('getDanmaku failed:', e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user