最近做的项目是一个水运头条项目,其中有个小视频上传的功能.起初项目评审技术讨论时,决定将视频上传至阿里云的VOD资源服务器,需要的时候就从阿里云的VOD去取就行了.为什么要上传到阿里云的VOD资源服务器了?主要是因为阿里云的VOD资源服务器有转码,自动截取封面图,加水印功能.其次减少我们服务器的压力.再就是收费也不贵.不过这过程真的是一波三折呀.
First 我们起初是打算后台从阿里云的VOD获取上传凭证和上传地址(小程序上传文件到阿里云的VOD需要先获取上传凭证和上传地址,这是阿里云规定的),然后小程序根据上传凭证和上传地址等参数调用VOD提供的SDK将视频文件上传到阿里云的VOD.后面证实这种解决方案是可行的,只是与我们的实际业务不太合适,兼容性也不是很好,被否定了.
Second 我们打算后台接受到小程序传递过来的视频文件,然后后台将其作为流给下载下来保存到本地.然后将视频文件再通过本地上传到阿里云的VOD.后面证实也是可行的,只是这样走了服务器,有些视频又很大,且如果大量用户上传视频会增加服务器的压力,这种方案也被否定了.不过我下面的示例代码却是这种,原因是我在写这个接口的时间耗费的时间与我预期的不太符合.
Third 我们打算小程序将文件上传到阿里云的OSS文件资源服务器,然后小程序根据返回地址(小视频在OSS上的地址),去调用后台上传文件接口.后台根据小程序传过来阿里云的OSS地址通过网络流的形式将文件上传到阿里云的VOD了.这样一来服务器的压力也小了,后面证明这种是可行的,且效果也是最好的,这种方案也被采纳了.
前端:
legenIndexViewTap: function() {
wx.chooseImage({
count: 1,
sizeType: ['orignal', 'compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
var tempFilePaths = res.tempFilePaths[0];
wx.uploadFile({
url: url,
filePath: tempFilePaths,
name: 'video',
formData: {
userId: value1,
filePath:tempFilePaths//后台参数filePath
},
success: function (res) {
var data = res.data
console.log(data)
},
fail:function(){
console.log("fail");
}
});
console.log(tempFilePaths);
},
fail: function () {
console.log("fail");
},
complete: function () {
console.log("complete");
}
})
//wx.navigateTo({
// url: '../doctor/doctor_zone'
// })
}
后台:
/**
* 服务器接受从小程序传过来的视频
*
* @param file
* @param createUploadVideoRequest
* @return
* @throws IOException
*/
@PostMapping(value = {"/video/upload/servertoaliyun"})
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public Object uploadDiagFile(@RequestParam("video") MultipartFile file, HttpServletRequest request, HttpServletResponse response, CreateUploadVideoRequest createUploadVideoRequest) throws IOException {
// 先判断文件是否为空
try {
if (!file.isEmpty()) {
// 获得原始文件名
String fileName = file.getOriginalFilename();
// 重命名文件
String newfileName = new Date().getTime() + String.valueOf(fileName);
// 本地文件存储路径
String pathRoot = props.getProperty(key);
// 项目下相对路径
String path = newfileName;
File downloadFile = new File(pathRoot + path);
if (!downloadFile.exists()) {
downloadFile.createNewFile();
}
//下载本地
boolean flag = download(file,request, response, newfileName);
if (flag) {
//将本地文件上传到阿里云VOD
String result = iUploadFile.upLoadFile(ossFileUrl);
return "success";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "fail";
}
/**
* 服务下载视频到本地
*
* @param file
* @param createUploadVideoRequest
* @return
* @throws IOException
*/
public static boolean download(MultipartFile file,HttpServletRequest request, HttpServletResponse response, String realName) throws Exception {
boolean flag = false;
try {
response.setContentType("application/json;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
String downLoadPath = props.getProperty(key);
long fileLength = new File(downLoadPath+realName).length();
response.setHeader("Content-disposition", "attachment; filename="
+ new String(realName.getBytes("utf-8"), "ISO8859-1"));
bis = new BufferedInputStream(file.getInputStream());
bos = new BufferedOutputStream(new FileOutputStream(new File(downLoadPath+realName)));
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
bis.close();
bos.close();
flag = true;
} catch (IOException e) {
e.printStackTrace();
}
return flag;
}