携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
想要使用腾讯云的点播功能,那么需要大家有一个腾讯云的账号。再次先说一下,腾讯云点播这个功能是需要收费的,大家可以先往里面充值几块钱。
1.前期准备
1.1 在腾讯云搜索云点播,然后开通即可。
1.2 这是管理控制台
1.3 上次视频
- 打开媒资管理
- 打开音视频管理
打开管理可以查看详情
1.4 前端集成
前端集成有两种方式,使用“超级播放器预览”与“web播放器预览”,后者代码已经不更新,推荐使用前者,因此“web播放器预览”仅做了解。
1.查看
说明:需要将视频进行转码,才能支持超级播放器播放,转码为:自适应码流
2、查看“任务流设置”
3. 你可能好奇怎么播放视频
复制代码到你的项目里就可以了,我是在桌面建一个html文件,把代码粘贴进去。
2.在实际项目中使用腾讯云
引入依赖
大家打开腾讯云的官方文档会发现没有exclusions标签,那为什么我们这里要添加这个标签?因为如果你不排除slf4j-log4j12,那么便会和springboot冲突,启动会报错。
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>vod_api</artifactId>
<version>2.1.4</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
2.1上传功能
controller代码
我们让上传接口返回这个视频上传后在腾讯云里的id
@Api(tags = "腾讯云点播")
@RestController
@RequestMapping("/admin/vod")
@CrossOrigin
public class VodController {
@Autowired
private VodService vodService;
//上传视频接口
@ApiOperation("上传视频")
@PostMapping("upload")
public Result upload() {
String fileId = vodService.ipdateVideo(); //返回这个视频的id
return Result.ok(fileId);
}
}
service接口和service实现类
public interface VodService {
String ipdateVideo();
}
这里为各位同学解释下:
- ConstantPropertiesUtil是我写的配置类,里面配置了我腾讯云的id和key,这里我就不放出来了。密钥可前往console.cloud.tencent.com/cam/capi网站进…
- GgktException是自定义的异常类,service接口实现类是从腾讯云官方复制再修改的
- 你会发现上传路径是这样设置的request.setMediaFilePath("D:\001.wmv");从本地获取,写法固定。因为目前腾讯云官方就是这样写的,后面他们可能会更改,后面会介绍一些其他的上传方式。
@Service
public class VodServiceImpl implements VodService {
//上传视频
@Override
public String ipdateVideo() {
//指定当前腾讯云账号id和key
VodUploadClient client = new VodUploadClient(ConstantPropertiesUtil.ACCESS_KEY_ID, ConstantPropertiesUtil.ACCESS_KEY_SECRET);
//上传请求对象
VodUploadRequest request = new VodUploadRequest();
//设置视频文件在本地路径
request.setMediaFilePath("D:\001.wmv");
//指定任务流 可以去控制台复制
request.setProcedure("LongVideoPreset");
try {
//调用方法上传视频,指定地域 这里指定广州
VodUploadResponse response = client.upload("ap-guangzhou", request);
//logger.info("Upload FileId = {}", response.getFileId());
//获取上传之后视频id
String fileId = response.getFileId();
return fileId;
} catch (Exception e) {
// 业务方进行异常处理
throw new GgktException(20001,"上传视频失败");
}
}
}
上传结果
2.2 腾讯云其他上传视频方式
腾讯云客户端上传视频到云点播平台
- 前提条件 (1)开通云点播服务 (2)获取腾讯云账号id和key
- 按文档步骤实现客户端上传视频 (1)申请上传签名 (2)使用SDK上传视频,我们选择Web上传SDK
申请上传签名
我们可以在项目里面创建一个工具类,这个工具类代码是从腾讯云复制来的,我们可以做些简单的修改,如设置任务流contextStr += "&procedure=LongVideoPreset";
import java.util.Random;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Encoder;
/**
* @Author wzj
* @Date 2022/8/22 21:38
*/
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) {
byte[] byte3 = new byte[byte1.length + byte2.length];
System.arraycopy(byte1, 0, byte3, 0, byte1.length);
System.arraycopy(byte2, 0, byte3, byte1.length, byte2.length);
return byte3;
}
// 获取签名
public String getUploadSignature() throws Exception {
String strSign = "";
String contextStr = "";
// 生成原始参数字符串
long endTime = (currentTime + signValidDuration);
contextStr += "secretId=" + java.net.URLEncoder.encode(secretId, "utf8");
contextStr += "¤tTimeStamp=" + currentTime;
contextStr += "&expireTime=" + endTime;
contextStr += "&random=" + random;
//设置任务流 不然视频无法播放LongVideoPreset
contextStr += "&procedure=LongVideoPreset";
try {
Mac mac = Mac.getInstance(HMAC_ALGORITHM);
SecretKeySpec secretKey = new SecretKeySpec(this.secretKey.getBytes(CONTENT_CHARSET), mac.getAlgorithm());
mac.init(secretKey);
byte[] hash = mac.doFinal(contextStr.getBytes(CONTENT_CHARSET));
byte[] sigBuf = byteMerger(hash, contextStr.getBytes("utf8"));
strSign = base64Encode(sigBuf);
strSign = strSign.replace(" ", "").replace("\n", "").replace("\r", "");
} catch (Exception e) {
throw e;
}
return strSign;
}
private String base64Encode(byte[] buffer) {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(buffer);
}
public void setSecretId(String secretId) {
this.secretId = secretId;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public void setCurrentTime(long currentTime) {
this.currentTime = currentTime;
}
public void setRandom(int random) {
this.random = random;
}
public void setSignValidDuration(int signValidDuration) {
this.signValidDuration = signValidDuration;
}
}
创建一个专门的接口来获取签名,里面的代码也是复制于腾讯云,也是稍加修改。return Result.ok(signature)的Result是统一的数据返回格式,每个同学习惯不同。
Api(tags = "腾讯云点播")
@RestController
@RequestMapping("/admin/vod")
@CrossOrigin
public class VodController {
@Autowired
private VodService vodService;
//返回客户端上传视频签名
@GetMapping("sign")
public Result sign() {
Signature sign = new Signature();
// 设置 App 的云 API 密钥
sign.setSecretId(ConstantPropertiesUtil.ACCESS_KEY_ID);
sign.setSecretKey(ConstantPropertiesUtil.ACCESS_KEY_SECRET);
sign.setCurrentTime(System.currentTimeMillis() / 1000);
sign.setRandom(new Random().nextInt(java.lang.Integer.MAX_VALUE));
sign.setSignValidDuration(3600 * 24 * 2); // 签名有效期:2天
try {
String signature = sign.getUploadSignature();
System.out.println("signature : " + signature);
return Result.ok(signature);
} catch (Exception e) {
System.out.print("获取签名失败");
e.printStackTrace();
throw new GgktException(20001,"获取签名失败");
}
}
}
使用SDK上传视频,我们选择Web上传SDK
如果你从腾讯云打开文档,你会发现你会跳转到GitHub里面,你会看到一段前端代码,你可以将它复制到你的Visual Studio Code的里面,然后打开即可。你会看到这个界面,然后就上传视频即可
上传成功
如果你们打不开GitHub的话,直接粘贴下面的内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>QCloud VIDEO UGC UPLOAD SDK</title>
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
.text-danger {
color: red;
}
.control-label {
text-align: left !important;
}
#resultBox {
width: 100%;
height: 300px;
border: 1px solid #888;
padding: 5px;
overflow: auto;
margin-bottom: 20px;
}
.uploaderMsgBox {
width: 100%;
border-bottom: 1px solid #888;
}
.cancel-upload {
text-decoration: none;
cursor: pointer;
}
</style>
</head>
<body>
<div id="content">
<div class="container">
<h1>UGC-Uploader</h1>
</div>
</div>
<div class="container" id="main-area">
<div class="row" style="padding:10px;">
<p>
示例1点击“直接上传视频”按钮即可上传视频。<br>
</p>
</div>
<form ref="vExample">
<input type="file" style="display:none;" ref="vExampleFile" @change="vExampleUpload" />
</form>
<div class="row" style="padding:10px;">
<h4>示例1:直接上传视频</h4>
<a href="javascript:void(0);" class="btn btn-default" @click="vExampleAdd">直接上传视频</a>
</div>
<!-- 上传信息组件 -->
<div class="uploaderMsgBox" v-for="uploaderInfo in uploaderInfos">
<div v-if="uploaderInfo.videoInfo">
视频名称:{{uploaderInfo.videoInfo.name + '.' + uploaderInfo.videoInfo.type}};
上传进度:{{Math.floor(uploaderInfo.progress * 100) + '%'}};
fileId:{{uploaderInfo.fileId}};
上传结果:{{uploaderInfo.isVideoUploadCancel ? '已取消' : uploaderInfo.isVideoUploadSuccess ? '上传成功' : '上传中'}};
<br>
地址:{{uploaderInfo.videoUrl}};
<a href="javascript:void(0);" class="cancel-upload" v-if="!uploaderInfo.isVideoUploadSuccess && !uploaderInfo.isVideoUploadCancel" @click="uploaderInfo.cancel()">取消上传</a><br>
</div>
<div v-if="uploaderInfo.coverInfo">
封面名称:{{uploaderInfo.coverInfo.name}};
上传进度:{{Math.floor(uploaderInfo.coverProgress * 100) + '%'}};
上传结果:{{uploaderInfo.isCoverUploadSuccess ? '上传成功' : '上传中'}};
<br>
地址:{{uploaderInfo.coverUrl}};
<br>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
<script src="https://cdn-go.cn/cdn/vod-js-sdk-v6/latest/vod-js-sdk-v6.js"></script>
<script type="text/javascript">
;(function () {
/**
* 计算签名。调用签名接口获取
**/
function getSignature() {
return axios.get("http://localhost:8301/admin/vod/sign").then(response =>{
return response.data.data
})
};
var app = new Vue({
el: '#main-area',
data: {
uploaderInfos: [],
vcExampleVideoName: '',
vcExampleCoverName: '',
cExampleFileId: '',
},
created: function () {
this.tcVod = new TcVod.default({
getSignature: getSignature
})
},
methods: {
/**
* vExample示例。添加视频
**/
vExampleAdd: function () {
this.$refs.vExampleFile.click()
},
/**
* vExample示例。上传视频过程。
**/
vExampleUpload: function () {
var self = this;
var mediaFile = this.$refs.vExampleFile.files[0]
var uploader = this.tcVod.upload({
mediaFile: mediaFile,
})
uploader.on('media_progress', function (info) {
uploaderInfo.progress = info.percent;
})
uploader.on('media_upload', function (info) {
uploaderInfo.isVideoUploadSuccess = true;
})
console.log(uploader, 'uploader')
var uploaderInfo = {
videoInfo: uploader.videoInfo,
isVideoUploadSuccess: false,
isVideoUploadCancel: false,
progress: 0,
fileId: '',
videoUrl: '',
cancel: function() {
uploaderInfo.isVideoUploadCancel = true;
uploader.cancel()
},
}
this.uploaderInfos.push(uploaderInfo)
uploader.done().then(function(doneResult) {
console.log('doneResult', doneResult)
uploaderInfo.fileId = doneResult.fileId;
return doneResult.video.url;
}).then(function (videoUrl) {
uploaderInfo.videoUrl = videoUrl
self.$refs.vExample.reset();
})
},
// cExample 上传过程
cExampleUpload: function() {
var self = this;
var coverFile = this.$refs.cExampleCover.files[0];
var uploader = this.tcVod.upload({
fileId: this.cExampleFileId,
coverFile: coverFile,
})
uploader.on('cover_progress', function(info) {
uploaderInfo.coverProgress = info.percent;
})
uploader.on('cover_upload', function(info) {
uploaderInfo.isCoverUploadSuccess = true;
})
console.log(uploader, 'uploader')
var uploaderInfo = {
coverInfo: uploader.coverInfo,
isCoverUploadSuccess: false,
coverProgress: 0,
coverUrl: '',
cancel: function () {
uploader.cancel()
},
}
this.uploaderInfos.push(uploaderInfo)
uploader.done().then(function (doneResult) {
console.log('doneResult', doneResult)
uploaderInfo.coverUrl = doneResult.cover.url;
self.$refs.cExample.reset();
})
},
},
})
})();
</script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-26476625-7"></script>
<script>
// add by alsotang@gmail.com
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-26476625-7');
</script>
</body>
</html>
2.3 删除视频
controller代码
@Api(tags = "腾讯云点播")
@RestController
@RequestMapping("/admin/vod")
@CrossOrigin
public class VodController {
@Autowired
private VodService vodService;
//删除腾讯云视频
@ApiOperation("删除视频")
@DeleteMapping("remove/{fileId}")
public Result remove(@PathVariable String fileId) {
vodService.removeVideo(fileId);
return Result.ok(null);
}
}
接口和接口实现类
public interface VodService {
void removeVideo(String fileId);
}
接口实现类代码是复制于腾讯云,再稍加修改
@Service
public class VodServiceImpl implements VodService {
//删除视频
@Override
public void removeVideo(String fileId) {
try{
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
Credential cred = new Credential(ConstantPropertiesUtil.ACCESS_KEY_ID, ConstantPropertiesUtil.ACCESS_KEY_SECRET);
// 实例化一个http选项,可选的,没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("vod.tencentcloudapi.com");
// 实例化一个client选项,可选的,没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
VodClient client = new VodClient(cred, "", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
DeleteMediaRequest req = new DeleteMediaRequest();
req.setFileId(fileId);
// 返回的resp是一个DeleteMediaResponse的实例,与请求对象对应
DeleteMediaResponse resp = client.DeleteMedia(req);
// 输出json格式的字符串回包
System.out.println(DeleteMediaResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
System.out.println(e.toString());
throw new GgktException(20001,"删除视频失败");
}
}
}