1.VOD介绍

云点播(Video on Demand,VOD)依托于腾讯音视频技术平台打造多场景融合的音视频点播服务,为客户提供易用、稳定的云端一体化解决方案。云点播支持多样上传 SDK,媒资管理,媒资处理,视频 AI,数据分析,播放器 SDK 等功能,仅需几分钟,用户就可以在云端获取和启用云点播服务,全面满足低延迟、高画质、高码率、多终端、视频安全等多场景业务需求。

2.使用

vod和cos不同,vod上传可使用javasdk,可使用其他方式,而播放或者修改删除等操作调用腾讯云提供的接口(SDK有点难找)

1.推荐对上传的视频进行加密

视频加密,加密之后,直接访问视频链接不能观看视频,需要使用超级播放器加appid+fileid+sign访问,其中sign是会过期的,本地生成方式会在下面给出
image.png
文件Id
image.png
推荐对视频进行转码
image.png

2.使用javaSDK上传

查看产品文档可知,腾讯云不支持流式上传,只支持本地文件或者拉取URl上传,所以需要先存为本地文件再上传,具体方式看下例

缺点:

多了一道中转过程,浪费时间,且这样一来,element-ui的上传组件进度条就会失效,因为进度条是根据上传到自己的服务器为依据的,而不是以实际的腾讯云上传完成为依据,
image.png

1.导入maven依赖

  1. <!-- 腾讯云vod-->
  2. <dependency>
  3. <groupId>com.qcloud</groupId>
  4. <artifactId>vod_api</artifactId>
  5. </dependency>
  6. <!-- 腾讯云javaSDK,就不需要调用腾讯云的url接口了,就可以自己写接口-->
  7. <dependency>
  8. <groupId>com.tencentcloudapi</groupId>
  9. <artifactId>tencentcloud-sdk-java</artifactId>
  10. </dependency>
  11. <!-- 用来生成腾讯云的加密签名-->
  12. <dependency>
  13. <groupId>com.auth0</groupId>
  14. <artifactId>java-jwt</artifactId>
  15. </dependency>

2.存为本地文件方法

  1. /**
  2. * 保存文件至本地,因为腾讯云不支持流式上传,所以只能先存为文件中转
  3. *
  4. * @param multipartFile
  5. * @return
  6. * @throws Exception
  7. */
  8. public String saveFileToLocal(MultipartFile multipartFile) throws Exception {
  9. //生成基础路径,路径为类路径下
  10. //E:/java/javaProgramFile/guli_parent/service/service_vod/target/classes/static/video
  11. String basePath = ResourceUtils.getURL("classpath:").getPath() + "static/video";
  12. //判断当前文件夹存不存在
  13. File file = new File(basePath);
  14. if (!file.exists()) {
  15. file.mkdirs();
  16. } //获取上传的文件名
  17. String fileName = multipartFile.getOriginalFilename();
  18. //生成最终路径,File.separator:分隔符
  19. String finalPath = basePath + File.separator + fileName;
  20. //将文件保存到对应文件夹
  21. multipartFile.transferTo(new File(finalPath));
  22. return finalPath;
  23. }

3.将本地文件上传至vod方法

  1. /**
  2. * 上传至腾讯云点播
  3. *
  4. * @param filePath
  5. * @return
  6. */
  7. public VodUploadResponse uploadFileToVod(String filePath) {
  8. //初始化一个上传客户端对象
  9. VodUploadClient client = new VodUploadClient(VodUtils.SECRET_ID, VodUtils.SECRET_KEY);
  10. //构造上传请求对象
  11. VodUploadRequest request = new VodUploadRequest();
  12. request.setMediaFilePath(filePath); //视频地址,必须为本地路径,不支持 URL
  13. // request.setCoverFilePath("/data/videos/Wildlife.jpg"); //指定封面,必须为本地路径,不支持 URL
  14. request.setProcedure("SimpleAesEncryptPreset"); //指定上传后执行的任务流,任务流查看vod控制台,这里是视频加密模板
  15. request.setConcurrentUploadNumber(5); //指定分片上传数,会把文件拆分成多个分片上传,更快
  16. try {
  17. //上传并获得视频id,此处地域只是请求的云服务器位置,不是视频的存储位置
  18. VodUploadResponse response = client.upload(VodUtils.REGION, request);
  19. log.info("腾讯云点播 FileId = {}", response.getFileId());
  20. log.info("腾讯云点播 url = {}", response.getMediaUrl());
  21. return response;
  22. } catch (Exception e) {
  23. // 业务方进行异常处理
  24. log.error("腾讯云上传 Error", e);
  25. return null;
  26. }
  27. }

