feat: 客户分享链接列表
This commit is contained in:
@ -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}`;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user