使用OSS SDK上传文件

上传SDK基于OSS SDK封装了部分上传逻辑,简化用户集成操作。如果上传SDK无法满足业务需求或希望更加灵活地控制上传,您也可直接使用OSS SDK上传文件。

OSS SDK

OSS SDK支持Java、Python、Go、PHP、Node.js、Ruby等编程语言,支持iOS、Android、Harmony等客户端,更多信息请参考使用SDK发起请求概述

流程介绍

服务端上传场景

如果您在业务服务器上使用OSS SDK(Java、Python、PHP等编程语言)上传本地文件到OSS Bucket,能够确保AK的安全使用,则可以直接在业务服务器调用点播OpenAPI,获取上传地址和凭证,再调用OSS SDK上传文件。

image

客户端上传场景

如果您在客户端(网页、iOS应用、Android应用)上使用OSS SDK上传本地文件到OSS Bucket,需要在您的业务服务器提前搭建授权服务,客户端调用授权服务获取上传地址和凭证,再从客户端直接向OSS上传文件。

image

说明

  • 应用服务器向点播服务获取上传地址和凭证的操作步骤和示例代码,参考获取上传地址和凭证

  • 返回Base64加密的上传地址(UploadAddress)、上传凭证(UploadAuth)、媒体ID等信息,你需要手动解析参数,将其转为OSS SDK初始化的入参。

    说明
    • UploadAddress字段包含上传的OSS Bucket相关信息,UploadAuth字段包含STS Token等授权信息,请手动使用Base64解码上传地址和凭证,并使用对应字段初始化OSS SDK客户端,参考信息:解析上传地址和凭证说明

    • 点播服务在下发上传地址和凭证时还会自动创建媒资信息,即媒体ID(MediaId),请妥善保存媒体ID,作为媒资管理、音视频播放、媒体处理等的输入。

      • 获取视频上传地址和凭证返回的VideoId

      • 获取图片上传地址和凭证返回的ImageId

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

示例Demo下载

视频点播提供了Demo源码供开发者参考。

程序集成

接下来我们以Java编程语言为例,介绍详细的集成步骤。

前提条件

  • 您已经开通了视频点播服务。开通步骤请参见开通视频点播服务

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

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

  • 已配置环境变量ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET。具体操作,请参见Linux、macOSWindows系统配置环境变量

    重要
    • 阿里云账号的AccessKey拥有所有API的访问权限,建议您使用RAM用户的AccessKey进行API访问或日常运维。

    • 强烈建议不要把AccessKey IDAccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。

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

环境要求

重要
  • 环境要求使用Java 1.8及以上版本。

  • 可在终端执行java -version命令查看Java版本。

示例代码

V1.0 SDK

步骤一、安装依赖

<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-core</artifactId>
  <version>4.6.1</version>
</dependency>
<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-vod</artifactId>
  <version>2.16.32</version>
</dependency>
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.17.4</version>
</dependency>

步骤二、上传(Java代码示例)

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoRequest;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
import org.apache.commons.codec.binary.Base64;

import java.io.File;

/**
 * descript
 */
public class UploadDemo {

