113 lines
3.5 KiB
TypeScript
113 lines
3.5 KiB
TypeScript
import { Template } from '@/lib/types/template';
|
||
|
||
export const VIDEO_EXTENSIONS = ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv', 'flv'];
|
||
export const IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'];
|
||
|
||
/**
|
||
* 验证媒体URL是否有效
|
||
*/
|
||
export const isValidMediaUrl = (url: string): boolean => {
|
||
if (!url || url.trim() === '') return false;
|
||
|
||
try {
|
||
new URL(url);
|
||
return true;
|
||
} catch {
|
||
// 如果不是有效的URL格式,检查是否是相对路径
|
||
return url.startsWith('/') || url.startsWith('./') || url.startsWith('../');
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 获取媒体类型:video 或 image
|
||
*/
|
||
export const getMediaType = (template: Template): 'video' | 'image' => {
|
||
// 1. 优先检查 previewUrl 的文件扩展名
|
||
if (template.previewUrl && isValidMediaUrl(template.previewUrl)) {
|
||
const previewUrl = template.previewUrl.toLowerCase();
|
||
|
||
// 检查是否为视频文件
|
||
const videoMatch = new RegExp(`\\.(${VIDEO_EXTENSIONS.join('|')})$`).test(previewUrl);
|
||
if (videoMatch) {
|
||
console.log(`"${template.title}" 通过previewUrl扩展名识别为视频: ${template.previewUrl}`);
|
||
return 'video';
|
||
}
|
||
|
||
// 检查是否为图片文件
|
||
const imageMatch = new RegExp(`\\.(${IMAGE_EXTENSIONS.join('|')})$`).test(previewUrl);
|
||
if (imageMatch) {
|
||
console.log(`"${template.title}" 通过previewUrl扩展名识别为图片: ${template.previewUrl}`);
|
||
return 'image';
|
||
}
|
||
}
|
||
|
||
// 2. 检查 coverImageUrl 的文件扩展名
|
||
if (template.coverImageUrl && isValidMediaUrl(template.coverImageUrl)) {
|
||
const coverImageUrl = template.coverImageUrl.toLowerCase();
|
||
const imageMatch = new RegExp(`\\.(${IMAGE_EXTENSIONS.join('|')})$`).test(coverImageUrl);
|
||
if (imageMatch) {
|
||
console.log(`"${template.title}" 通过coverImageUrl扩展名识别为图片: ${template.coverImageUrl}`);
|
||
return 'image';
|
||
}
|
||
}
|
||
|
||
// 3. 根据 previewUrl 是否存在来推断类型
|
||
if (template.previewUrl && template.previewUrl.trim() !== '') {
|
||
console.log(`"${template.title}" 通过previewUrl存在性推断为视频: ${template.previewUrl}`);
|
||
return 'video';
|
||
}
|
||
|
||
// 4. 如果有coverImageUrl,默认为图片
|
||
if (template.coverImageUrl && template.coverImageUrl.trim() !== '') {
|
||
console.log(`"${template.title}" 通过coverImageUrl存在性推断为图片: ${template.coverImageUrl}`);
|
||
return 'image';
|
||
}
|
||
|
||
// 5. 默认为图片
|
||
console.log(`"${template.title}" 无法确定类型,默认为图片`);
|
||
return 'image';
|
||
};
|
||
|
||
/**
|
||
* 判断模板是否为视频类型(带日志)
|
||
*/
|
||
export const isVideoTemplate = (template: Template): boolean => {
|
||
const mediaType = getMediaType(template);
|
||
return mediaType === 'video';
|
||
};
|
||
|
||
/**
|
||
* 判断模板是否为图片类型(带日志)
|
||
*/
|
||
export const isImageTemplate = (template: Template): boolean => {
|
||
const mediaType = getMediaType(template);
|
||
return mediaType === 'image';
|
||
};
|
||
|
||
/**
|
||
* 获取有效的媒体URL
|
||
*/
|
||
export const getEffectiveMediaUrl = (template: Template): string => {
|
||
const mediaType = getMediaType(template);
|
||
|
||
if (mediaType === 'video') {
|
||
return template.previewUrl || '';
|
||
} else {
|
||
return template.coverImageUrl || '';
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 检查媒体URL是否有效且可以加载
|
||
*/
|
||
export const canLoadMedia = (template: Template): boolean => {
|
||
const mediaType = getMediaType(template);
|
||
const url = getEffectiveMediaUrl(template);
|
||
|
||
if (!url || !isValidMediaUrl(url)) {
|
||
console.warn(`模板 "${template.title}" 的${mediaType}URL无效:`, url);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}; |