项目技术栈:vue、vite、ts
官网地址:https://cloud.tencent.com/act/event/video_BestPractices?
上传视频文档:https://cloud.tencent.com/document/product/266/9239
预览视频文档:https://rtcube.cloud.tencent.com/component/experience-center/index.html#/detail?scene=player
关于 vod-js-sdk-v6 与 cos-js-sdk-v5 区别
- 如果应用场景是通用文件存储,例如上传用户头像、保存文档、分享图片等,与腾讯云对象存储(COS)直接交互,那么
cos-js-sdk-v5更合适。 - 如果业务核心是视频相关,例如在线教育、短视频、媒体门户等,并且需要使用腾讯云点播提供的视频转码、内容审核、密钥防盗链、超级播放器等能力,那么
vod-js-sdk-v6更适合
注意事项:
-
签名安全至关重要:
getSignature函数必须通过后端服务器实现,绝对不能在前端直接计算密钥 - 断点续传:SDK内置支持。上传意外中断后再次上传同一文件,会从中断处继续
-
上传进度监控:通过监听
media_progress事件实现 -
动态上传加速:从
1.7.0-beta.4版本开始,SDK支持通过dynamicAccelerate: true参数开启动态加速,提升上传速度(需在腾讯云控制台开启全球链路加速) - SDK依赖
Promise,如果需要支持低版本浏览器,需要自行引入Promise的polyfill - 上传的文件最大支持 60GB
封装Hooks代码如下:
import TcVod from 'vod-js-sdk-v6';
import request from '@/utils/request'
import { ResultInter } from '@/api/types'
interface VodUploader {
on: (event: string, callback: (info: any) => void) => void;
done: () => Promise<any>;
cancel: () => void; // 添加 cancel 方法
}
let tcVod: any = null // 腾讯云VOD实例
const uploaderList = new Set<VodUploader>(); // 存储所有活动的上传器实例
/**
* 获取上传签名
* @returns {string} 签名
*/
const getSignature = async (): Promise<string> => {
// 替换为您自己的后端签名接口
const response = await request<ResultInter>({
method: 'get',
url: '/golfer/teaching/course/sign',
});
// console.log('签名', response);
return response.data;
};
/**
* 处理文件上传
* @param file 文件
* @param onProgress 进度回调
* @returns {Promise}
*/
const handleVodUpload = (file: File, onProgress?: (percent: number) => void): Promise<any> => {
console.log('开始上传文件', file);
return new Promise((resolve, reject) => {
if (!file) {
reject(new Error('文件为空'));
return;
}
if (file.size === 0) {
reject(new Error('文件为空'));
return;
}
if (!tcVod) {
tcVod = new TcVod({
getSignature: getSignature
});
}
const uploader = tcVod.upload({
mediaFile: file
})
// 添加到上传器集合
uploaderList.add(uploader);
// 监听上传进度
uploader.on('media_progress', (info: any) => {
const percent = Math.floor(info.percent); // 取整
// console.log(`上传进度: ${percent}%`);
// 如果有进度回调,就执行
if (onProgress) {
onProgress(percent);
}
});
// 开始上传
uploader.done().then((doneResult: any) => {
// console.log('上传成功', doneResult);
resolve(doneResult);
}).catch((err: any) => {
console.error('上传失败', err);
reject(err);
}).finally(() => {
// 上传完成后从集合中移除
if (uploader && uploaderList.has(uploader)) {
uploaderList.delete(uploader);
}
})
});
};
/**
* 取消所有上传
*/
const cancelAllVodUpload = () => {
// 遍历所有上传器并取消
uploaderList.forEach(uploader => {
try {
uploader?.cancel();
} catch (error) {
console.error('取消上传时出错:', error);
}
});
// 清空上传器集合
uploaderList.clear();
}
// 格式化文件大小显示
const formatFileSize = (bytes?: number): string => {
if (!bytes) return '--'
if (bytes === 0) return '0 B'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
export {
getSignature,
formatFileSize,
handleVodUpload,
cancelAllVodUpload
}
使用示例:
import { handleVodUpload, cancelAllVodUpload, formatFileSize } from '@/hooks/useVod'
const result = await handleVodUpload(fileItem.file, (progress) => {
console.log(`上传进度回调:${progress}%`)
})
console.log('上传完成:', result)