关于大文件的保存,一般会保存在阿里云的视频点播上,因为保存在服务器上呢内存有限,而保存在视频点播上不会占用你服务器的资源,阿里云给你提供保存空间,而收取一定的流量费。
参考阿里云的sdk,引入maven:
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.7.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.11.5</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>
maven引入这些包之后,有可能会部分jar包缺失,最好是在官网下载示例,然后手动导入jar包。
建议使用js的上传方式,因为用Java的流上传,流是保存在内存之中,有点吃服务器的内存,多人同时上传会导致服务器卡顿现象,所以一般是使用js上传的方式。
流程如下:
前端发起ajax请求到后台,获取上传视频的凭证,返回给前端,前端获得凭证之后开始上传。
前端代码:
<script src="aliyunvoddemo/libs/aliyun-upload-sdk-1.4.0/lib/es6-promise.min.js"></script>
<script src="aliyunvoddemo/libs/aliyun-upload-sdk-1.4.0/lib/aliyun-oss-sdk-5.2.0.min.js"></script>
<script src="aliyunvoddemo/libs/aliyun-upload-sdk-1.4.0/aliyun-upload-sdk-1.4.0.min.js"></script>
var uploader = new AliyunUpload.Vod({
//分片大小默认1M,不能小于100K
partSize: 1048576,
//并行上传分片个数,默认5
parallel: 5,
//网络原因失败时,重新上传次数,默认为3
retryCount: 3,
//网络原因失败时,重新上传间隔时间,默认为2秒
retryDuration: 2,
// 开始上传
'onUploadstarted': function(uploadInfo) {
console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" +
uploadInfo.bucket + ", object:" + uploadInfo.object);
//上传方式1, 需要根据uploadInfo.videoId是否有值,调用点播的不同接口获取uploadauth和uploadAddress,如果videoId有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
//uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId);
$.ajax({
url: reqUrl + "videoUpload",
data: {
lessonTitle: title
},
dataType: 'json',
type: 'post',
success: function(json) {
var uploadAddress = json.data.UploadAddress;
var uploadAuth = json.data.UploadAuth;
var videoId = json.data.VideoId;
//得到视频上传的凭证
vId = videoId;
//如果此部分执行说明后端返回凭证成功,从data中获取返回的uploadAddress、uploadAuth、videoId,然后调用阿里云的api直接进行文件上传
uploader.setUploadAuthAndAddress(uploadInfo, json.data.UploadAuth, json.data.UploadAddress, json.data.VideoId);
}
});
},
// 文件上传成功
'onUploadSucceed': function(uploadInfo) {
console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" +
uploadInfo.bucket + ", object:" + uploadInfo.object + uploadInfo);
//文件上传成功后执行所需逻辑
},
// 文件上传失败
'onUploadFailed': function(uploadInfo, code, message) {
console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message);
},
// 文件上传进度,单位:字节
'onUploadProgress': function(uploadInfo, totalSize, loadedPercent) {
console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(
loadedPercent * 100) + "%");
//控制台显示进度
},
// 上传凭证超时
'onUploadTokenExpired': function(uploadInfo) {
console.console.log("onUploadTokenExpired");
//上传方式1 实现时,根据uploadInfo.videoId调用刷新视频上传凭证接口重新获取UploadAuth
// uploader.resumeUploadWithAuth(uploadAuth);
// 上传方式2 实现时,从新获取STS临时账号用于恢复上传
// uploader.resumeUploadWithSTSToken(accessKeyId, accessKeySecret, secretToken, expireTime);
},
//全部文件上传结束
'onUploadEnd': function(uploadInfo) {
console.log("onUploadEnd: uploaded all the files");
}
});
var userData = {
Vod: {
UserData: {
IsShowWaterMark: false,
Priority: 7
}
}
};
document.getElementById("file")//
.addEventListener('change', function(event) {
for (var i = 0; i < event.target.files.length; i++) {
// 逻辑代码
uploader.addFile(event.target.files[i], null, null, null, JSON.stringify(userData));
}
uploader.startUpload();
});
后台获取上传的凭证(Java):
public class AliyunUpload {
private static String accessKeyId = "你的秘钥";
private static String accessKeySecret = "你的秘钥";
public static Map getAuth(String title) throws Exception{
Map map = new HashMap();
DefaultAcsClient client = AliyunuploadClientUtils.initVodClient(accessKeyId, accessKeySecret);
CreateUploadVideoRequest request = new CreateUploadVideoRequest();
//将以下信息替换成前端动态传入的文件信息即可
//上传的文件标题
request.setTitle(title);
//上传文件的相关藐视
//request.setDescription("linux");
//上传文件名
request.setFileName(title+".mp4");
CreateUploadVideoResponse response = new CreateUploadVideoResponse();
try {
response = client.getAcsResponse(request);
//将下面是三个参数封装成json串返回给前端,这个json传就相当于一个凭证,该凭证默认的生命周期是3600秒
//VideoId : + response.getVideoId()
//UploadAddress: response.getUploadAddress()
//UploadAuth : + response.getUploadAuth()
System.out.print("VideoId = " + response.getVideoId() + "\n");
System.out.print("UploadAddress = " + response.getUploadAddress() + "\n");
System.out.print("UploadAuth = " + response.getUploadAuth() + "\n");
map.put("code","0");
map.put("VideoId",response.getVideoId());
map.put("UploadAddress",response.getUploadAddress());
map.put("UploadAuth",response.getUploadAuth());
} catch (Exception e) {
System.out.print("ErrorMessage = " + e.getLocalizedMessage());
map.put("code","-1");
}
return map;
}
controller调用该方法,返回json格式即可。
到这里只是视频成功的上传到了阿里云,但是要怎么样得到视频的播放地址呢?
要获取视频的播放地址,需要videoId,同时也需要后台的秘钥认证,所以得到的视频播放地址,也要走后台的流程。代码如下:
public class AliyunuploadClientUtils {
/**
* 初始化客户端
* @param accessKeyId
* @param accessKeySecret
* @return
*/
public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) {
//点播服务所在的Region,国内请填cn-shanghai,不要填写别的区域
String regionId = "cn-shanghai";
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
return client;
}
}
public static GetPlayInfoResponse getPlayInfo(DefaultAcsClient client,String videoId) throws Exception {
GetPlayInfoRequest request = new GetPlayInfoRequest();
request.setVideoId(videoId);
return client.getAcsResponse(request);
}
public static String getUrl(String videoId){
DefaultAcsClient client = AliyunuploadClientUtils.initVodClient("你的秘钥", "你的秘钥");
GetPlayInfoResponse response = new GetPlayInfoResponse();
try {
response = getPlayInfo(client,videoId);
List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
// 播放地址
for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
System.out.print("PlayInfo.PlayURL = " + playInfo.getPlayURL() + "\n");
}
// Base信息
System.out.print("VideoBase.Title = " + response.getVideoBase().getTitle() + "\n");
return playInfoList.get(1).getPlayURL();//会返回两个url,第一个是m3u8格式的,我们用第二个就好
} catch (Exception e) {
System.out.print("ErrorMessage = " + e.getLocalizedMessage());
return null;
}
}