This commit is contained in:
imeepos
2025-10-21 10:21:45 +08:00
parent 7e3f94bae3
commit 3a99ff96d5
28 changed files with 6981 additions and 176 deletions

113
utils/media-utils.ts Normal file
View File

@@ -0,0 +1,113 @@
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;
};