.Net Core MVC使用阿里云Vod视频点播批量上传视频
目前公司资源需要从服务器上转移至阿里云Vod(视频点播)上,仔细看了下阿里云相关文档,发现只有.Net 视频点播SDK并没有Vod OSS上传的SDK,如果想要使用的话,也只有通过其他的SDK上传或者自己计算阿里云的签名封装一个。。。
这里介绍的就是使用JavaScript的SDK进行上传,后端使用.Net Core 来获取视频凭证
后端环境
.Net Core 2.2
通过Nuget
aliyun-net-sdk-core
aliyun-net-sdk-vod
前端
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/aliyunvod/aliyun-upload-sdk-1.5.0.min.js"></script>
<script src="~/js/aliyunvod/lib/aliyun-oss-sdk-5.3.1.min.js"></script>
什么是视频点播
视频点播有点类似于Oss对象存储,实际上也是OSS一个东西,不同的是视频点播专精于视频处理,提供了转码、播放、分析、审核等,功能是很多,代价嘛。。当然是很贵的,反正各位看官,更具自己需求慎用!
前期准备
开通视频点播,计费模式选择后付费就好了,上传几十G也没有几块钱,用来测试,足够用了,上传和不转码都不收费,转码的话,分辨率和码率越高,价格越贵,详细价格点击传送门
当然了解了这些之后,需要我们开通阿里云的AccessKey来进行访问点击进行设置
做完之后,我们下载阿里云的相关SDK并引用至项目中
Vod 视频点播SDK
JavaScript上传SDK
至于jQuery的。。。自己百度吧
上传思路
实例化VodUpload类,用户选择上传文件后,使用uploader.addFile(event.target.files[i], null, null, null, userData)方法,将文件添加至上传列表。这时候我们可以设定一些媒体相关属性。使用SDK中内置方法,可以对上传列表进行增删改等操作。
对上传列表完成设置后,使用startUpload方法进行上传。
上传方法调用后,开始上传的回调里,获取并设置视频的上传凭证(upload_auth)和上传地址(upload_address)。
流程图通俗的来讲就是选择文件>>创建vod对象>>添加文件>>通过文件信息向后端获取上传凭证和地址(这时候在视频点播控制台只能看到一个视频的标题和视频id还有相关的存储信息,有点像我们把抗挖好了,就等待往里面灌水了)>>使用JavaScript的SDK进行上传>>返回上传完成
大致流程就是这样的,批量上传和单个上传都是一样的流程
后端代码
我是封装了一个类来使用的,具体使用方式看根据自己需求,可以卸载控制器下面
视频凭证类
public class Aliyun_Vod_UploadVideo
{
public static readonly string AccessKey = "自己的key";
public static readonly string AccessKeySecret = "自己的Secret";
public static readonly string regionId = "自己的存储地址区域";
public static readonly string RemoteStorageLocation = "存储地址";
public static readonly long CateId = 分类的id;
public static readonly string TemplateGroupId = "转码模组的ID";
public DefaultAcsClient InitVodClient()
{
IClientProfile profile = DefaultProfile.GetProfile(regionId, AccessKey, AccessKeySecret);
return new DefaultAcsClient(profile);
}
public CreateUploadVideoResponse GetUploadURL(string title,string fileName)
{
try
{
// 构造请求
CreateUploadVideoRequest request = new CreateUploadVideoRequest();
request.Title = title;//"测试视频";
request.FileName = fileName; // "测试视频上传.mp4";
request.CateId = CateId;
request.TemplateGroupId = TemplateGroupId;
// 初始化客户端
DefaultAcsClient client = InitVodClient();
// 发起请求,并得到响应结果
CreateUploadVideoResponse response = client.GetAcsResponse(request);
return response;
}
catch (ServerException ex)
{
Console.WriteLine(ex.ToString());
return null;
}
catch (ClientException ex)
{
Console.WriteLine(ex.ToString());
return null;
}
}
public RefreshUploadVideoResponse RefreshUploadURL(string videoId)
{
try
{
// 构造请求
RefreshUploadVideoRequest request = new RefreshUploadVideoRequest();
request.VideoId = videoId;
// 初始化客户端
DefaultAcsClient client = InitVodClient();
// 发起请求,并得到 response
RefreshUploadVideoResponse response = client.GetAcsResponse(request);
Console.WriteLine("RequestId = " + response.RequestId);
Console.WriteLine("UploadAddress = " + response.UploadAddress);
Console.WriteLine("UploadAuth = " + response.UploadAuth);
return response;
}
catch (ServerException ex)
{
Console.WriteLine(ex.ToString());
return null;
}
catch (ClientException ex)
{
Console.WriteLine(ex.ToString());
return null;
}
}
}
控制器方法
/// <summary>
/// 创建视频凭证 接口
/// </summary>
/// <returns></returns>
public JsonResult ICreateUploadVideo(string title, string fileName)
{
Aliyun_Vod_UploadVideo aliyun_Vod = new Aliyun_Vod_UploadVideo();
CreateUploadVideoResponse response = aliyun_Vod.GetUploadURL(title, fileName);
VodModel vodMode = new VodModel
{
RequestId = response.RequestId,
UploadAddress = response.UploadAddress,
UploadAuth = response.UploadAuth,
VideoId = response.VideoId
};
AppendExcel(fileName, vodMode.VideoId);
return Json(vodMode);
}
前端代码
@{
ViewData["Title"] = "UploadVideo";
}
<h1>UploadVideo</h1>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/aliyunvod/aliyun-upload-sdk-1.5.0.min.js"></script>
<script src="~/js/aliyunvod/lib/aliyun-oss-sdk-5.3.1.min.js"></script>
<input type="file" class="layui-btn" value="添加上传" id="fileUpload" multiple />
<label class="layui-text">上传状态:<span id="status"></span></label>
<input type="button" class="layui-btn" value="开始上传" id="authUpload" disabled="true" />
<input type="button" class="layui-btn" value="暂停上传" id="pauseUpload" disabled="true" />
<input type="button" class="layui-btn" value="恢复上传" id="resumeUpload" disabled="true" />
<span class="progress">上传进度<i id="auth-progress">0</i>%</span>
<table class="layui-table" id="tab">
<thead>
<tr>
<th width="30%">文件名</th>
<th>视频id</th>
<th>状态</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<input type="button" class="layui-btn" value="插入" id="addTable" />
<script>
$(document).ready(function () {
//创建上传对象
function createUploader() {
var uploader = new AliyunUpload.Vod({
timeout: 90000,
partSize: 1048576,
parallel: efile.target.files.length,//文件多少,就设置多少
retryCount: 3,
retryDuration: 2,
region: '储存地址区域',
userId: '阿里云id',
// 添加文件成功
addFileSuccess: function (uploadInfo) {
console.log('addFileSuccess')
$('#authUpload').attr('disabled', false)
$('#resumeUpload').attr('disabled', false)
$('#status').text('添加文件成功, 等待上传...')
console.log("添加文件名addFileSuccess: " + uploadInfo.file.name)
},
onUploadstarted: function (uploadInfo) {
// 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
// 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值,调用点播的不同接口获取uploadauth和uploadAddress
// 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
// 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
// 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
// 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
if (!uploadInfo.videoId) {
var fileName = uploadInfo.file.name
//自定义上传接口
var createUrl = 'https://localhost:44325/vod/ICreateUploadVideo?title=' + fileName + '&fileName=' + fileName
console.log('上传凭证请求接口:' + createUrl)
$.get(createUrl, function (data) {
console.log('返回上传地址和上传凭证:' + data);
var uploadAuth = data.uploadAuth
var uploadAddress = data.uploadAddress
var videoId = data.videoId
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
}, 'json')
$('#status').text('文件开始上传...')
} else {
// 如果videoId有值,根据videoId刷新上传凭证
var refreshUrl = 'https://localhost:44325/vod/IRefreshUploadVideo?videoId=' + uploadInfo.videoId
var fileName = uploadInfo.file.name
//自定义上传接口
//afaf8aa3d3e2489fb55a5601f076d3d1这里会莫名多出一个id,由于时间问题,所以这边我直接调用了视频接口,没有调用刷新凭证接口
var createUrl = 'https://localhost:44325/vod/ICreateUploadVideo?title=' + fileName + '&fileName=' + fileName
$.get(createUrl, function (data) {
var uploadAuth = data.uploadAuth
var uploadAddress = data.uploadAddress
var videoId = data.videoId
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
}, 'json')
}
},
// 文件上传成功
onUploadSucceed: function (uploadInfo) {
console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
$('#status').text('文件上传成功!')
$('#tab').append('<tr><td>' + uploadInfo.file.name + '</td><td>' + uploadInfo.videoId + '</td><td>'+uploadInfo.file.name+'>>文件已上传完成</td></tr>')
},
// 文件上传失败
onUploadFailed: function (uploadInfo, code, message) {
console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message)
$('#status').text('文件上传失败!')
},
// 取消文件上传
onUploadCanceled: function (uploadInfo, code, message) {
console.log("Canceled file: " + uploadInfo.file.name + ", code: " + code + ", message:" + message)
$('#status').text('文件上传已暂停!')
},
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress: function (uploadInfo, totalSize, progress) {
console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(progress * 100) + "%")
var progressPercent = Math.ceil(progress * 100)
$('#auth-progress').text(progressPercent)
$('#status').text('文件上传中...')
},
// 上传凭证超时
onUploadTokenExpired: function (uploadInfo) {
// 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
// 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
// 然后调用 resumeUploadWithAuth 方法, 这里是测试接口, 所以我直接获取了 UploadAuth
$('#status').text('文件上传超时!')
let refreshUrl = 'https://localhost:44325/vod/IRefreshUploadVideo?videoId=' + uploadInfo.videoId
$.get(refreshUrl, function (data) {
var uploadAuth = data.uploadAuth
uploader.resumeUploadWithAuth(uploadAuth)
console.log('upload expired and resume upload with uploadauth ' + uploadAuth)
}, 'json')
},
// 全部文件上传结束
onUploadEnd: function (uploadInfo) {
$('#status').text('所有文件全部上传完毕!')
console.log("onUploadEnd: uploaded all the files")
}
})
return uploader
}
var uploader = null
var efile;
//选择上传文件
$('#fileUpload').on('change', function (e) {
efile = e;
startUploadVido(efile)
})
var startUploadVido = function (file) {
if (!file) {
alert("请先选择需要上传的文件!")
return
}
var Title = file.name
var userData = '{"Vod":{}}'
if (uploader) {
uploader.stopUpload()
$('#auth-progress').text('0')
$('#status').text("")
}
uploader = createUploader()
// 首先调用 uploader.addFile(event.target.files[i], null, null, null, userData)
//批量添加文件上传
for (var i = 0; i < file.target.files.length; i++) {
uploader.addFile(file.target.files[i], null, null, null, userData)
}
$('#authUpload').attr('disabled', false)
$('#pauseUpload').attr('disabled', true)
$('#resumeUpload').attr('disabled', true)
var tempInt;
var bool = true
}
// 第一种方式 UploadAuth 上传
$('#authUpload').on('click', function () {
// 然后调用 startUpload 方法, 开始上传
if (uploader !== null) {
uploader.startUpload()
$('#authUpload').attr('disabled', true)
$('#pauseUpload').attr('disabled', false)
}
})
// 暂停上传
$('#pauseUpload').on('click', function () {
if (uploader !== null) {
uploader.stopUpload()
$('#resumeUpload').attr('disabled', false)
$('#pauseUpload').attr('disabled', true)
}
})
//恢复上传
$('#resumeUpload').on('click', function () {
if (uploader !== null) {
uploader.startUpload()
$('#resumeUpload').attr('disabled', true)
$('#pauseUpload').attr('disabled', false)
}
})
})
</script>
大部分代码阿里云提供了示例,当然直接复制我这个代码也是可以直接使用的,测试了一次性上传2000个视频,接近300GB,一晚上全部上传完毕,很稳定,没有出现异常,在如果视频id存在,而调用了刷新凭证接口后端会抛出该视频id不存在的异常,所以我直接调用了创建新的视频id接口,未发现异常,解决了的这个问题的朋友可以留言分享下