使用JavaScript SDK上传文件

本文介绍如何使用JavaScript SDK将媒体文件(本地文件或网络文件)从客户端上传至点播存储,提供相关SDK的集成及文件上传指引。

前提条件

  • 您已经完成上传相关的系统配置,包括启用目标存储地域的存储地址和配置回调。操作指引请参见管理存储Bucket回调设置

  • 您已准备好用于调用点播服务的账号。为避免阿里云账号AccessKey泄露带来的安全风险,推荐您创建RAM用户并授予其VOD相关权限。然后使用RAM用户的AK对(AccessKey ID和AccessKey Secret)访问点播服务。操作指引请参见创建RAM用户并授权

  • JavaScript上传SDK目前兼容的浏览器是:

    • IE 10及以上版本

    • Edge

    • 主流版本的Chrome/Firefox/Safari

    • 主流版本的Android/iOS/WindowsPhone系统默认浏览器

  • 下载SDK代码:V1.5.6 JavaScript上传SDKDemo源码(jquery和Vue)

上传流程

客户端上传SDK封装了OSS上传逻辑。在客户端上传媒体文件时,会直接将文件上传到点播存储(基于OSS),不会再经服务端进行中转,故客户端上传必须进行鉴权,也就是需要您在应用服务器上部署授权服务以获取上传地址和凭证。目前客户端上传SDK支持两种授权方式,两种方式差异对比请参见凭证方式与STS方式对比,推荐使用凭证方式。

上传地址和凭证方式上传流程详解

以集成点播服务端SDK获取上传地址和凭证为例,完整的上传流程如下图所示:客户端SDK上传凭证上传流程

  1. 用户在上传应用服务器上部署授权服务(如集成点播服务端SDK)用于获取上传地址和凭证。

  2. 客户端向上传应用服务器发起请求获取上传地址和凭证。

  3. 上传应用服务器向视频点播服务发起请求获取上传地址和凭证。

  4. 点播服务返回上传地址和凭证。

    说明

    点播服务在下发上传地址和凭证时还会自动创建媒资信息,即媒体ID(MediaId),用于媒资生命周期管理或媒体处理。

    • 获取音视频上传地址和凭证返回的VideoId即媒体ID。

    • 获取图片上传地址和凭证返回的ImageId即媒体ID。

    • 获取辅助媒资上传地址和凭证返回的MediaId即媒体ID。

    • 请妥善保存媒体ID,作为媒资管理、音视频播放、媒体处理等的输入。

  5. 上传应用服务器向客户端下发上传地址和凭证。

    说明

    下发地址和凭证即可,无需Base64解码。

  6. 客户端使用上传地址和凭证初始化上传实例。

  7. 客户端构造上传参数发起上传请求。

  8. OSS服务返回上传结果。

    说明

    上传结果也可以通过提前配置回调接收上传相关事件来监听。

STS方式上传流程详解

如需使用STS临时授权方式(阿里云Security Token Service)访问点播服务,请为RAM用户创建角色并授予角色VOD相关权限。操作指引请参见使用STS临时授权方案上传视频

使用STS方式上传的完整的流程如下图所示:客户端STS方式上传流程

  1. 用户在上传应用服务器上部署授权服务(如集成阿里云STS SDK)用于获取STS临时Token。

  2. 客户端向上传应用服务器发起请求获取STS临时Token。

  3. 上传应用服务器向阿里云STS服务发起请求获取STS临时Token。

  4. 阿里云STS服务返回上传地址和凭证。

  5. 上传应用服务器向客户端下发STS临时Token。

  6. 客户端使用STS临时Token初始化上传实例。

  7. 客户端构造请求发起上传请求。

  8. OSS服务返回上传结果。

    说明

    上传结果也可以通过提前配置回调接收上传相关事件来监听。

上传凭证

说明

