视频点播服务中的视频,也依然是存在OSS上的,但是区别是什么呢?下面关于区别的描述摘自阿里云官网
视频的点播场景涉及视频的存储、转码、分发加速几个环节,那么:
- 视频点播是集视频音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速于一体的一站式音视频点播解决方案;而OSS是作为一种海量、安全、低成本、高可靠的云存储服务。
- 视频点播中存储的媒体主要是视频,后续也会提供音频等完成媒体库的建设;但OSS中可以存放各种类型的文件,从视频、音频到图片,再到doc、pdf等等任何文件,可以理解为就是一个云上的硬盘。
- OSS下可以作为独立的存储来用,也可以链接cdn产品,完成存放在OSS下文件的分发加速;但视频点播在存储音视频的媒体文件之后,核心作用是提供视频的托管服务,满足在线点播视频的业务需求,并且通过媒资管理、视频在线编辑、视频审核发布、数据统计、短视频SDK、视频安全等能力,覆盖到视频点播业务的不同方面。
- 视频点播的数据存储也是基于oss bucket,不同于OSS的是,视频点播为客户提供的私有bucket不占用OSS的空间,无需客户开通OSS产品, 该bucket在客户OSS下也不可见,采用独立的计量计费方式。
使用java操作之前,确保你必须开通了各种服务,要不然会提示你类似The storageLocation does not exist这种服务类型的异常
此处吐槽一下,阿里云的文档写的不是很容易懂,否则我也就不会写这篇文章来记录了
上传视频
上传视频分两种形式,第一种是API形式,就是你通过HTTP请求来和阿里云交互,第二种是SDK形式,就是你引入阿里云的jar包,最终有这个jar包去和阿里云交互,本文介绍的是SDK的形式
首先引入POM文件
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-vod</artifactId>
<version>2.15.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
你以为这就完事儿了?阿里云竟然还有一个包是在maven仓库不存在的,这个包的名字叫aliyun-java-vod-upload-1.4.12.jar,这个包你必须去阿里云官网搜索,然后找到关于该包,把这个包引入到本地的项目里
下面是相关上传视频和下载视频的代码
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import com.aliyun.vod.upload.impl.UploadImageImpl;
import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadImageRequest;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadImageResponse;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoRequest;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.aliyuncs.vod.model.v20170321.GetVideoInfoRequest;
import com.aliyuncs.vod.model.v20170321.GetVideoInfoResponse;
/**
* <p>处理阿里云视频点播的相关操作
*
* <p>官方API文档
* {@link https://help.aliyun.com/document_detail/60574.html?spm=a2c4g.11186623.6.701.6fcf3fa0qMuxMM}
*
* @author shiwentian
* @since 08.07.2020
*/
public abstract class AliVideoUtils {
private static final String accessKeyId = "你的accessKeyId";
private static final String accessKeySecret = "你的accessKeySecret";
private static final String regionId = "cn-shanghai";
/**
* @return 视频ID,根据这个视频ID获取视频链接
*/
public static String uploadVideo() throws IOException {
String title = "标题必须有不能为空";
String fileName = "aa.mp4";// 文件名必须带格式
InputStream videoStream = Files.newInputStream(Paths.get("C:\\Users\\aa.mp4"));
// 这个类是com.aliyun.vod.upload.req.UploadStreamRequest
UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName,
videoStream);
// 是否加水印
request.setShowWaterMark(false);
request.setTags("标签1,标签2,多个用逗号隔开");
request.setDescription("视频描述");
request.setCoverURL("视频封面地址");
// 设置上传完成后的回调URL(可选),建议通过点播控制台配置消息监听事件,参见文档
// request.setCallback("http://callback.sample.com");
// 自定义消息回调设置,参数说明参考文档,https://help.aliyun.com/document_detail/86952.html#UserData
// request.setUserData(""{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}"");
// 视频分类ID(可选)
// request.setCateId(0);
// 模板组ID(可选)
// request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56a33d");
// 工作流ID(可选)
// request.setWorkflowId("d4430d07361f0*be1339577859b0177b");
// 存储区域(可选)
// request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com");
// 开启默认上传进度回调
// request.setPrintProgress(true);
// 设置自定义上传进度回调 (必须继承 VoDProgressListener)
// request.setProgressListener(new PutObjectProgressListener());
// 设置应用ID
// request.setAppId("app-1000000");
// 点播服务接入点
// request.setApiRegionId("cn-shanghai");
// ECS部署区域
// request.setEcsRegionId("cn-shanghai");
UploadVideoImpl uploader = new UploadVideoImpl();
UploadStreamResponse response = uploader.uploadStream(request);
return response.getVideoId();
}
/**
* <p>获取视频地址
*
* @return 会返回多个地址,如果list长度为0,则应该业务处理该异常
*/
public static List<String> getVideoUri(String videoId) {
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
GetPlayInfoResponse response = new GetPlayInfoResponse();
List<String> uris = new ArrayList<>();
try {
GetPlayInfoRequest request = new GetPlayInfoRequest();
request.setVideoId(videoId);
response = client.getAcsResponse(request);
List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
uris.add(playInfo.getPlayURL());
}
// Base信息
// response.getVideoBase().getTitle()
} catch (Exception e) {
e.printStackTrace();
}
return uris;
}
/**
* <p>获取视频相关信息,注意,该方法不会获取视频本身(视频路径以及视频流),而是获取诸如描述,标签,标题等内容
*/
public static void getVideoInfo() {
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
GetVideoInfoResponse response = new GetVideoInfoResponse();
try {
GetVideoInfoRequest request = new GetVideoInfoRequest();
request.setVideoId("视频ID,一个32长度的字符串,类似40a53db847e54b17bc799b3566ea5218");
response = client.getAcsResponse(request);
System.out.print("Title = " + response.getVideo().getTitle() + "\n");
System.out.print("Description = " + response.getVideo().getDescription() + "\n");
} catch (Exception e) {
System.out.print("ErrorMessage = " + e.getLocalizedMessage());
}
System.out.print("RequestId = " + response.getRequestId() + "\n");
}
/**
* <p>上传封面图片
*
* @param imageStream 封面图片流
*
* @return 图片URI
*/
public static String uploadCoverImage(InputStream imageStream) {
return uploadImage(imageStream, "cover");
}
/**
* <p>上传封面图片
*
* @param imageStream 封面图本地绝对路径
*
* @return 图片URI
*/
public static String uploadCoverImage(String uri) {
try {
InputStream in = Files.newInputStream(Paths.get(uri));
return uploadImage(in, "cover");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("上传封面图片异常");
}
}
/**
* <p>图片上传,注意,该上传图片是OSS视频相关的上传图片,和普通上传图片略有不同
*
* @param imageStream 封面图片流
* @param imageType 必选,图片类型,用字符串表示default(默认),cover(封面),watermark(水印)
*
* @return 图片URI
*/
private static String uploadImage(InputStream imageStream, String imageType) {
UploadImageRequest request = new UploadImageRequest(accessKeyId, accessKeySecret, imageType);
request.setInputStream(imageStream);
// 图片文件扩展名(可选)取值范围:png,jpg,jpeg
// request.setImageExt("png");
// 图片标题(可选)长度不超过128个字节,UTF8编码
// request.setTitle("图片标题");
// 图片标签(可选)单个标签不超过32字节,最多不超过16个标签,多个用逗号分隔,UTF8编码
// request.setTags("标签1,标签2");
// 存储区域(可选)
// request.setStorageLocation("out-4f3952f78c0211e8b3020013e7.oss-cn-shanghai.aliyuncs.com");
// 流式上传时,InputStream为必选,fileName为源文件名称,如:文件名称.png(可选)
// request.setFileName("测试文件名称.png");
// 开启默认上传进度回调
// request.setPrintProgress(true);
// 设置自定义上传进度回调 (必须继承 VoDProgressListener)
// request.setProgressListener(new PutObjectProgressListener());
// 设置应用ID
// request.setAppId("app-1000000");
// 开始上传图片
UploadImageImpl uploadImage = new UploadImageImpl();
UploadImageResponse response = uploadImage.upload(request);
if (response.isSuccess()) {
return response.getImageURL();
} else {
System.out.print("ErrorCode=" + response.getCode() + "\n");
System.out.print("ErrorMessage=" + response.getMessage() + "\n");
throw new RuntimeException(
"ErrorCode=" + response.getCode() + "\nErrorMessage=" + response.getMessage() + "\n");
}
}