/**
|
* 视频处理工具函数
|
*/
|
|
/**
|
* 从视频文件中提取第一帧作为封面图
|
* @param {File} videoFile - 视频文件对象
|
* @param {number} quality - 图片质量 (0-1),默认0.8
|
* @returns {Promise<Blob>} 返回图片Blob对象
|
*/
|
export const extractVideoFrame = (videoFile, quality = 0.8) => {
|
return new Promise((resolve, reject) => {
|
// 创建video元素
|
const video = document.createElement('video')
|
video.crossOrigin = 'anonymous'
|
video.muted = true
|
video.playsInline = true
|
|
// 创建canvas元素
|
const canvas = document.createElement('canvas')
|
const ctx = canvas.getContext('2d')
|
|
// 监听视频加载完成
|
video.addEventListener('loadedmetadata', () => {
|
// 设置canvas尺寸为视频尺寸
|
canvas.width = video.videoWidth
|
canvas.height = video.videoHeight
|
|
// 跳转到第一帧(0.1秒处,避免黑屏)
|
video.currentTime = 0.1
|
})
|
|
// 监听视频可以播放
|
video.addEventListener('canplay', () => {
|
// 绘制当前帧到canvas
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
|
// 将canvas转换为Blob
|
canvas.toBlob((blob) => {
|
if (blob) {
|
resolve(blob)
|
} else {
|
reject(new Error('无法提取视频帧'))
|
}
|
}, 'image/jpeg', quality)
|
|
// 清理资源
|
video.src = ''
|
URL.revokeObjectURL(video.src)
|
})
|
|
// 监听错误
|
video.addEventListener('error', (e) => {
|
reject(new Error('视频加载失败: ' + e.message))
|
})
|
|
// 设置视频源
|
video.src = URL.createObjectURL(videoFile)
|
})
|
}
|
|
/**
|
* 检查文件是否为视频
|
* @param {File} file - 文件对象
|
* @returns {boolean} 是否为视频文件
|
*/
|
export const isVideoFile = (file) => {
|
return file && file.type && file.type.startsWith('video/')
|
}
|
|
/**
|
* 获取视频文件的基本信息
|
* @param {File} videoFile - 视频文件对象
|
* @returns {Promise<Object>} 返回视频信息对象
|
*/
|
export const getVideoInfo = (videoFile) => {
|
return new Promise((resolve, reject) => {
|
const video = document.createElement('video')
|
video.crossOrigin = 'anonymous'
|
video.muted = true
|
video.playsInline = true
|
|
video.addEventListener('loadedmetadata', () => {
|
const info = {
|
duration: video.duration,
|
width: video.videoWidth,
|
height: video.videoHeight,
|
size: videoFile.size,
|
type: videoFile.type,
|
name: videoFile.name
|
}
|
resolve(info)
|
|
// 清理资源
|
video.src = ''
|
URL.revokeObjectURL(video.src)
|
})
|
|
video.addEventListener('error', (e) => {
|
reject(new Error('无法获取视频信息: ' + e.message))
|
})
|
|
video.src = URL.createObjectURL(videoFile)
|
})
|
}
|
|
/**
|
* 生成缩略图文件名
|
* @param {string} originalFileName - 原始文件名
|
* @returns {string} 缩略图文件名
|
*/
|
export const generateThumbnailFileName = (originalFileName) => {
|
const nameWithoutExt = originalFileName.replace(/\.[^/.]+$/, '')
|
const timestamp = Date.now()
|
return `${nameWithoutExt}_thumb_${timestamp}.jpg`
|
}
|