mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-06-09 01:42:15 +08:00
- 将 groupedSources 存储在 sessionStorage 中而非 URL 参数里,以防止因 URL 过长导致的 CDN 414 错误 (#112) - 自动将旧版 groupedSources URL 迁移至短 gs 键 - 从视频元素中检测并显示实际视频分辨率(例如 1920x1080),不再依赖来源提供的标签 - 修复 PlayerNavbar 设置链接在高级模式下总是跳转到 /settings 而非 /premium/settings 的问题 (#106) - 修复 WatchHistorySidebar 未向 HistoryList 传递 isPremium,导致历史记录项 URL 丢失 premium=1 参数的问题 (#106) - 为 HLS 播放添加多级浏览器回退机制 (HLS.js → 原生 → 代理 → 错误并提供浏览器建议) (#104) - 在 IPTV 播放器中添加 HEVC/H.265 级别过滤,防止 CCTV 等频道出现仅有音频播放的问题 (#81) - 更新依赖并升级版本至 4.5.0
86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
/**
|
|
* Grouped Sources Cache
|
|
* Stores groupedSources data in sessionStorage to avoid extremely long URLs
|
|
* that cause HTTP 414 errors on CDNs (e.g., Cloudflare, AWS CloudFront).
|
|
*
|
|
* Instead of passing the full JSON array in the URL parameter,
|
|
* we store it in sessionStorage and pass a short key in the URL.
|
|
*/
|
|
|
|
const CACHE_PREFIX = 'gs:';
|
|
const MAX_CACHE_SIZE = 100;
|
|
|
|
/**
|
|
* Store grouped sources data and return a short cache key.
|
|
*/
|
|
export function storeGroupedSources(data: any[]): string {
|
|
if (typeof window === 'undefined') return '';
|
|
|
|
const key = generateKey();
|
|
try {
|
|
// Cleanup old entries if too many
|
|
cleanupOldEntries();
|
|
sessionStorage.setItem(
|
|
`${CACHE_PREFIX}${key}`,
|
|
JSON.stringify({ data, ts: Date.now() })
|
|
);
|
|
} catch {
|
|
// sessionStorage full or unavailable — fall back gracefully
|
|
}
|
|
return key;
|
|
}
|
|
|
|
/**
|
|
* Retrieve grouped sources data by cache key.
|
|
*/
|
|
export function retrieveGroupedSources(key: string): any[] | null {
|
|
if (typeof window === 'undefined' || !key) return null;
|
|
try {
|
|
const raw = sessionStorage.getItem(`${CACHE_PREFIX}${key}`);
|
|
if (!raw) return null;
|
|
const parsed = JSON.parse(raw);
|
|
return parsed?.data || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate a short random key (8 chars, base36).
|
|
*/
|
|
function generateKey(): string {
|
|
return Math.random().toString(36).slice(2, 10);
|
|
}
|
|
|
|
/**
|
|
* Remove oldest entries when cache exceeds max size.
|
|
*/
|
|
function cleanupOldEntries(): void {
|
|
try {
|
|
const entries: { key: string; ts: number }[] = [];
|
|
for (let i = 0; i < sessionStorage.length; i++) {
|
|
const key = sessionStorage.key(i);
|
|
if (key?.startsWith(CACHE_PREFIX)) {
|
|
try {
|
|
const raw = sessionStorage.getItem(key);
|
|
const parsed = raw ? JSON.parse(raw) : null;
|
|
entries.push({ key, ts: parsed?.ts || 0 });
|
|
} catch {
|
|
entries.push({ key, ts: 0 });
|
|
}
|
|
}
|
|
}
|
|
|
|
if (entries.length >= MAX_CACHE_SIZE) {
|
|
// Sort by timestamp ascending and remove oldest half
|
|
entries.sort((a, b) => a.ts - b.ts);
|
|
const toRemove = entries.slice(0, Math.floor(entries.length / 2));
|
|
for (const entry of toRemove) {
|
|
sessionStorage.removeItem(entry.key);
|
|
}
|
|
}
|
|
} catch {
|
|
// Ignore cleanup errors
|
|
}
|
|
}
|