mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-12 23:33:43 +08:00
Make source badges numeric only
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { extractPlaybackQualityLabel } from '@/lib/utils/video';
|
||||
import { extractNumericResolutionLabel } from '@/lib/utils/video';
|
||||
|
||||
export interface ResolutionProbeLabel {
|
||||
label: string;
|
||||
@@ -8,27 +8,22 @@ export interface ResolutionProbeLabel {
|
||||
}
|
||||
|
||||
const QUALITY_RANK: Record<string, number> = {
|
||||
'8K': 780,
|
||||
'4K': 700,
|
||||
'2K': 620,
|
||||
'1080P': 540,
|
||||
'蓝光': 520,
|
||||
'HDR': 500,
|
||||
'超清': 480,
|
||||
'720P': 420,
|
||||
'WEB-DL': 380,
|
||||
'HDTV': 360,
|
||||
'高清': 340,
|
||||
'540P': 300,
|
||||
'DVD': 280,
|
||||
'480P': 260,
|
||||
'360P': 220,
|
||||
'TS': 120,
|
||||
'SD': 100,
|
||||
'240P': 180,
|
||||
'144P': 160,
|
||||
};
|
||||
|
||||
const DIMENSION_PATTERN = /(\d{3,4})\s*[xX]\s*(\d{3,4})/g;
|
||||
const HLS_RESOLUTION_PATTERN = /RESOLUTION=(\d+)x(\d+)/gi;
|
||||
const TEXT_QUALITY_PATTERNS: Array<{ pattern: RegExp; width?: number; height?: number; label: string; color: string }> = [
|
||||
{ pattern: /(?:^|[^\d])(4320p?|8k)(?:[^\d]|$)/i, width: 7680, height: 4320, label: '8K', color: 'bg-rose-500' },
|
||||
{ pattern: /(?:^|[^\d])(2160p?|4k|uhd)(?:[^\d]|$)/i, width: 3840, height: 2160, label: '4K', color: 'bg-amber-500' },
|
||||
{ pattern: /(?:^|[^\d])(1440p?|2k|qhd)(?:[^\d]|$)/i, width: 2560, height: 1440, label: '2K', color: 'bg-emerald-500' },
|
||||
{ pattern: /(?:^|[^\d])(1080p?|1080i|fhd|fullhd|full-hd)(?:[^\d]|$)/i, width: 1920, height: 1080, label: '1080P', color: 'bg-green-500' },
|
||||
@@ -36,12 +31,15 @@ const TEXT_QUALITY_PATTERNS: Array<{ pattern: RegExp; width?: number; height?: n
|
||||
{ pattern: /(?:^|[^\d])540p?(?:[^\d]|$)/i, width: 960, height: 540, label: '540P', color: 'bg-cyan-500' },
|
||||
{ pattern: /(?:^|[^\d])480p?(?:[^\d]|$)/i, width: 854, height: 480, label: '480P', color: 'bg-sky-500' },
|
||||
{ pattern: /(?:^|[^\d])360p?(?:[^\d]|$)/i, width: 640, height: 360, label: '360P', color: 'bg-gray-500' },
|
||||
{ pattern: /(?:^|[^\d])240p?(?:[^\d]|$)/i, width: 426, height: 240, label: '240P', color: 'bg-gray-500' },
|
||||
{ pattern: /(?:^|[^\d])144p?(?:[^\d]|$)/i, width: 256, height: 144, label: '144P', color: 'bg-gray-500' },
|
||||
];
|
||||
|
||||
export function getResolutionLabel(width: number, height: number): ResolutionProbeLabel {
|
||||
const normalizedWidth = Math.max(width, height);
|
||||
const normalizedHeight = Math.min(width, height);
|
||||
|
||||
if (normalizedHeight >= 4320) return { width: normalizedWidth, height: normalizedHeight, label: '8K', color: 'bg-rose-500' };
|
||||
if (normalizedHeight >= 2160) return { width: normalizedWidth, height: normalizedHeight, label: '4K', color: 'bg-amber-500' };
|
||||
if (normalizedHeight >= 1440) return { width: normalizedWidth, height: normalizedHeight, label: '2K', color: 'bg-emerald-500' };
|
||||
if (normalizedHeight >= 1080) return { width: normalizedWidth, height: normalizedHeight, label: '1080P', color: 'bg-green-500' };
|
||||
@@ -49,6 +47,8 @@ export function getResolutionLabel(width: number, height: number): ResolutionPro
|
||||
if (normalizedHeight >= 540) return { width: normalizedWidth, height: normalizedHeight, label: '540P', color: 'bg-cyan-500' };
|
||||
if (normalizedHeight >= 480) return { width: normalizedWidth, height: normalizedHeight, label: '480P', color: 'bg-sky-500' };
|
||||
if (normalizedHeight >= 360) return { width: normalizedWidth, height: normalizedHeight, label: '360P', color: 'bg-gray-500' };
|
||||
if (normalizedHeight >= 240) return { width: normalizedWidth, height: normalizedHeight, label: '240P', color: 'bg-gray-500' };
|
||||
if (normalizedHeight >= 144) return { width: normalizedWidth, height: normalizedHeight, label: '144P', color: 'bg-gray-500' };
|
||||
return { width: normalizedWidth, height: normalizedHeight, label: `${normalizedHeight}P`, color: 'bg-gray-500' };
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ export function extractResolutionHint(...values: Array<string | undefined>): Res
|
||||
});
|
||||
}
|
||||
|
||||
best = chooseHigherQuality(best, extractPlaybackQualityLabel(value) || null);
|
||||
best = chooseHigherQuality(best, extractNumericResolutionLabel(value) || null);
|
||||
}
|
||||
|
||||
return best;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { extractPlaybackQualityLabel } from '@/lib/utils/video';
|
||||
import { extractNumericResolutionLabel } from '@/lib/utils/video';
|
||||
|
||||
export interface ResolutionBadge {
|
||||
label: string;
|
||||
@@ -42,5 +42,5 @@ export function getSourceResolutionBadge(options: {
|
||||
return { label: cachedResolution.label, color: cachedResolution.color };
|
||||
}
|
||||
|
||||
return extractPlaybackQualityLabel(remarks) || null;
|
||||
return extractNumericResolutionLabel(remarks) || null;
|
||||
}
|
||||
|
||||
+26
-23
@@ -27,39 +27,35 @@ export function parseVideoTitle(title: string): { cleanTitle: string, quality?:
|
||||
}
|
||||
|
||||
/**
|
||||
* Quality keywords and their display labels, ordered by priority (highest first).
|
||||
* Numeric resolution keywords only.
|
||||
* Qualitative labels such as "蓝光" or "高清" are intentionally excluded because
|
||||
* they are not real numeric resolutions.
|
||||
*/
|
||||
const PLAYBACK_QUALITY_PATTERNS: { pattern: RegExp; label: string; color: string }[] = [
|
||||
{ pattern: /4k|2160p|uhd/i, label: '4K', color: 'bg-amber-500' },
|
||||
{ pattern: /2k|1440p|qhd/i, label: '2K', color: 'bg-emerald-500' },
|
||||
{ pattern: /蓝光|藍光|bluray|blu-ray|remux/i, label: '蓝光', color: 'bg-blue-500' },
|
||||
{ pattern: /\bhdr\b|hdr10\+?/i, label: 'HDR', color: 'bg-violet-500' },
|
||||
{ pattern: /1080p|1080i|full\s*hd|fhd/i, label: '1080P', color: 'bg-green-500' },
|
||||
{ pattern: /超清|超高清/i, label: '超清', color: 'bg-green-500' },
|
||||
{ pattern: /540p/i, label: '540P', color: 'bg-cyan-500' },
|
||||
{ pattern: /720p|hd720/i, label: '720P', color: 'bg-teal-500' },
|
||||
{ pattern: /480p/i, label: '480P', color: 'bg-sky-500' },
|
||||
{ pattern: /360p/i, label: '360P', color: 'bg-gray-500' },
|
||||
{ pattern: /高清|流畅/i, label: '高清', color: 'bg-sky-500' },
|
||||
{ pattern: /web-?dl|webrip/i, label: 'WEB-DL', color: 'bg-indigo-500' },
|
||||
{ pattern: /hdtv/i, label: 'HDTV', color: 'bg-teal-500' },
|
||||
{ pattern: /dvd|dvdrip/i, label: 'DVD', color: 'bg-purple-500' },
|
||||
{ pattern: /抢先|枪版|ts版|(?:^|[\s([【_-])(ts|cam|hdts)(?:$|[\s)\]】_-])|预告/i, label: 'TS', color: 'bg-orange-500' },
|
||||
{ pattern: /标清|(?:^|[\s([【_-])sd(?:$|[\s)\]】_-])/i, label: 'SD', color: 'bg-gray-500' },
|
||||
const NUMERIC_RESOLUTION_PATTERNS: { pattern: RegExp; label: string; color: string }[] = [
|
||||
{ pattern: /(?:^|[^\d])(4320p?|8k)(?:[^\d]|$)/i, label: '8K', color: 'bg-rose-500' },
|
||||
{ pattern: /(?:^|[^\d])(2160p?|4k|uhd)(?:[^\d]|$)/i, label: '4K', color: 'bg-amber-500' },
|
||||
{ pattern: /(?:^|[^\d])(1440p?|2k|qhd)(?:[^\d]|$)/i, label: '2K', color: 'bg-emerald-500' },
|
||||
{ pattern: /(?:^|[^\d])(1080p?|1080i|full\s*hd|fhd)(?:[^\d]|$)/i, label: '1080P', color: 'bg-green-500' },
|
||||
{ pattern: /(?:^|[^\d])720p?(?:[^\d]|$)|hd720/i, label: '720P', color: 'bg-teal-500' },
|
||||
{ pattern: /(?:^|[^\d])540p?(?:[^\d]|$)/i, label: '540P', color: 'bg-cyan-500' },
|
||||
{ pattern: /(?:^|[^\d])480p?(?:[^\d]|$)/i, label: '480P', color: 'bg-sky-500' },
|
||||
{ pattern: /(?:^|[^\d])360p?(?:[^\d]|$)/i, label: '360P', color: 'bg-gray-500' },
|
||||
{ pattern: /(?:^|[^\d])240p?(?:[^\d]|$)/i, label: '240P', color: 'bg-gray-500' },
|
||||
{ pattern: /(?:^|[^\d])144p?(?:[^\d]|$)/i, label: '144P', color: 'bg-gray-500' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Extracts a playback quality label from video remarks or title.
|
||||
* This intentionally excludes language, subtitle, and audio labels.
|
||||
* Extracts a numeric playback resolution from video remarks or title.
|
||||
* Non-numeric labels are intentionally ignored.
|
||||
*/
|
||||
export function extractPlaybackQualityLabel(
|
||||
export function extractNumericResolutionLabel(
|
||||
remarks?: string,
|
||||
quality?: string
|
||||
): { label: string; color: string } | null {
|
||||
const text = `${remarks || ''} ${quality || ''}`;
|
||||
if (!text.trim()) return null;
|
||||
|
||||
for (const { pattern, label, color } of PLAYBACK_QUALITY_PATTERNS) {
|
||||
for (const { pattern, label, color } of NUMERIC_RESOLUTION_PATTERNS) {
|
||||
if (pattern.test(text)) {
|
||||
return { label, color };
|
||||
}
|
||||
@@ -68,6 +64,13 @@ export function extractPlaybackQualityLabel(
|
||||
return null;
|
||||
}
|
||||
|
||||
export function extractPlaybackQualityLabel(
|
||||
remarks?: string,
|
||||
quality?: string
|
||||
): { label: string; color: string } | null {
|
||||
return extractNumericResolutionLabel(remarks, quality);
|
||||
}
|
||||
|
||||
export function extractQualityLabel(remarks?: string, quality?: string): { label: string; color: string } | null {
|
||||
return extractPlaybackQualityLabel(remarks, quality);
|
||||
return extractNumericResolutionLabel(remarks, quality);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user