4.service调用

  1. public String uploadTencentVideo(MultipartFile file) {
  2. try {
  3. String filePath = saveFileToLocal(file);
  4. VodUploadResponse response = uploadFileToVod(filePath);
  5. String fileId = response.getFileId();
  6. //上传完成后删除存在本地的文件
  7. File path = new File(filePath);
  8. if (path.exists()) {
  9. path.delete();
  10. }
  11. return fileId;
  12. } catch (Exception e) {
  13. throw new GuliException(20001, "文件上传失败");
  14. }
  15. }

3.使用webSDK上传

1.与javaSDK的区别:

  1. javaSDK是属于服务端上传,不需要上传签名认证,web是客户端上传,需要签名认证
  2. javaSDK不支持流式上传,需先存为本地文件,浪费时间且会使进度条失效,web上传直接在前端将选择的文件使用腾讯提供的sdk上传,少一道中转,且不会使进度条失效

    2.使用步骤:

    1.后端提供签名服务接口,具体代码参考腾讯云文档

    1. /**
    2. * 获得上传签名
    3. * @return
    4. */
    5. @GetMapping("getSign")
    6. public R getSign() {
    7. String sign = vodService.getSign();
    8. return R.ok().data("signature", sign);
    9. }

    2.编写service层

    1. public String getSign() {
    2. Signature sign = new Signature();
    3. // 设置 App 的云 API 密钥
    4. sign.setSecretId(VodUtils.SECRET_ID);
    5. sign.setSecretKey(VodUtils.SECRET_KEY);
    6. sign.setCurrentTime(System.currentTimeMillis() / 1000);
    7. sign.setRandom(new Random().nextInt(java.lang.Integer.MAX_VALUE));
    8. sign.setSignValidDuration(3600 * 24); // 签名有效期:1天
    9. try {
    10. String signature = sign.getUploadSignature();
    11. log.info("signature : " + signature);
    12. return signature;
    13. } catch (Exception e) {
    14. e.printStackTrace();
    15. throw new GuliException(20001, "获取签名失败");
    16. }
    17. }

    3.签名生成工具类。复制腾讯云文档即可

    ```java package com.guli.utils;

import java.util.Random; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64;

/**

  • 上传签名工具类 */ public class Signature { private String secretId; private String secretKey; private long currentTime; private int random; private int signValidDuration; private static final String HMAC_ALGORITHM = “HmacSHA1”; //签名算法 private static final String CONTENT_CHARSET = “UTF-8”;

    public static byte[] byteMerger(byte[] byte1, byte[] byte2) {

    1. byte[] byte3 = new byte[byte1.length + byte2.length];
    2. System.arraycopy(byte1, 0, byte3, 0, byte1.length);
    3. System.arraycopy(byte2, 0, byte3, byte1.length, byte2.length);
    4. return byte3;

    }

    // 获取签名 public String getUploadSignature() throws Exception {

    1. String strSign = "";
    2. String contextStr = "";
    3. // 生成原始参数字符串
    4. long endTime = (currentTime + signValidDuration);
    5. contextStr += "secretId=" + java.net.URLEncoder.encode(secretId, "utf8");
    6. contextStr += "&currentTimeStamp=" + currentTime;
    7. contextStr += "&expireTime=" + endTime;
    8. contextStr += "&random=" + random;
    9. try {
    10. Mac mac = Mac.getInstance(HMAC_ALGORITHM);
    11. SecretKeySpec secretKey = new SecretKeySpec(this.secretKey.getBytes(CONTENT_CHARSET), mac.getAlgorithm());
    12. mac.init(secretKey);
    13. byte[] hash = mac.doFinal(contextStr.getBytes(CONTENT_CHARSET));
    14. byte[] sigBuf = byteMerger(hash, contextStr.getBytes("utf8"));
    15. strSign = base64Encode(sigBuf);
    16. strSign = strSign.replace(" ", "").replace("\n", "").replace("\r", "");
    17. } catch (Exception e) {
    18. throw e;
    19. }
    20. return strSign;

    }

    private String base64Encode(byte[] buffer) {

    1. Base64.Encoder encoder = Base64.getEncoder();
    2. return encoder.encodeToString(buffer);

    }

    public void setSecretId(String secretId) {

    1. this.secretId = secretId;

    }

    public void setSecretKey(String secretKey) {

    1. this.secretKey = secretKey;

    }

    public void setCurrentTime(long currentTime) {

    1. this.currentTime = currentTime;

    }

    public void setRandom(int random) {

    1. this.random = random;

    }

    public void setSignValidDuration(int signValidDuration) {

    1. this.signValidDuration = signValidDuration;

    } }

    1. <a name="wdWxi"></a>
    2. #### 4.前端下载并引入依赖
    3. ```javascript
    4. // npm install vod-js-sdk-v6 之后,在页面中直接 import 引入,web上传到腾讯云点播
    5. import TcVod from 'vod-js-sdk-v6'

    5.使用自定义方法覆盖默认上传方式

    1. <el-form-item label="上传视频">
    2. <el-upload
    3. :on-remove="handleVodRemove"
    4. :before-remove="beforeVodRemove"
    5. :on-exceed="handleUploadExceed"
    6. :before-upload="BeforeUpload"
    7. :file-list="fileList"
    8. :http-request="uploadVideo"
    9. :limit="1"
    10. action
    11. class="upload-demo">
    12. <!-- :action="BASE_API+'/eduVod/video/uploadTencentVideo'"-->
    13. <el-button size="small" type="primary">上传视频</el-button>
    14. <el-tooltip placement="right-end">
    15. <div slot="content">最大支持1G,<br>
    16. 支持3GP、ASF、AVI、DAT、DV、FLV、F4V、<br>
    17. GIF、M2T、M4V、MJ2、MJPEG、MKV、MOV、MP4、<br>
    18. MPE、MPG、MPEG、MTS、OGG、QT、RM、RMVB、<br>
    19. SWF、TS、VOB、WMV、WEBM 等视频格式上传
    20. </div>
    21. <i class="el-icon-question"/>
    22. </el-tooltip>
    23. </el-upload>
    24. <el-progress v-show="isShowProgress" :percentage="percent" :status="upLoadStatus"></el-progress>
    25. </el-form-item>

    6.自定义方法,复制腾讯云示例

    1. getSign(){
    2. return request ({
    3. url: `/eduVod/video/getSign`,
    4. method: 'get'
    5. })
    6. }
    1. //获得后端生成的上传签名,请求自己的接口即可
    2. getSign() {
    3. return video.getSign().then((response) => {
    4. return response.data.signature
    5. })
    6. }
    1. //自定义的上传方法,覆盖率原来的上传方式,前端将文件上传至腾讯云
    2. //param为upload组件
    3. uploadVideo(param) {
    4. const tcVod = new TcVod({
    5. getSignature: this.getSign
    6. })
    7. const uploader = tcVod.upload({
    8. mediaFile: param.file, // 媒体文件(视频或音频或图片),类型为 File
    9. })
    10. // 进度条
    11. uploader.on('media_progress', (info) =>{
    12. this.percent = info.percent*100
    13. })
    14. //上传完成执行的操作,doneResult.fileId会返回保存的id
    15. uploader.done().then((doneResult)=>{
    16. //..........
    17. })
    18. }

    4.播放视频

    播放视频推荐使用腾讯云的超级播放器
    image.png

    1. <link href="aaa.xxx.ccc/tcplayer.min.css" rel="stylesheet">
    2. <!--如果需要在 Chrome 和 Firefox 等现代浏览器中通过 H5 播放 HLS 格式的视频,需要在 tcplayer.v4.2.1.min.js 之前引入 hls.min.0.13.2m.js。-->
    3. <script src="aaa.xxx.ccc/libs/hls.min.0.13.2m.js"></script>
    4. <!--播放器脚本文件-->
    5. <script src="aaa.xxx.ccc/tcplayer.v4.2.1.min.js"></script>

    image.png

    1. <video id="player-container-id" width="414" height="270" preload="auto" playsinline webkit-playsinline>
    2. </video>

    image.png

    1. var player = TCPlayer('player-container-id', { // player-container-id 为播放器容器 ID,必须与 html 中一致
    2. fileID: '5285890799710670616', // 请传入需要播放的视频 fileID(必须)
    3. appID: '1400329073' // 请传入点播账号的 appID(必须)
    4. });

    示例代码

    ```javascript <!DOCTYPE html>

  1. <a name="Kg1c8"></a>
  2. ## 5.其他操作
  3. <a name="JOSsG"></a>
  4. ### 1.调用接口方式
  5. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/25654866/1648809701246-728b98bb-891a-4806-a23e-20d24b9e3153.png#clientId=u3b0ac6b3-19c2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=661&id=u236eae41&margin=%5Bobject%20Object%5D&name=image.png&originHeight=826&originWidth=1723&originalType=binary&ratio=1&rotation=0&showTitle=false&size=210584&status=done&style=none&taskId=ub4e2accf-799b-46a7-b6a3-65cacafe8e8&title=&width=1378.4)
  6. <a name="p82GF"></a>
  7. ### 2.使用javaSDK方式
  8. 具体操作示例可以查看腾讯云JavaSDK的[github地址](https://github.com/TencentCloud/tencentcloud-sdk-java)<br />接口参数可以参考接口方式的文档
  9. <a name="DQrrA"></a>
  10. #### 1.导入maven,上方已经给出
  11. <a name="oKezM"></a>
  12. #### 2.删除操作
  13. ```java
  14. /**
  15. * 删除vod中指定文件
  16. * @throws Exception
  17. */
  18. @Test
  19. public void deleteFile() throws Exception{
  20. //实例化一个认证对象
  21. Credential client = new Credential("xxxxxxxxxx", "xxxxxxx");
  22. //实例化要请求产品的client对象
  23. VodClient vodClient = new VodClient(client,"ap-chengdu");
  24. DeleteMediaRequest deleteMediaRequest = new DeleteMediaRequest();
  25. deleteMediaRequest.setFileId("xxxxxxxxxxxx");
  26. DeleteMediaResponse deleteMediaResponse = vodClient.DeleteMedia(deleteMediaRequest);
  27. //System.out.println(deleteMediaResponse);
  28. }

