infio-copilot-dev/src/utils/video-detector.ts
2025-06-07 17:13:02 +08:00

143 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 视频平台URL检测工具
* 支持多种主流视频平台的URL识别
*/
// 各种视频平台的正则表达式
const VIDEO_PATTERNS = {
// YouTube
youtube: /(?:youtube\.com\/(?:[^/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?/\s]{11})/i,
// Bilibili
bilibili: /(?:bilibili\.com\/video\/|b23\.tv\/)[A-Za-z0-9]+/i,
// Vimeo
vimeo: /(?:vimeo\.com\/)([0-9]+)/i,
// Dailymotion
dailymotion: /(?:dailymotion\.com\/video\/|dai\.ly\/)([A-Za-z0-9]+)/i,
// TikTok
tiktok: /(?:tiktok\.com\/@[^/]+\/video\/|vm\.tiktok\.com\/)[A-Za-z0-9]+/i,
// Twitch
twitch: /(?:twitch\.tv\/videos\/|clips\.twitch\.tv\/)[A-Za-z0-9]+/i,
// 腾讯视频
tencent: /(?:v\.qq\.com\/x\/cover\/|v\.qq\.com\/x\/page\/)[A-Za-z0-9]+/i,
// 爱奇艺
iqiyi: /(?:iqiyi\.com\/v_)[A-Za-z0-9]+/i,
// 优酷
youku: /(?:youku\.com\/v_show\/id_)[A-Za-z0-9]+/i,
// Facebook/Meta
facebook: /(?:facebook\.com\/watch\/|fb\.watch\/)[A-Za-z0-9]+/i,
// Instagram
instagram: /(?:instagram\.com\/(?:p|reel)\/)[A-Za-z0-9_-]+/i,
// Twitter/X
twitter: /(?:twitter\.com\/[^/]+\/status\/|x\.com\/[^/]+\/status\/)[0-9]+/i,
// 抖音
douyin: /(?:douyin\.com\/video\/)[0-9]+/i,
// 快手
kuaishou: /(?:kuaishou\.com\/short-video\/)[A-Za-z0-9]+/i,
// 小红书
xiaohongshu: /(?:xiaohongshu\.com\/explore\/)[A-Za-z0-9]+/i,
// 微博视频
weibo: /(?:weibo\.com\/[^/]+\/[A-Za-z0-9]+|weibo\.cn\/sinaurl)/i,
// Rumble
rumble: /(?:rumble\.com\/)[A-Za-z0-9_-]+/i,
// Odysee
odysee: /(?:odysee\.com\/@[^/]+\/)[A-Za-z0-9_-]+/i,
// JW Player (通用嵌入式播放器)
jwplayer: /(?:jwplayer\.com\/players\/)[A-Za-z0-9_-]+/i,
// 通用视频文件扩展名
videoFile: /\.(mp4|avi|mov|wmv|flv|webm|mkv|m4v|3gp|ogv)(\?.*)?$/i,
// 通用视频流媒体
streaming: /(?:stream|live|video|watch|play).*\.(m3u8|mpd|f4m)(\?.*)?$/i
}
export type VideoProvider = keyof typeof VIDEO_PATTERNS
/**
* 检测URL是否为视频内容
* @param url 要检测的URL
* @returns 是否为视频URL
*/
export function isVideoUrl(url: string): boolean {
return Object.values(VIDEO_PATTERNS).some(pattern => pattern.test(url))
}
/**
* 检测URL属于哪个视频平台
* @param url 要检测的URL
* @returns 视频平台名称如果不是视频URL则返回null
*/
export function getVideoProvider(url: string): VideoProvider | null {
for (const [provider, pattern] of Object.entries(VIDEO_PATTERNS)) {
if (pattern.test(url)) {
return provider as VideoProvider
}
}
return null
}
/**
* 检测特定平台的视频URL
* @param url 要检测的URL
* @param provider 视频平台
* @returns 是否为指定平台的视频URL
*/
export function isVideoUrlFromProvider(url: string, provider: VideoProvider): boolean {
const pattern = VIDEO_PATTERNS[provider]
return pattern ? pattern.test(url) : false
}
/**
* 从URL中提取视频ID如果可能
* @param url 视频URL
* @returns 视频ID或null
*/
export function extractVideoId(url: string): string | null {
const provider = getVideoProvider(url)
if (!provider) return null
const pattern = VIDEO_PATTERNS[provider]
const match = url.match(pattern)
// 返回第一个捕获组(如果存在)
return match && match[1] ? match[1] : null
}
/**
* 获取支持的视频平台列表
* @returns 支持的视频平台名称数组
*/
export function getSupportedVideoProviders(): VideoProvider[] {
return Object.keys(VIDEO_PATTERNS) as VideoProvider[]
}
// 为了向后兼容保留原有的YouTube检测函数
export function isYoutubeUrl(url: string): boolean {
return isVideoUrlFromProvider(url, 'youtube')
}
// 导出常用的视频平台检测函数
export const isYouTubeUrl = isYoutubeUrl // 别名
export const isBilibiliUrl = (url: string) => isVideoUrlFromProvider(url, 'bilibili')
export const isVimeoUrl = (url: string) => isVideoUrlFromProvider(url, 'vimeo')
export const isTikTokUrl = (url: string) => isVideoUrlFromProvider(url, 'tiktok')
export const isTwitchUrl = (url: string) => isVideoUrlFromProvider(url, 'twitch')