Files
KVideo/components/player/hooks/useVideoResolution.ts
T
kuekhaoyang 0e87c94a64 feat: 修复超长 URL (414) 问题,添加分辨率检测,修复高级模式 bug,提升兼容性
- 将 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
2026-03-12 22:58:30 +08:00

67 lines
2.1 KiB
TypeScript

import { useState, useEffect } from 'react';
/**
* Maps video resolution height to a human-readable quality label.
*/
function getResolutionLabel(width: number, height: number): { label: string; color: string } | null {
if (width === 0 || height === 0) return null;
// Use the larger dimension in case of portrait video
const h = Math.max(width, height) === width ? height : width;
if (h >= 2160) return { label: '4K', color: 'bg-amber-500' };
if (h >= 1440) return { label: '2K', color: 'bg-emerald-500' };
if (h >= 1080) return { label: '1080P', color: 'bg-green-500' };
if (h >= 720) return { label: '720P', color: 'bg-teal-500' };
if (h >= 480) return { label: '480P', color: 'bg-sky-500' };
if (h >= 360) return { label: '360P', color: 'bg-gray-500' };
return { label: `${h}P`, color: 'bg-gray-500' };
}
export interface VideoResolutionInfo {
width: number;
height: number;
label: string;
color: string;
}
/**
* Detects the actual video resolution from the <video> element
* after metadata is loaded.
*/
export function useVideoResolution(videoRef: React.RefObject<HTMLVideoElement | null>): VideoResolutionInfo | null {
const [resolution, setResolution] = useState<VideoResolutionInfo | null>(null);
useEffect(() => {
const video = videoRef.current;
if (!video) return;
const detectResolution = () => {
const w = video.videoWidth;
const h = video.videoHeight;
if (w > 0 && h > 0) {
const info = getResolutionLabel(w, h);
if (info) {
setResolution({ width: w, height: h, ...info });
}
}
};
// Detect on loadedmetadata and also on resize (quality change)
video.addEventListener('loadedmetadata', detectResolution);
video.addEventListener('resize', detectResolution);
// Check if already loaded
if (video.videoWidth > 0 && video.videoHeight > 0) {
detectResolution();
}
return () => {
video.removeEventListener('loadedmetadata', detectResolution);
video.removeEventListener('resize', detectResolution);
};
}, [videoRef]);
return resolution;
}