.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接口,未发现异常,解决了的这个问题的朋友可以留言分享下

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容