    public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
        // 根据点播接入服务所在的Region填写,例如:接入服务在上海,则填cn-shanghai;其他区域请参见媒体上传概述。
        String regionId = "cn-shanghai";
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }

    public static CreateUploadVideoResponse createUploadVideo(DefaultAcsClient vodClient) throws ClientException {
        CreateUploadVideoRequest request = new CreateUploadVideoRequest();
        request.setFileName("vod_test.mp4");
        request.setTitle("this is title");
        //request.setDescription("this is desc");
        //request.setTags("tag1,tag2");
        //CoverURL示例:http://example.aliyundoc.com/test_cover_****.jpg
        //request.setCoverURL("<your CoverURL>");
        //request.setCateId(-1L);
        //request.setTemplateGroupId("");
        //request.setWorkflowId("");
        //request.setStorageLocation("");
        //request.setAppId("app-1000000");
        //设置请求超时时间
        request.setSysReadTimeout(1000);
        request.setSysConnectTimeout(1000);
        return vodClient.getAcsResponse(request);
    }

    public static OSSClient initOssClient(JSONObject uploadAuth, JSONObject uploadAddress) {
        String endpoint = uploadAddress.getString("Endpoint");
        String accessKeyId = uploadAuth.getString("AccessKeyId");
        String accessKeySecret = uploadAuth.getString("AccessKeySecret");
        String securityToken = uploadAuth.getString("SecurityToken");
        return new OSSClient(endpoint, accessKeyId, accessKeySecret, securityToken);
    }

    public static void uploadLocalFile(OSSClient ossClient, JSONObject uploadAddress, String localFile) {
        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");
        File file = new File(localFile);
        ossClient.putObject(bucketName, objectName, file);
    }

    public static void main(String[] argv) {
        // 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
        // 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
        // 本示例通过从环境变量中读取AccessKey,来实现API访问的身份验证。运行代码示例前,请配置环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        //您的AccessKeyId
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        //您的AccessKeySecret
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        //需要上传到VOD的本地视频文件的完整路径,需要包含文件扩展名
        String localFile = "/Users/yours/Video/testVideo.flv";
        try {
            // 初始化VOD客户端并获取上传地址和凭证
            DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
            CreateUploadVideoResponse createUploadVideoResponse = createUploadVideo(vodClient);
            // 执行成功会返回VideoId、UploadAddress和UploadAuth
            String videoId = createUploadVideoResponse.getVideoId();

            JSONObject uploadAuth = JSONObject.parseObject(decodeBase64(createUploadVideoResponse.getUploadAuth()));
            JSONObject uploadAddress = JSONObject.parseObject(decodeBase64(createUploadVideoResponse.getUploadAddress()));

            // 使用UploadAuth和UploadAddress初始化OSS客户端
            OSSClient ossClient = initOssClient(uploadAuth, uploadAddress);
            // 上传文件,注意是同步上传会阻塞等待,耗时与文件大小和网络上行带宽有关
            uploadLocalFile(ossClient, uploadAddress, localFile);
            System.out.println("Put local file succeed, VideoId : " + videoId);
        } catch (Exception e) {
            System.out.println("Put local file fail, ErrorMessage : " + e.getLocalizedMessage());
        }
    }

    private static String decodeBase64(String data) {
        return new String(Base64.decodeBase64(data));
    }
}
                

V2.0 SDK

步骤一、安装依赖

    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>vod20170321</artifactId>
      <version>3.6.4</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea-openapi</artifactId>
      <version>0.3.8</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea-console</artifactId>
      <version>0.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea-util</artifactId>
      <version>0.2.23</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>credentials-java</artifactId>
      <version>1.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun.oss</groupId>
      <artifactId>aliyun-sdk-oss</artifactId>
      <version>3.17.4</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.83</version>
    </dependency>

步骤二、上传(Java代码示例)

说明

工程代码建议使用更安全的无AK方式,凭据配置方式请参见管理访问凭据

package com.aliyun.sample;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.tea.*;
import com.alibaba.fastjson.JSONObject;
import java.io.File;
import org.apache.commons.codec.binary.Base64;

public class Sample {

