VOD使用开发
阿里云视频点播官方文档
阿里云视频点播(ApsaraVideo VoD)是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、高效云剪辑处理、分发加速、视频播放于一体的一站式音视频点播解决方案。
阿里云视频点播基于阿里云强大的基础设施服务,面向视频网站、短视频、在线教育、娱乐社交、新闻传媒等行业,提供端-云-端的视频全链路服务,帮助企业和开发者快速搭建安全、弹性、高效、可定制的视频点播平台和应用。
网站上观看的视频需要保证安全性,不可下载和传播。但是视频所占内存巨大,因此决定使用阿里云的视频点播来存储和处理视频。我负责的是视频上传、加密、解密播放这一块的开发,在开发过程中也是遇到了许多问题,因此记录一下,也是以后遇到问题时,能够及时回顾和查看。
视频上传部分
视频点播支持通过多种方式上传媒体文件(音频、视频、图片等)到点播存储。同时支持自动触发或通过API,发起进行转码、剪辑、分发等后续处理。
支持的方式有:
控制台上传
服务端上传
客户端上传
离线拉取上传
PC客户端工具上传
我做的部分主要是服务端上传,其他方式的上传可以去阿里云视频点播官方文档上查找,里面有详细的文档介绍。
服务端上传阿里云的官方解释为:
服务端上传,是指将应用服务器上的媒体文件上传到点播存储。适合自动化上传、大批量迁移视频上传等场景,也可用于网络媒体文件的上传,其原理也是先下载到应用服务器本地再上传到点播。
这里采用的是SDK的上传方式:
安装SDK需要导入Maven依赖包:
<!-- 添加Jar包依赖 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-vod</artifactId>
<version>2.15.10</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-kms</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-vod-upload</artifactId>
<version>1.4.12</version>
<scope>system</scope>
<systemPath>${pom.basedir}/lib/aliyun-java-vod-upload-1.4.12.jar</systemPath>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.6.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
其中aliyun-java-vod-upload 这个包需要去网上找相应版本的jar包,新建一个lib包放到里面。如果直接用阿里云提供的Maven依赖,可能会产生各种各样的问题,会产生各种版本冲突。也可以直接通过百度网盘下载:
链接
提取码:ldvu
/**
* 视频文件流上传调用接口
* @param title
* @param fileName
* @return
*/
public static Map<Object,Object> VodUploadStream( String title,String fileName,String TemplateGroupId) {
// 一、视频文件上传
// 视频标题(必选)
//String title = "测试标题";
// 1.本地文件上传和文件流上传时,文件名称为上传文件绝对路径,如:/User/sample/文件名称.mp4 (必选)
// 2.网络流上传时,文件名称为源文件名,如文件名称.mp4(必选)。
// 3.流式上传时,文件名称为源文件名,如文件名称.mp4(必选)。
// 任何上传方式文件名必须包含扩展名
//String fileName = "E:\\baa4cfc04fd94efca3b515b0ed35c4dc.mp4";
// 待上传视频的网络流地址
//String url = "http://test.aliyun.com/video/test.mp4";
// 4.流式上传,如文件流和网络流
InputStream inputStream = null;
// 4.1 文件流
try {
inputStream = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 4.2 网络流
/*try {
inputStream = new URL(url).openStream();
} catch (IOException e) {
e.printStackTrace();
}*/
Map<Object,Object>map=UploadStream(accessKeyId, accessKeySecret, title, fileName, inputStream,TemplateGroupId);
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
/**
* 流式上传接口
*
* @param accessKeyId
* @param accessKeySecret
* @param title
* @param fileName
* @param inputStream
*/
private static Map<Object,Object> UploadStream(String accessKeyId, String accessKeySecret, String title, String fileName, InputStream inputStream,String TemplateGroupId) {
UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, inputStream);
File newFile = new File(fileName);
Long totalBytes = newFile.length();
//System.out.println(totalBytes);
Map<Object, Object> resultMap = new HashMap<Object, Object>();
/* 是否使用默认水印(可选),指定模板组ID时,根据模板组配置确定是否使用默认水印*/
//request.setShowWaterMark(true);
/* 设置上传完成后的回调URL(可选),建议通过点播控制台配置消息监听事件,参见文档 https://help.aliyun.com/document_detail/57029.html */
//request.setCallback("http://callback.sample.com");
/* 自定义消息回调设置,参数说明参考文档 https://help.aliyun.com/document_detail/86952.html#UserData */
//request.setUserData("{\"MessageCallback\":{\"CallbackURL\":\"http://xxx/api/HlsDecryptServer/uploadCallBack\"}}");
request.setUserData(uploadCallBack);
/* 视频分类ID(可选) */
request.setCateId((long) 0000156004);
/* 视频标签,多个用逗号分隔(可选) */
//request.setTags("标签1,标签2");
/* 视频描述(可选) */
//request.setDescription("视频描述");
/* 封面图片(可选) */
//request.setCoverURL("https:///9f0b5337bbea4076ad9594feb2ebb59e/snapshots/2cb1545b97fb4229b4d89402137c9f2f-00001.jpg");
/* 模板组ID(可选) */
request.setTemplateGroupId(TemplateGroupId);
/* 工作流ID(可选) */
//request.setWorkflowId("d4430d07361f0*be1339577859b0177b");
/* 存储区域(可选) */
request.setStorageLocation(storageLocation);
/* 开启默认上传进度回调 */
//request.setPrintProgress(true);
/* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */
PutObjectProgressListener putObjectProgressListener = new PutObjectProgressListener();
putObjectProgressListener.setTotalBytes(totalBytes);
request.setProgressListener(putObjectProgressListener);
/* 设置应用ID*/
//request.setAppId("app-1000000");
/* 点播服务接入点 */
//request.setApiRegionId("cn-shanghai");
/* ECS部署区域*/
//request.setEcsRegionId("cn-shanghai");
UploadVideoImpl uploader = new UploadVideoImpl();
UploadStreamResponse response = uploader.uploadStream(request);
//System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
resultMap .put("RequestId", response.getRequestId());
if (response.isSuccess()) {
//System.out.print("VideoId=" + response.getVideoId() + "\n");
resultMap .put("VideoId", response.getVideoId());
} else {
//如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
//System.out.print("VideoId=" + response.getVideoId() + "\n");
resultMap .put("VideoId", response.getVideoId());
//System.out.print("ErrorCode=" + response.getCode() + "\n");
resultMap .put("ErrorCode", response.getCode());
//System.out.print("ErrorMessage=" + response.getMessage() + "\n");
resultMap .put("ErrorMessage=", response.getMessage());
}
return resultMap;
}
其中 TemplateGroupId 是模板组Id,可以在阿里云控制台上获取,设置模板组可以使视频转码,高清、超清等等都有,我这里设置的是不转码,把上传视频和视频加密分开操作。
上传进度回调函数示例代码:
package com.huanke.managesystem.framework.core.service.impl;
import com.aliyun.oss.event.ProgressEvent;
import com.aliyun.oss.event.ProgressEventType;
import com.aliyun.vod.upload.impl.VoDProgressListener;
/**
* 上传进度回调方法类
* 当您开启上传进度回调时该事件回调才会生效。
* OSS分片上传成功或失败均触发相应的回调事件,您可根据业务逻辑处理相应的事件回调。
* 当创建音视频信息成功后,此上传进度回调中的videoId为本次上传生成的视频ID,您可以根据视频ID进行音视频管理。
* 当创建图片信息成功后,此上传进度回调中的ImageId为本次上传生成的图片ID,您可以根据视频ID进行图片管理。
*/
public class PutObjectProgressListener implements VoDProgressListener{
/**
* 已成功上传至OSS的字节数
*/
private long bytesWritten = 0;
/**
* 原始文件的总字节数
*/
private long totalBytes ;
/**
* 本次上传成功标记
*/
private boolean succeed = false;
/**
* 视频ID
*/
private String videoId;
/**
* 图片ID
*/
private String imageId;
public void progressChanged(ProgressEvent progressEvent) {
long bytes = progressEvent.getBytes();
ProgressEventType eventType = progressEvent.getEventType();
switch (eventType) {
// 开始上传事件
case TRANSFER_STARTED_EVENT:
if (videoId != null) {