此处以音视频上传凭证为例进行说明,图片上传凭证需调用CreateUploadImage - 获取图片上传地址和凭证接口获取。

  • 设置上传地址和上传凭证

    设置上传地址和上传凭证方法在onUploadstarted回调里调用,此回调的参数包含uploadInfo的值。

    const {VideoId,UploadAuth,UploadAddress} = data;
    uploader.setUploadAuthAndAddress(uploadInfo,UploadAuth,UploadAddress,VideoId);

    参数名称

    参数描述

    uploadInfo

    将onUploadstarted回调中的第一个参数进行透传

    uploadAuth

    CreateUploadVideo接口返回

    uploadAddress

    CreateUploadVideo接口返回

    videoId

    CreateUploadVideo接口返回

  • 上传凭证失效后恢复上传

    一般在onUploadTokenExpired回调中调用,用于上传凭证过期后更新上传凭证。uploadAuth为RefreshUploadVideo接口中返回的上传凭证。

    const {VideoId,UploadAuth,UploadAddress} = data;
    uploader.resumeUploadWithAuth(UploadAuth);
  • 设置STS Token

    用于通过STS方式进行上传时,设置上传地址和上传凭证方法。一般在onUploadstarted回调里调用,此回调的参数包含uploadInfo的值。

    var info = data.SecurityTokenInfo
    uploader.setSTSToken(uploadInfo,info.AccessKeyId,info.AccessKeySecret,info.SecretToken);

    参数名称

    参数描述

    uploadInfo

    将onUploadstarted回调中的第一个参数进行透传

    accessKeyId

    CreateSecurityToken接口返回

    accessKeySecret

    CreateSecurityToken接口返回

    secretToken

    CreateSecurityToken接口返回

  • 上传STS Token失效后恢复上传

    一般在onUploadTokenExpired回调中调用,用于通过STS方式进行上传时上传凭证过期后更新上传凭证。

    var info = data.SecurityTokenInfo
    uploader.resumeUploadWithSTSToken(info.AccessKeyId, info.AccessKeySecret, info.SecretToken);

上传文件

使用JavaScript上传SDK上传文件的基本操作步骤如下:

说明
  • 如果Web端上传中断,重新上传可能会产生404报错。您可以将SDK版本升级至1.5.3及以上版本,再重新上传即可。如需使用1.5.3之前版本重新上传,请修改待上传文件名称,不要与上传中断的文件重名,避免报错。

  • 如需实现在一个页面同时上传多个文件,可通过创建多个上传实例来实现。一个上传实例对应一个上传文件,一个上传实例不能同时上传多个文件。

  1. 引入JavaScript上传SDK。

    JavaScript脚本下载,请参见SDK下载。上传SDK当前未提供完整的模块化加载支持,如果通过importrequire引用文件会导致报错ReferenceError: OSS is not defined。可根据业务需要选择使用如下两种引用方式:

    • (推荐)在HTML中通过script引用

      <!--  IE需要es6-promise,目前支持IE 10及以上 -->
        <script src="../lib/es6-promise.min.js"></script>
        <script src="../lib/aliyun-oss-sdk-6.17.1.min.js"></script>
        <script src="../aliyun-upload-sdk-1.5.5.min.js"></script>
    • 模块化引用

      手动将OSS模块的内容赋值给Window,示例代码如下:

      说明

      如果已经在HTML通过script引用,则不需要重复引用。

      import OSS from '../lib/aliyun-upload-sdk/lib/aliyun-oss-sdk-6.17.1.min'
      window.OSS = OSS;
      import '../lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.5.min'
  2. 请求上传地址和凭证请求STS临时Token,用于上传授权。

    JavaScript上传SDK中,文件上传流程包含从AppServer获取上传凭证(需要服务端接入)和文件上传到OSS Server(阿里云能力)两部分。接入JavaScript上传时只需要关心从AppServer获取上传凭证并设置给上传SDK即可,上传凭证支持以下两种获取方式:

    执行结果

    使用获取到的上传地址和凭证或STS临时Token作为入参初始化上传实例。

  3. 使用上传凭证(推荐)或STS临时Token初始化上传实例。

    初始化上传实例分为声明初始化回调和初始化上传实例两步。

    1. 声明初始化回调。

      声明AliyunUpload.Vod初始化回调。以下示例代码为初始化实例时,可传入的配置:

      说明

      视频点播支持的服务地域及对应地域标识请参见点播地域标识

      展开查看代码

      var uploader = new AliyunUpload.Vod({
           // userID,用于标识上传者的身份,必填,有值即可,可以是阿里云账号ID或者您自定义的用户ID,您可以访问阿里云账号中心(https://account.console.aliyun.com/)查看账号ID
           userId:"122",
           // 上传到视频点播的地域,默认值为'cn-shanghai',
           //eu-central-1,ap-southeast-1
           region:"",
           // 分片大小默认1 MB,不能小于100 KB(100*1024)
           partSize: 1048576,
           // 并行上传分片个数,默认5
           parallel: 5,
           // 网络原因失败时,重新上传次数,默认为3
           retryCount: 3,
           // 网络原因失败时,重新上传间隔时间,默认为2秒
           retryDuration: 2,
           // 开始上传
           'onUploadstarted': function (uploadInfo) {
            },
           // 文件上传成功
           'onUploadSucceed': function (uploadInfo) {
            },
           // 文件上传失败
           'onUploadFailed': function (uploadInfo, code, message) {
            },
           // 文件上传进度,单位:字节
           'onUploadProgress': function (uploadInfo, totalSize, loadedPercent) {
            },
           // 上传凭证或STS token超时
           'onUploadTokenExpired': function (uploadInfo) {
            },
           // 全部文件上传结束
           'onUploadEnd':function(uploadInfo){
             }
        });
    2. 初始化上传实例。请根据业务需求选择用上传地址和凭证方式STS方式初始化上传实例。

      onUploadstarted回调中,获取或刷新上传凭证。根据实际情况,选择初始化上传实例的方法。

      • 上传地址和凭证方式(推荐)

        以上传音视频为例,在上传开始后触发的onUploadstarted回调中调用setUploadAuthAndAddress(uploadFileInfo, uploadAuth, uploadAddress,videoId)方法进行设置,上传图片的逻辑与之类似。

        上传音视频示例

        说明

        当获取到的上传凭证(UploadAuth)过期时,会触发onUploadTokenExpired回调,需要调用resumeUploadWithAuth(uploadAuth)方法,设置新的上传凭证继续上传。

        展开查看代码

        //开始上传
        //uploadInfo 包含要上传的文件信息
        // {
        //   videoId: '', // videoId,由服务端返回的音/视频ID
        //   Endpoint: '', // OSS对外服务的访问域名
        //   Bucket: '', // OSS存储空间
        //   Object: '' // OSS存储数据的基本单元
        // }
        'onUploadstarted': function (uploadInfo) {
          // 上传方式,需要根据uploadInfo.videoId是否有值(该值由SDK通过localstorage获取),调用视频点播的不同接口获取uploadauth和uploadAddress
          // 如果videoId有值,调用刷新音视频上传凭证接口,否则调用获取音视频上传地址和凭证接口
          // 上传过程中,如果在点播控制台删除了音频或视频,即videoId不存在了,则会产生冲突,会出现控制台不存在videoId,而浏览器存在videoId的情况,报InvalidVideo.NotFound错误。此时,需手动清除localstorage
          var url = '';
          if (uploadInfo.videoId) {
            //如果uploadInfo.videoId存在,调用刷新音视频上传凭证接口
            url = 'refreshUrl'; // 此处URL需要替换为服务端AppServer对应的地址
          }
          else{
            //如果uploadInfo.videoId不存在,调用获取音视频上传地址和凭证接口
            url = 'createUrl'; // 此处URL需要替换为您自己服务端的“获取音视频上传地址和凭证”接口的对应服务地址,例如:https://xxxx.com/createUploadVideo
          }
        
          // 以下请求实现为示例,用于演示设置凭证
          // 获取UploadAuth, UploadAddress, VideoId可能因您自有服务端的实现有差异
          fetch(url)
            .then((res) => res.json())
            .then((data) => {
                uploader.setUploadAuthAndAddress(uploadInfo, data.uploadAuth, data.uploadAddress, data.videoId);
          });
        },
        
        //上传凭证超时
        'onUploadTokenExpired': function (uploadInfo) {
          //实现时,根据uploadInfo.videoId调用刷新音视频上传凭证接口重新获取UploadAuth
          //从点播服务刷新的uploadAuth,设置到SDK里
        
          var url = 'refreshUrl'; // 此处URL需要替换为您自己服务端的“获取音视频上传地址和凭证”接口的对应服务地址,例如:https://xxxx.com/createUploadVideo
          // 以下请求实现为示例,用于演示设置凭证
          // 获取UploadAuth, UploadAddress, VideoId可能因您自有服务端的实现有差异
          fetch(url)
            .then((res) => res.json())
            .then((data) => {
            uploader.resumeUploadWithAuth(data.UploadAuth);
          });
        },

        上传图片示例

        说明

        图片凭证超时目前不支持刷新凭证操作,若凭证超时请您重新获取凭证进行上传,此前的ImageId将失效,您可以选择删除此ImageId。

        展开查看代码

        //开始上传
        //uploadInfo 包含要上传的文件信息
        // {
        //   ImageId: '', // ImageId,由服务端返回的图片媒资ImageId
        //   Endpoint: '', // OSS对外服务的访问域名
        //   Bucket: '', // OSS存储空间
        //   Object: '' // OSS存储数据的基本单元
        // }
        'onUploadstarted': function (uploadInfo) {
          // 上传方式,需要根据uploadInfo.ImageId是否有值(该值由SDK通过localstorage获取),调用视频点播的不同接口获取uploadauth和uploadAddress
          // 上传过程中,如果在点播控制台删除了图片,即ImageId不存在了,则会产生冲突,会出现控制台不存在imageId,而浏览器存在imageId的情况,会出现NotFound错误。此时,需手动清除localstorage
          var url = 'createUrl';   // 此处URL需要替换为您自己服务端的“获取图片上传地址和凭证”接口的对应服务地址,例如:https://xxxx.com/createUploadImage
          // 获取UploadAuth, UploadAddress, ImageId可能因您自有服务端的实现有所差异
          fetch(url)
            .then((res) => res.json())
            .then((data) => {
                uploader.setUploadAuthAndAddress(uploadInfo, data.UploadAuth, data.UploadAddress, data.ImageId);
          });
        }
        
      • STS方式

        在上传开始后触发的onUploadstarted回调中调用setSTSToken(uploadInfo, accessKeyId, accessKeySecret, secretToken);方法进行设置。

        说明

        当STS临时Token超时,会触发onUploadTokenExpired回调,需要调用resumeUploadWithSTSToken(accessKeyId, accessKeySecret, secretToken)方法,设置新的STS继续上传。

        展开查看代码

        onUploadstarted: function (uploadInfo) {
          // 如果是STSToken上传方式, 需要调用uploader.setUploadAuthAndAddress方法
          var stsUrl = 'stsUrl';
          // 以下请求实现为示例,用于演示设置凭证
          // 获取 accessKeyId, accessKeySecret,secretToken 可能因您自有服务端的实现有差异
          fetch(stsUrl)
            .then((res) => res.json())
            .then((data) => {
            var info = data.SecurityTokenInfo
            uploader.setSTSToken(uploadInfo, info.AccessKeyId, info.AccessKeySecret, info.SecretToken);
          });
        },
        
        onUploadTokenExpired: function (uploadInfo) {
          // 如果是上传方式二即根据STSToken实现时,从新获取STS临时账号用于恢复上传
          // 上传文件过大时可能在上传过程中sts token就会失效, 所以需要在token过期的回调中调用resumeUploadWithSTSToken 方法
        
          var stsUrl = 'stsUrl';
          // 以下请求实现为示例,用于演示设置凭证
          // 获取 accessKeyId, accessKeySecret,secretToken 可能因您自有服务端的实现有差异
          fetch(stsUrl)
            .then((res) => res.json())
            .then((data) => {
            var info = data.SecurityTokenInfo
            uploader.resumeUploadWithSTSToken(info.AccessKeyId, info.AccessKeySecret, info.SecretToken);
          });
        },
  4. 根据上传的文件类型构造上传参数。

    1. 选择上传文件。

       <form action="">
         <input type="file" name="file" id="files" multiple/>
       </form>
       userData = '';
       document.getElementById("files")
        .addEventListener('change', function (event) {
          for(var i=0; i<event.target.files.length; i++) {
            //逻辑代码
          }
        });
    2. 将选中的文件添加到上传列表中。

      uploader.addFile(file,null,null,null,'{"Vod":{}}');

      参数名称

      是否必填

      类型

      参数描述

      file

      File

      需要上传的音视频文件。

      endpoint

      String

      想要上传到的endpoint,传入null则由服务端决定。

      bucket

      String

      想要上传到的bucket,传入null则由服务端决定。

      object

      String

      想要上传到的object,传入null则由服务端决定。

      paramData

      String

      当您使用STS方式上传时,可以通过paramData设置音视频或图片的标题、描述等信息,以及设置对音视频的转码、回调等。

      paramData是一个JSON对象字符串,第一级的Vod是必须的,通过在Vod下添加paramData设置属性实现。支持设置的属性,请参见CreateUploadVideo - 获取音视频上传地址和凭证CreateUploadImage - 获取图片上传地址和凭证

      接口示例如下:

      说明
      • paramData只有在STS方式上传时需要在SDK指定,如果是上传地址和凭证方式,则在获取上传凭证的接口(CreateUploadVideo或CreateUploadImage)的参数里指定,无需在SDK里指定paramData参数。

      • 如果同时传递了WorkflowId和TemplateGroupId,以WorkflowId为准。

      • 设置名称和分类

        var paramData = '{"Vod":{"Title":"test","CateId":"234"}}';
      • 设置名称和转码

        var paramData = '{"Vod":{"Title":"test","TemplateGroupId":"e6bb587b5365ac38a41462a4940****"}}';
      • 设置名称和工作流

        var paramData = '{"Vod":{"Title":"test","WorkflowId":"e2d027f16b5ee9cdf126266d32d****"}}';
  5. 开始上传。

    1. 调用startUpload()方法开始上传。

      uploader.startUpload();
    2. 文件开始上传后,onUploadProgress回调开始同步上传进度。

    3. 文件上传成功后,onUploadSucceed回调会返回上传结果。