    /**
     * <b>description</b> :
     * <p>使用凭据初始化账号Client</p>
     * @return Client
     * 
     * @throws Exception
     */
    public static com.aliyun.vod20170321.Client createClient() throws Exception {
        com.aliyun.credentials.models.Config creditConfig = new com.aliyun.credentials.models.Config();
        creditConfig.setType("access_key")
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));

        com.aliyun.credentials.Client credential = new com.aliyun.credentials.Client(creditConfig);
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                .setCredential(credential);
        // Endpoint 请参考 https://api.aliyun.com/product/vod
        config.endpoint = "vod.cn-shanghai.aliyuncs.com";
        return new com.aliyun.vod20170321.Client(config);
    }

    public static void main(String[] args_) throws Exception {
        
        com.aliyun.vod20170321.Client client = Sample.createClient();
        com.aliyun.vod20170321.models.CreateUploadVideoRequest createUploadVideoRequest = new com.aliyun.vod20170321.models.CreateUploadVideoRequest()
                .setFileName("ecs.mp4")
                .setTitle("ecs");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            com.aliyun.vod20170321.models.CreateUploadVideoResponse resp = client.createUploadVideoWithOptions(createUploadVideoRequest, runtime);
            // 执行成功会返回VideoId、UploadAddress和UploadAuth
            String videoId = resp.getBody().videoId;
            String localFile = "/Users/yours/ecs.mp4";

            JSONObject uploadAuth = JSONObject.parseObject(decodeBase64(resp.getBody().uploadAuth));
            JSONObject uploadAddress = JSONObject.parseObject(decodeBase64(resp.getBody().uploadAddress));

            OSS ossClient = initOssClient(uploadAuth, uploadAddress);
            uploadLocalFile(ossClient, uploadAddress, localFile);

            System.out.println("Put local file succeed, VideoId : " + videoId);
        } catch (TeaException error) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }        
    }

    /**
     * 初始化OSS Client
     * @param uploadAuth
     * @param uploadAddress
     * @return
     */
    public static OSS initOssClient(JSONObject uploadAuth, JSONObject uploadAddress) {
        String endpoint = uploadAddress.getString("Endpoint");
        String accessKeyId = uploadAuth.getString("AccessKeyId");
        String accessKeySecret = uploadAuth.getString("AccessKeySecret");
        String securityToken = uploadAuth.getString("SecurityToken");

        com.aliyun.credentials.models.Config creditConfig = new com.aliyun.credentials.models.Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret)
                .setSecurityToken(securityToken);

        DefaultCredentialProvider credentialsProvider = new CredentialsProviderFactory()
                .newDefaultCredentialProvider(accessKeyId, accessKeySecret, securityToken);


        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V1);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(endpoint)
                .build();

        return ossClient;
    }

    /**
     * 上传本地文件
     * @param ossClient
     * @param uploadAddress
     * @param localFile
     * @throws Exception
     */
    public static void uploadLocalFile(OSS ossClient, JSONObject uploadAddress, String localFile) throws Exception {
        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");
        File file = new File(localFile);
        PutObjectResult result = ossClient.putObject(bucketName, objectName, file);
        com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(result));
    }

    /**
     * 解码UploadAuth/UploadAddress
     * @param s
     * @return
     */
    public static String decodeBase64(String s) {
        byte[] b = null;
        String result = null;
        if (s != null) {
            Base64 decoder = new Base64();
            try {
                b = decoder.decode(s);
                result = new String(b, "utf-8");
            } catch (Exception e) {
            }
        }
        return result;
    }
}

参考信息:解析上传地址和凭证说明

Base64解析上传地址(UploadAddress)和上传凭证(UploadAuth),得到OSS的上传地址和授权信息。解析后的上传地址和授权信息可用于初始化OSS客户端。示例代码如下:

  import org.apache.commons.codec.binary.Base64;
  
  
  public static String decodeBase64(String s) {
      byte[] b = null;
      String result = null;
      if (s != null) {
          Base64 decoder = new Base64();
          try {
              b = decoder.decode(s);
              result = new String(b, "utf-8");
          } catch (Exception e) {
          }
      }
      return result;
  }

表 1. UploadAddress解析后字段

字段

描述

Bucket

点播存储地址。

Endpoint

点播存储地域标识。

FileName

点播系统为上传文件分配的文件名。

ObjectPrefix

当且仅当上传文件是M3U8文件时返回。

表 2. UploadAuth解析后字段

字段

描述

AccessKeyId

上传用户的AccessKey ID。

AccessKeySecret

上传用户的AccessKey Secret。

SecurityToken

上传授权安全令牌。

ExpireUTCTime

上传地址和凭证过期时间,为UTC时间,格式:yyyy-MM-ddTHH:mm:ssZ。

Expiration

上传授权过期时间,视频为3000秒,过期需要刷新上传凭证。

Region

上传地域标识。