前端开发记录:Web端对接腾讯云上传视频

项目技术栈: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,如果需要支持低版本浏览器,需要自行引入 Promisepolyfill
  • 上传的文件最大支持 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)

链接汇总

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容