3.如果需要加密操作,需要生成签名的话

  1. /**
  2. * 生成腾讯云的加密签名
  3. */
  4. @Test
  5. public void createSign(){
  6. Integer AppId = 1255566655; //账号 appId
  7. String FileId = "4564972818519602447"; //文件 ID
  8. Integer CurrentTime = 1589448067; //派发签名当前 Unix 时间戳
  9. Integer PsignExpire = 1589548067; //派发签名到期 Unix 时间戳,不填表示不过期
  10. String UrlTimeExpire = "5ebe9423‬"; //url到期时间
  11. String Key = "24FEQmTzro4V5u3D5epW"; //控制台中key盗链生成的key
  12. HashMap<String, String> urlAccessInfo = new HashMap<String, String>();
  13. urlAccessInfo.put("t", UrlTimeExpire);
  14. try {
  15. Algorithm algorithm = Algorithm.HMAC256(Key);
  16. String token = JWT.create().withClaim("appId", AppId).withClaim("fileId", FileId)
  17. .withClaim("currentTimeStamp", CurrentTime).withClaim("expireTimeStamp", PsignExpire)
  18. .withClaim("urlAccessInfo", urlAccessInfo).sign(algorithm);
  19. System.out.println("token:" + token);
  20. } catch (JWTCreationException exception) {
  21. // Invalid Signing configuration / Couldn't convert Claims.
  22. }
  23. }