执行结果

  • 音视频上传成功后会返回videoId作为音视频ID,拿到videoId后需要获取播放地址进行播放。更多信息,请参见通过播放凭证播放

  • 图片上传完成后不会返回imageUrl,可事先配置回调事件为图片上传完成回调设置,待收到图片上传完成的事件通知后,在该事件通知中可以获取到图片的URL(FileURL)。开启URL鉴权后URL会有过期时间。更多信息,请参见配置URL鉴权

高级功能

上传控制

停止上传

说明

stopUpload要确保文件正在上传,有文件上传进度时才能工作。

uploader.stopUpload();

队列管理

对于上传中或者上传完成的文件,可以通过对应的API进行管理。支持的API如下:

  • 获取上传文件列表

    返回值为通过addFile添加的文件信息列表。其中的file属性为对应的File类型的文件,可以通过遍历获取到需要操作的文件的index。

    var list = uploader.listFiles();
    for (var i=0; i<list.length; i++) {
        log("file:" + list[i].file.name);
    }
  • 删除上传文件

    uploader.deleteFile(index);//需要删除的文件index,对应listFiles接口返回列表中元素的索引
  • 取消单个文件上传

    说明
    • cancelFile成功后会在控制台打印oss is cancel as error。这是SDK为了避免已上传的部分分片文件占用存储空间(如果占用就会产生存储费用)做的处理。

    • 取消文件上传后,如果后续还需要继续上传该文件,则需要先使用uploader.resumeFile(index);恢复该文件后,再进行上传。

    uploader.cancelFile(index);
  • 恢复单个文件上传

    uploader.resumeFile(index);
  • 清理上传文件列表

    uploader.cleanList();

断点续传

在音视频上传过程中,由于某种原因(例如:页面被关闭、浏览器崩溃等)没有上传完成,下次选择同一个文件上传时, SDK会从上次完成的位置继续上传,并在onUploadstarted回调中获取上传凭证。使用上传地址和凭证方式上传时,用户可以根据回调返回的videoId的值,调用视频点播的接口获取断点信息。示例如下:

onUploadstarted: function (uploadInfo) {
if (上传方式1) {
  if(!uploadInfo.videoId)//这个文件没有上传异常
  {
    //实际环境中调用视频点播的获取上传凭证接口
    uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId);
  }
  else//如果videoId有值,根据videoId刷新上传凭证
  {
    //实际环境中调用视频点播的刷新上传凭证接口,获取凭证
    uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress);
  }
}
else(上传方式2)
{
   //实际环境中调用获取STS接口,获取STS的值
   uploader.setSTSToken(uploadInfo, accessKeyId, accessKeySecret,secretToken);
}
}

获取断点信息:

 uploader.getCheckpoint(file);