feat: 客户分享链接列表

This commit is contained in:
rd
2025-08-07 18:05:27 +08:00
parent de55e00196
commit d07f773123
17 changed files with 678 additions and 115 deletions

View File

@ -131,101 +131,101 @@ export function getVideoInfo(file: File): Promise<{ duration: number; firstFrame
video.style.position = 'fixed'; // 确保视频元素在DOM中
video.style.top = '-1000px'; // 但不可见
document.body.appendChild(video); // 添加到DOM
let hasResolved = false;
// 先获取元数据(时长)
video.onloadedmetadata = function () {
// 视频时长
const duration = video.duration;
// 尝试将视频定位到非常小的时间点,确保有帧可捕获
if (duration > 0) {
video.currentTime = Math.min(0.1, duration / 2);
}
};
// 当视频定位完成后尝试捕获首帧
video.onseeked = function () {
if (hasResolved) return;
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
}
// 清理
window.URL.revokeObjectURL(video.src);
document.body.removeChild(video);
// 返回结果
hasResolved = true;
resolve({
duration: video.duration,
firstFrame: canvas.toDataURL('image/jpeg', 0.9) // 提高质量
firstFrame: canvas.toDataURL('image/jpeg', 0.9), // 提高质量
});
};
// 作为备选方案监听loadeddata事件
video.onloadeddata = function () {
if (hasResolved) return;
// 尝试捕获帧
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
}
// 检查是否捕获到有效帧(非全黑)
const imageData = ctx?.getImageData(0, 0, canvas.width, canvas.height);
if (imageData) {
let isAllBlack = true;
for (let i = 0; i < imageData.data.length; i += 4) {
if (imageData.data[i] > 10 || imageData.data[i+1] > 10 || imageData.data[i+2] > 10) {
if (imageData.data[i] > 10 || imageData.data[i + 1] > 10 || imageData.data[i + 2] > 10) {
isAllBlack = false;
break;
}
}
if (!isAllBlack) {
// 清理
window.URL.revokeObjectURL(video.src);
document.body.removeChild(video);
// 返回结果
hasResolved = true;
resolve({
duration: video.duration,
firstFrame: canvas.toDataURL('image/jpeg', 0.9)
firstFrame: canvas.toDataURL('image/jpeg', 0.9),
});
return;
}
}
// 如果是全黑帧尝试定位到0.1秒
if (video.duration > 0) {
video.currentTime = 0.1;
}
};
// 设置视频源以触发加载
video.src = URL.createObjectURL(file);
// 设置超时,防止长时间无响应
setTimeout(() => {
if (!hasResolved) {
document.body.removeChild(video);
resolve({
duration: 0,
firstFrame: ''
firstFrame: '',
});
}
}, 5000); // 5秒超时
@ -266,7 +266,7 @@ export const formatUploadSpeed = (bytesPerSecond: number): string => {
}
};
export function convertVideoUrlToCoverUrl(videoUrl: string): string {
export function convertVideoUrlToCoverUrl(videoUrl: string): string {
if (!videoUrl || typeof videoUrl !== 'string') {
console.error('Invalid video URL');
return '';
@ -281,3 +281,20 @@ export const formatUploadSpeed = (bytesPerSecond: number): string => {
return urlWithCovers + '.jpg';
}
/**
* 生成包含协议、域名和参数的完整URL
*/
export const generateFullUrl = (pathTemplate: string, params: Record<string, string | number> = {}): string => {
const protocol = window.location.protocol;
const hostname = window.location.hostname;
const port = window.location.port ? `:${window.location.port}` : '';
const baseUrl = `${protocol}//${hostname}${port}`;
let path = pathTemplate;
Object.entries(params).forEach(([key, value]) => {
path = path.replace(`:${key}`, String(value));
});
return `${baseUrl}${path}`;
};