本文通过示例详细介绍如何使用服务端上传SDK(Java语言)将各类媒体文件上传至点播存储。

上传流程

从内部逻辑角度看,Java上传SDK遵循点播服务端SDK的通用流程。详情请参见上传流程。从操作角度看,使用Java上传SDK的基础流程如下:
  1. 完成前提条件。详细信息请参见前提条件
  2. 集成Java上传SDK。详细信息请参见集成Java上传SDK
  3. 实现上传逻辑(主要是上传信息配置)。

前提条件

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

  • 您已经完成上传相关的系统配置,包括启用目标存储地域的存储地址和配置回调。操作指引请参见存储管理回调设置
  • 您已准备好用于调用点播服务的账号。为避免阿里云账号AccessKey泄露带来的安全风险,推荐您创建RAM用户并授予其VOD相关权限。然后使用RAM用户的AK对(AccessKey ID和AccessKey Secret)访问点播服务。操作指引请参见创建RAM用户并授权
  • (可选)如需使用STS临时授权方式(阿里云Security Token Service)访问点播服务,请为RAM用户创建角色并授予角色VOD相关权限。操作指引请参见创建角色并进行STS临时授权
    说明 STS临时授权方式的适用场景请参见凭证方式与STS方式对比

集成Java上传SDK

说明 本文以Java 1.8及以上版本、Java上传SDK 1.4.14版本举例说明集成步骤。其他版本请根据实际情况操作。上传SDK暂不支持依赖,您需要下载并引入jar包。如果集成遇到问题,请参见常见问题排查。
  1. 下载Java上传SDK及示例代码。
    最新版本的下载地址请参见服务端上传SDK。历史版本下载请参见Java上传SDK发布历史
  2. 解压Java上传SDK及示例代码文件。
    以最新版本VODUploadDemo-java-1.4.14.zip为例,解压后的文件如下:
    • lib:存放Java上传SDK所需要的jar包。
    • sample:存放Java上传SDK的示例代码。
  3. 引入Jar包。
    • 如果您在Eclipse环境集成:在Eclipse中右击您的工程,选择Properties > Java Build Path > Add JARs。找到解压后的VODUploadDemo-java-1.4.14文件,并将lib目录下的所有jar文件添加到您的项目中。
    • 如果您在IntelliJ IDEA集成:在IntelliJ IDEA中打开您的工程,选择File > Project Structure > Modules,单击右侧Dependencies,然后单击+,再单击JARs or directories。找到解压后的VODUploadDemo-java-1.4.14文件,并将lib目录下的所有jar文件添加到您的项目中。
    注意 引入Jar包后仍然需要配置依赖。
  4. 添加阿里云Java SDK、OSS SDK、视频点播服务端SDK、视频点播服务端上传SDK等依赖。
    注意
    • 以上依赖必须全部导入,否则会导致集成失败。
    • 使用最新版本Jar包(aliyun-java-vod-upload-1.4.14.jar)时,需保证aliyun-sdk-oss的版本号不低于3.9.0。
    • 目前视频点播已在中国内地发布的区域有上海、深圳、北京。使用上传SDK上传到深圳、北京地域时,需保证aliyun-java-sdk-vod版本号不低于2.15.11、aliyun-java-sdk-core版本号不低于4.4.5。
       <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>
         <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-vod</artifactId>
            <version>2.15.11</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20170516</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.vod</groupId>
            <artifactId>upload</artifactId>
            <version>1.4.14</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/aliyun-java-vod-upload-1.4.14.jar</systemPath>
        </dependency>
                            

音视频上传

普通音视频文件

音视频上传目前支持四种方式上传:
  • 上传本地文件,使用分片上传,并支持断点续传。请参见示例代码中的testUploadVideo函数。
    • 当断点续传关闭时,最大支持上传任务执行时间为3000秒,具体可上传文件大小与您的网络带宽及磁盘读写能力有关。
    • 当断点续传开启时,最大支持48.8 TB的单个文件。
      注意 断点续传开启后,上传任务执行过程中,同时会将当前上传位置写入本地磁盘文件,影响您上传文件的速度,请您根据文件大小选择是否开启。
  • 上传网络流,可指定文件URL进行上传,支持断点续传,最大支持48.8 TB的单个文件。该上传方式需要先将网络文件下载到本地磁盘,再进行上传,所以要保证本地磁盘有充足的空间。请参见示例代码中的testUploadURLStream函数。
  • 上传文件流,可指定本地文件进行上传,不支持断点续传,最大支持5 GB的单个文件。请参见示例代码中的testUploadFileStream函数。
  • 流式上传,可指定输入流进行上传,支持文件流和网络流等,不支持断点续传,最大支持5 GB的单个文件。请参见示例代码中的testUploadStream函数。
注意

在使用示例代码时,需要手动引入对应的类。解决执行代码过程中出现找不到相关依赖等问题,请参见常见问题

示例代码
public class UploadVideoDemo {
    //账号AK信息请填写(必选)
    private static final String accessKeyId = "<Your accessKeyId>";
    //账号AK信息请填写(必选)
    private static final String accessKeySecret = "<Your accessKeySecret>";
public static void main(String[] args) {
    // 视频文件上传
    // 视频标题(必选)
    String title = "测试标题";
    // 1.本地文件上传和文件流上传时,文件名称为上传文件绝对路径,如:/User/sample/文件名称.mp4 (必选)
    // 2.网络流上传时,文件名称为源文件名,如文件名称.mp4(必选)。
    // 3.流式上传时,文件名称为源文件名,如文件名称.mp4(必选)。
    // 任何上传方式文件名必须包含扩展名
    String fileName = "/Users/test/video/test.mp4";
    // 本地文件上传
    testUploadVideo(accessKeyId, accessKeySecret, title, fileName);

    // 待上传视频的网络流地址
    String url = "http://test.aliyun.com/video/test.mp4";

    // 2.网络流上传
    // 文件扩展名,当url中不包含扩展名时,需要设置该参数
    String fileExtension = "mp4";
    testUploadURLStream(accessKeyId, accessKeySecret, title, url, fileExtension);

    // 3.文件流上传
    testUploadFileStream(accessKeyId, accessKeySecret, title, fileName);

    // 4.流式上传,如文件流和网络流
    InputStream inputStream = null;
    // 4.1 文件流
    try {
        inputStream = new FileInputStream(fileName);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    // 4.2 网络流
    try {
        inputStream = new URL(url).openStream();
    } catch (IOException e) {
        e.printStackTrace();
    }
    testUploadStream(accessKeyId, accessKeySecret, title, fileName, inputStream);
}

/**
 * 本地文件上传接口
 *
 * @param accessKeyId
 * @param accessKeySecret
 * @param title
 * @param fileName
 */
private static void testUploadVideo(String accessKeyId, String accessKeySecret, String title, String fileName) {
    UploadVideoRequest request = new UploadVideoRequest(accessKeyId, accessKeySecret, title, fileName);
    /* 可指定分片上传时每个分片的大小,默认为2M字节 */
    request.setPartSize(2 * 1024 * 1024L);
    /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
    request.setTaskNum(1);
    /* 是否开启断点续传, 默认断点续传功能关闭。当网络不稳定或者程序崩溃时,再次发起相同上传请求,可以继续未完成的上传任务,适用于超时3000秒仍不能上传完成的大文件。
    注意:断点续传开启后,会在上传过程中将上传位置写入本地磁盘文件,影响文件上传速度,请您根据实际情况选择是否开启*/
    //request.setEnableCheckpoint(false);
    /* OSS慢请求日志打印超时时间,是指每个分片上传时间超过该阈值时会打印debug日志,如果想屏蔽此日志,请调整该阈值。单位:毫秒,默认为300000毫秒*/
    //request.setSlowRequestsThreshold(300000L);
    /* 可指定每个分片慢请求时打印日志的时间阈值,默认为300s*/
    //request.setSlowRequestsThreshold(300000L);
    /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/
    //request.setIsShowWaterMark(true);
    /* 自定义消息回调设置(可选) */
    // request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://demo.example.com\"}}");
    /* 视频分类ID(可选) */
    //request.setCateId(0);
    /* 视频标签,多个用逗号分隔(可选) */
    //request.setTags("标签1,标签2");
    /* 视频描述(可选)*/
    //request.setDescription("视频描述");
    /* 封面图片(可选)*/
    //request.setCoverURL("http://cover.example.com/image_01.jpg");
    /* 模板组ID(可选)*/
    //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e5****");
    /* 工作流ID(可选)*/
    //request.setWorkflowId("d4430d07361f0*be1339577859b0****");
    /* 存储区域(可选)*/
    //request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
    /* 开启默认上传进度回调 */
    //request.setPrintProgress(false);
    /* 设置自定义上传进度回调(必须继承 VoDProgressListener)*/
    /*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
    //request.setProgressListener(new PutObjectProgressListener());
    /* 设置您实现的生成STS信息的接口实现类*/
    // request.setVoDRefreshSTSTokenListener(new RefreshSTSTokenImpl());
    /* 设置应用ID*/
    //request.setAppId("app-100****");
    /* 点播服务接入点 */
    //request.setApiRegionId("cn-shanghai");
    /* ECS部署区域*/
    // request.setEcsRegionId("cn-shanghai");
    UploadVideoImpl uploader = new UploadVideoImpl();
    UploadVideoResponse response = uploader.uploadVideo(request);
    System.out.print("RequestId=" + response.getRequestId() + "\n");  //请求视频点播服务的请求ID
    if (response.isSuccess()) {
        System.out.print("VideoId=" + response.getVideoId() + "\n");
    } else {
        /* 如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 */
        System.out.print("VideoId=" + response.getVideoId() + "\n");
        System.out.print("ErrorCode=" + response.getCode() + "\n");
        System.out.print("ErrorMessage=" + response.getMessage() + "\n");
    }
}

/**
 * URL网络流上传。支持断点续传,最大支持48.8TB的单个文件。
 * 该上传方式需要先将网络文件下载到本地磁盘,再进行上传,所以要保证本地磁盘有充足的空间。
 * 当您设置的URL中不包括文件扩展名时,需要单独设置fileExtension,表示文件扩展名。
 * @param accessKeyId
 * @param accessKeySecret
 * @param title
 * @param fileName
 * @param url
 */
private static void testUploadURLStream(String accessKeyId, String accessKeySecret, String title, String url, String fileExtension) {
    UploadURLStreamRequest request = new UploadURLStreamRequest(accessKeyId, accessKeySecret, title, url);

    /* 文件扩展名*/
    request.setFileExtension(fileExtension);
    /* 网络文件下载连接超时,单位毫秒,0-表示不限制*/
    request.setDownloadConnectTimeout(1000);
    /* 网络文件下载读取超时,单位毫秒,0-表示不限制*/
    request.setDownloadReadTimeout(0);
    /* 网络文件下载后保存的本地目录*/
    request.setLocalDownloadFilePath("/Users/download");
    /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/
    //request.setShowWaterMark(true);
    /* 自定义消息回调设置(可选) */
    // request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://demo.example.com\"}}");
    /* 视频分类ID(可选) */
    //request.setCateId(0);
    /* 视频标签,多个用逗号分隔(可选) */
    //request.setTags("标签1,标签2");
    /* 视频描述(可选) */
    //request.setDescription("视频描述");
    /* 封面图片(可选)*/
    //request.setCoverURL("http://cover.example.com/image_01.jpg");
    /* 模板组ID(可选)*/
    //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56****");
    /* 工作流ID(可选)*/
    //request.setWorkflowId("d4430d07361f0*be1339577859b0****");
    /* 存储区域(可选)*/
    //request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
    /* 开启默认上传进度回调 */
    //request.setPrintProgress(true);
    /* 设置自定义上传进度回调 (必须继承 VoDProgressListener)*/
    /*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
    //request.setProgressListener(new PutObjectProgressListener());
    /* 设置应用ID*/
    //request.setAppId("app-100****");
    /* 点播服务接入点 */
    //request.setApiRegionId("cn-shanghai");
    /* ECS部署区域*/
    // request.setEcsRegionId("cn-shanghai");
    UploadVideoImpl uploader = new UploadVideoImpl();
    UploadURLStreamResponse response = uploader.uploadURLStream(request);
    System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
    if (response.isSuccess()) {
        System.out.print("VideoId=" + response.getVideoId() + "\n");
    } else {
        /* 如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 */
        System.out.print("VideoId=" + response.getVideoId() + "\n");
        System.out.print("ErrorCode=" + response.getCode() + "\n");
        System.out.print("ErrorMessage=" + response.getMessage() + "\n");
    }
}

/**
 * 文件流上传接口
 *
 * @param accessKeyId
 * @param accessKeySecret
 * @param title
 * @param fileName
 */
private static void testUploadFileStream(String accessKeyId, String accessKeySecret, String title, String fileName) {
    UploadFileStreamRequest request = new UploadFileStreamRequest(accessKeyId, accessKeySecret, title, fileName);
    /* 是否使用默认水印(可选),指定模板组ID时,根据模板组配置确定是否使用默认水印*/
    //request.setShowWaterMark(true);
    /* 自定义消息回调设置 */
    //request.setUserData(""{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://demo.example.com\"}}"");
    /* 视频分类ID(可选)*/
    //request.setCateId(0);
    /* 视频标签,多个用逗号分隔(可选) */
    //request.setTags("标签1,标签2");
    /* 视频描述(可选)*/
    //request.setDescription("视频描述");
    /* 封面图片(可选)*/
    //request.setCoverURL("http://cover.example.com/image_01.jpg");
    /* 模板组ID(可选)*/
    //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56****");
    /* 工作流ID(可选)*/
    //request.setWorkflowId("d4430d07361f0*be1339577859b0****");
    /* 存储区域(可选)*/
    //request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
    /* 开启默认上传进度回调 */
    //request.setPrintProgress(true);
    /* 设置自定义上传进度回调(必须继承 VoDProgressListener)*/
    /*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
    //request.setProgressListener(new PutObjectProgressListener());
    /* 设置应用ID*/
    //request.setAppId("app-100****");
    /* 点播服务接入点 */
    //request.setApiRegionId("cn-shanghai");
    /* ECS部署区域*/
    // request.setEcsRegionId("cn-shanghai");
    UploadVideoImpl uploader = new UploadVideoImpl();
    UploadFileStreamResponse response = uploader.uploadFileStream(request);
    System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
    if (response.isSuccess()) {
        System.out.print("VideoId=" + response.getVideoId() + "\n");
    } else {
        /* 如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 */
        System.out.print("VideoId=" + response.getVideoId() + "\n");
        System.out.print("ErrorCode=" + response.getCode() + "\n");
        System.out.print("ErrorMessage=" + response.getMessage() + "\n");
    }
}

/**
 * 流式上传接口
 *
 * @param accessKeyId
 * @param accessKeySecret
 * @param title
 * @param fileName
 * @param inputStream
 */
private static void testUploadStream(String accessKeyId, String accessKeySecret, String title, String fileName, InputStream inputStream) {
    UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, inputStream);
     /* 是否使用默认水印(可选),指定模板组ID时,根据模板组配置确定是否使用默认水印*/
    //request.setShowWaterMark(true);
    /* 自定义消息回调设置 */
    //request.setUserData(""{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://demo.example.com\"}}"");
    /* 视频分类ID(可选) */
    //request.setCateId(0);
    /* 视频标签,多个用逗号分隔(可选) */
    //request.setTags("标签1,标签2");
    /* 视频描述(可选)*/
    //request.setDescription("视频描述");
    /* 封面图片(可选)*/
    //request.setCoverURL("http://cover.example.com/image_01.jpg");
    /* 模板组ID(可选)*/
    //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56****");
    /* 工作流ID(可选)*/
    //request.setWorkflowId("d4430d07361f0*be1339577859b0****");
    /* 存储区域(可选)*/
    //request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
    /* 开启默认上传进度回调 */
    // request.setPrintProgress(true);
    /* 设置自定义上传进度回调(必须继承 VoDProgressListener) */
    /*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
    // request.setProgressListener(new PutObjectProgressListener());
     /* 设置应用ID*/
    //request.setAppId("app-100****");
    /* 点播服务接入点 */
    //request.setApiRegionId("cn-shanghai");
    /* ECS部署区域*/
    // request.setEcsRegionId("cn-shanghai");
    UploadVideoImpl uploader = new UploadVideoImpl();
    UploadStreamResponse response = uploader.uploadStream(request);
    System.out.print("RequestId=" + response.getRequestId() + "\n");  //请求视频点播服务的请求ID
    if (response.isSuccess()) {
        System.out.print("VideoId=" + response.getVideoId() + "\n");
    } else { //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
        System.out.print("VideoId=" + response.getVideoId() + "\n");
        System.out.print("ErrorCode=" + response.getCode() + "\n");
        System.out.print("ErrorMessage=" + response.getMessage() + "\n");
    }
  }
}
M3U8文件
示例代码
public class UploadVideoDemo {
    //账号AK信息请填写(必选)
    private static final String accessKeyId = "<Your accessKeyId>";
    //账号AK信息请填写(必选)
    private static final String accessKeySecret = "<Your accessKeySecret>";

    public static void main(String[] args) {
    //m3u8文件上传
        // 1.上传本地m3u8音视频文件
        testUploadLocalM3u8(accessKeyId, accessKeySecret);
        // 2.上传网络m3u8音视频文件
        testUploadWebM3u8(accessKeyId, accessKeySecret);
    }
    /**
     * 上传本地m3u8视频或音频文件到点播,m3u8文件和分片文件默认在同一目录(sliceFilenames为空时,会按照同一目录去解析分片地址)
     *
     * @param request 本地m3u8上传请求类
     *                m3u8Filename: 本地m3u8索引文件的绝对路径,且m3u8文件的分片信息必须是相对路径,不能含有URL或本地绝对路径
     *                sliceFilenames: ts分片文件的绝对路径列表,如指定则以此为准,若不指定,则自动解析 m3u8Filename 里的m3u8文件
     */
    private static void testUploadLocalM3u8(String accessKeyId, String accessKeySecret) {
        String title = "test_upload_local_m3u8";
        String m3u8Filename = "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/cc38da35c7b24de0abe58619cdd7a8-6479a12446b994719838e0307f****-ld.m3u8";
        UploadLocalM3u8Request request = new UploadLocalM3u8Request(accessKeyId, accessKeySecret, title, m3u8Filename);
        String[] sliceFilenames = new String[]{
                "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a8493703****-ld-00001.ts",
                "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a8493703****-ld-00002.ts",
                "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a8493703****-ld-00003.ts",
                "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a8493703****-ld-00004.ts",
                "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a8493703****-ld-00005.ts"
        };
        // ts分片文件列表,可选,不指定时,直接解析m3u8FileURL获取分片地址
        request.setSliceFilenames(sliceFilenames);
        /* 可指定分片上传时每个分片的大小,默认为2M字节 */
        request.setPartSize(2 * 1024 * 1024L);
        /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
        request.setTaskNum(1);
        /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/
        //request.getShowWaterMark(true);
        /* 自定义消息回调设置(可选)*/
        // request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}");
        /* 视频分类ID(可选)*/
        //request.setCateId(-1L);
        /* 视频标签,多个用逗号分隔(可选)*/
        //request.setTags("标签1,标签2");
        /* 视频描述(可选)*/
        //request.setDescription("视频描述");
        /* 封面图片(可选)*/
        //request.setCoverURL("http://cover.sample.com/sample.jpg");
        /* 模板组ID(可选)*/
        //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56****");
        /* 工作流ID(可选)*/
        //request.setWorkflowId("d4430d07361f0*be1339577859b0****");
        /* 存储区域(可选)*/
        //request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
        /* 设置应用ID*/
        // request.setAppId("app-1000000");
        /* 点播服务接入点 */
        // request.setApiRegionId("cn-shanghai");
        /* ECS部署区域*/
        // request.setEcsRegionId("cn-shanghai");
        UploadM3u8FileImpl uploadM3u8File = new UploadM3u8FileImpl();
        UploadLocalM3u8Response uploadLocalM3u8Response = uploadM3u8File.uploadLocalM3u8(request);
        System.out.println("code = " + uploadLocalM3u8Response.getCode());
        System.out.println("message = " + uploadLocalM3u8Response.getMessage());
        System.out.println("videoId = " + uploadLocalM3u8Response.getVideoId());
        System.out.println("requestId = " + uploadLocalM3u8Response.getRequestId());
    }

    /**
     * 上传网络m3u8视频或音频文件到点播,需本地磁盘空间足够,会先下载到本地临时目录,再上传到点播存储
     *
     * @param request 网络m3u8上传请求类
     *                m3u8FileURL: 网络m3u8索引文件的URL地址,且m3u8文件的分片信息必须是相对地址,不能含有URL或本地绝对路径
     *                sliceFileURLs: ts分片文件的URL地址列表;需自行拼接ts分片的URL地址列表
     */
    private static void testUploadWebM3u8(String accessKeyId, String accessKeySecret) {
        String title = "test_upload_web_m3u8";
        String m3u8FileURL = "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-538087dcf2c201c31ce4324bf76af69****.m3u8";
        UploadWebM3u8Request request = new UploadWebM3u8Request(accessKeyId, accessKeySecret, title, m3u8FileURL);
        String[] sliceFileURLs = new String[]{
                "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-0****.ts",
                "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-0****.ts",
                "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-0****.ts",
                "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-0****.ts",
                "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-0****.ts"
        };
        // ts分片地址,可选,不指定时,直接解析m3u8FileURL获取分片地址
        request.setSliceFileURLs(sliceFileURLs);
        /* 下载文件的临时存储目录,可自定义,如不指定则保存到程序所运行的目录下*/
        // request.setGlobalLocalFilePath("/User/download/");
        /* 可指定分片上传时每个分片的大小,默认为2M字节 */
        request.setPartSize(2 * 1024 * 1024L);
        /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
        request.setTaskNum(1);
        /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/
        //request.setShowWaterMark(true);
        /* 自定义消息回调设置(可选)*/
        //request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.example.com\"}}");
        /* 视频分类ID(可选)*/
        //request.setCateId(-1L);
        /* 视频标签,多个用逗号分隔(可选)*/
        //request.setTags("标签1,标签2");
        /* 视频描述(可选)*/
        //request.setDescription("视频描述");
        /* 封面图片(可选)*/
        //request.setCoverURL("http://cover.example.com/sample.jpg");
        /* 模板组ID(可选)*/
        //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56****");
        /* 工作流ID(可选)*/
        //request.setWorkflowId("d4430d07361f0*be1339577859b0****");
        /* 存储区域(可选)*/
        //request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com");
        /* 设置应用ID*/
        //request.setAppId("app-100****");
        /* 点播服务接入点 */
        //request.setApiRegionId("cn-shanghai");
        /* ECS部署区域*/
        // request.setEcsRegionId("cn-shanghai");
        UploadM3u8FileImpl uploadM3u8File = new UploadM3u8FileImpl();
        UploadWebM3u8Response uploadWebM3u8Response = uploadM3u8File.uploadWebM3u8(request);
        System.out.println("code = " + uploadWebM3u8Response.getCode());
        System.out.println("message = " + uploadWebM3u8Response.getMessage());
        System.out.println("videoId = " + uploadWebM3u8Response.getVideoId());
        System.out.println("requestId = " + uploadWebM3u8Response.getRequestId());
    }
}
            

图片上传

示例代码
public class UploadImageDemo {
    //账号AK信息请填写(必选)
    private static final String accessKeyId = "<Your accessKeyId>";
    //账号AK信息请填写(必选)
    private static final String accessKeySecret = "<Your accessKeySecret>";
    public static void main(String[] args) {
        // 图片上传
        // 1.图片上传-本地文件上传
         testUploadImageLocalFile(accessKeyId, accessKeySecret);
        // 2.图片上传-流式上传(文件流和网络流)
         testUploadImageStream(accessKeyId, accessKeySecret);
    }
    /**
     * 图片上传接口,本地文件上传示例
     *
     * @param accessKeyId
     * @param accessKeySecret
     */
    private static void testUploadImageLocalFile(String accessKeyId, String accessKeySecret) {
        /* 图片类型(必选)取值范围:default(默认),cover(封面),watermark(水印)*/
        String imageType = "cover";
        UploadImageRequest request = new UploadImageRequest(accessKeyId, accessKeySecret, imageType);
        request.setImageType("cover");
        /* 图片文件扩展名(可选)取值范围:png,jpg,jpeg */
        //request.setImageExt("png");
        /* 图片标题(可选)长度不超过128个字节,UTF8编码 */
        //request.setTitle("图片标题");
        /* 图片标签(可选)单个标签不超过32字节,最多不超过16个标签,多个用逗号分隔,UTF8编码 */
        //request.setTags("标签1,标签2");
        /* 存储区域(可选)*/
        //request.setStorageLocation("out-4f3952f78c0211e8b30200****.oss-cn-shanghai.aliyuncs.com");
        /* 流式上传时,InputStream为必选,fileName为源文件名称,如:文件名称.png(可选)*/
        String fileName = "/Users/demo/png/test.png";
        request.setFileName(fileName);
        /* 开启默认上传进度回调 */
        //request.setPrintProgress(false);
        /* 设置自定义上传进度回调 (必须继承 VoDProgressListener)*/
        /*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
        // request.setProgressListener(new PutObjectProgressListener());
        /* 设置应用ID*/
        //request.setAppId("app-100****");
        /* 点播服务接入点 */
        //request.setApiRegionId("cn-shanghai");
        UploadImageImpl uploadImage = new UploadImageImpl();
        UploadImageResponse response = uploadImage.upload(request);
        System.out.print("RequestId=" + response.getRequestId() + "\n");
        if (response.isSuccess()) {
            System.out.print("ImageId=" + response.getImageId() + "\n");
            System.out.print("ImageURL=" + response.getImageURL() + "\n");
        } else {
            System.out.print("ErrorCode=" + response.getCode() + "\n");
            System.out.print("ErrorMessage=" + response.getMessage() + "\n");
        }
    }
    /**
     * 图片上传接口,流式上传示例(支持文件流和网络流)
     *
     * @param accessKeyId
     * @param accessKeySecret
     */
    private static void testUploadImageStream(String accessKeyId, String accessKeySecret) {
        /* 图片类型(必选)取值范围:default(默认),cover(封面),watermark(水印)*/
        String imageType = "cover";
        UploadImageRequest request = new UploadImageRequest(accessKeyId, accessKeySecret, imageType);
        /* 图片文件扩展名(可选)取值范围:png,jpg,jpeg */
        //request.setImageExt("png");
        /* 图片标题(可选)长度不超过128个字节,UTF8编码 */
        //request.setTitle("图片标题");
        /* 图片标签(可选)单个标签不超过32字节,最多不超过16个标签,多个用逗号分隔,UTF8编码 */
        //request.setTags("标签1,标签2");
        /* 存储区域(可选)*/
        //request.setStorageLocation("out-4f3952f78c0211e8b30200****.oss-cn-shanghai.aliyuncs.com");
        /* 流式上传时,InputStream为必选,fileName为源文件名称,如:文件名称.png(可选)*/
        //request.setFileName("测试文件名称.png");
        /* 开启默认上传进度回调 */
        // request.setPrintProgress(true);
        /* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */
        /*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
        // request.setProgressListener(new PutObjectProgressListener());
        /* 设置应用ID*/
        //request.setAppId("app-1000000");
        // 1.文件流上传
        // InputStream fileStream = getFileStream(request.getFileName());
        // if (fileStream != null) { 
        //     request.setInputStream(fileStream);
        // }
        // 2.网络流上传
        String url = "http://test.aliyun.com/image/default/test.png";
        InputStream urlStream = getUrlStream(url);
        if (urlStream != null) {
            request.setInputStream(urlStream); 
       }
        // 开始上传图片
        UploadImageImpl uploadImage = new UploadImageImpl();
        UploadImageResponse response = uploadImage.upload(request);
        System.out.print("RequestId=" + response.getRequestId() + "\n");
        if (response.isSuccess()) {
            System.out.print("ImageId=" + response.getImageId() + "\n");
            System.out.print("ImageURL=" + response.getImageURL() + "\n");
        } else {
            System.out.print("ErrorCode=" + response.getCode() + "\n");
            System.out.print("ErrorMessage=" + response.getMessage() + "\n");
        }
    }
    private static InputStream getFileStream(String fileName) {
        try {
            return new FileInputStream(fileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
    private static InputStream getUrlStream(String url) {
        try {
            return new URL(url).openStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}          

辅助媒资上传

示例代码
public class UploadAttachedMediaDemo {
  //账号AK信息请填写(必选)
    private static final String accessKeyId = "<Your accessKeyId>";
    //账号AK信息请填写(必选)
    private static final String accessKeySecret = "<Your accessKeySecret>";
    public static void main(String[] args) {
        // 辅助媒资上传
        // 辅助媒资-本地文件上传
        testUploadAttachedMediaLocalFile(accessKeyId, accessKeySecret);
        // 辅助媒资-流式上传(文件流和网络流)
        testUploadAttachedMediaStream(accessKeyId, accessKeySecret);
    }
 /**
     * 辅助媒资上传接口,本地文件上传示例
     *
     * @param accessKeyId
     * @param accessKeySecret
     */
    private static void testUploadAttachedMediaLocalFile(String accessKeyId, String accessKeySecret) {
        /* 业务类型 */
        String businessType = "watermark";
        /* 文件扩展名 */
        String mediaExt = "png";
        String filename = "/Users/demo/png/test.png";
        UploadAttachedMediaRequest request = new UploadAttachedMediaRequest(accessKeyId, accessKeySecret, businessType, mediaExt);
        request.setFileName(filename);
        /* 标题*/
        request.setTitle("test_attached_media");
        /* 分类ID */
        request.setCateId(-1L);
        /* 标签,多个用逗号分隔(可选) */
        request.setTags("tag1,tag2");
        /* 描述(可选) */
        request.setDescription("test_desc");
        /* 存储区域(可选) */
        request.setStorageLocation("out-20170323225118266-5l3hs5****.oss-cn-shanghai.aliyuncs.com");
        /* 点播服务接入点 */
        request.setApiRegionId("cn-shanghai");
        /* 设置应用ID*/
        //request.setAppId("app-1000000");
        UploadAttachedMediaImpl uploader = new UploadAttachedMediaImpl();
        UploadAttachedMediaResponse response = uploader.upload(request);
        System.out.print("RequestId=" + response.getRequestId() + "\n");
        if (response.isSuccess()) {
            System.out.print("MediaId=" + response.getMediaId() + "\n");
            System.out.print("MediaURL=" + response.getMediaURL() + "\n");
            System.out.print("FileURL=" + response.getFileURL() + "\n");
        } else {
            System.out.print("ErrorCode=" + response.getCode() + "\n");
            System.out.print("ErrorMessage=" + response.getMessage() + "\n");
        }
    }
     /**
     * 辅助媒资上传接口,流式上传示例(支持文件流和网络流)
     *
     * @param accessKeyId
     * @param accessKeySecret
     */
    private static void testUploadAttachedMediaStream(String accessKeyId, String accessKeySecret) {
        /* 业务类型 */

        String businessType = "watermark";

        /* 文件扩展名 */
        String mediaExt = "png";

        String filename = "http://test.aliyun.com/test.png";

        UploadAttachedMediaRequest request;
        // 1.文件流上传

        InputStream fileStream = getFileStream(filename);

        request = new UploadAttachedMediaRequest(accessKeyId, accessKeySecret, businessType, mediaExt);
        request.setInputStream(fileStream);


        // 2.网络流上传

//        String url = "http://test.aliyun.com/image//test.png";

//        InputStream urlStream = getUrlStream(url);

//        request = new UploadAttachedMediaRequest(accessKeyId, accessKeySecret, businessType, mediaExt);
//        request.setInputStream(urlStream);

        /* 标题*/

        request.setTitle("test_attached_media");
        /* 分类ID */
        request.setCateId(-1L);
        /* 标签,多个用逗号分隔(可选)*/
        request.setTags("tag1,tag2");

        /* 描述(可选)*/
        request.setDescription("test_desc");

        /* 存储区域(可选)*/

        request.setStorageLocation("out-20170323225118266-5l3****wa.oss-cn-shanghai.aliyuncs.com");

        /* 点播服务接入点 */
        request.setApiRegionId("cn-shanghai");

        /* 设置应用ID*/

        // request.setAppId("app-1000000");

        // 开始上传

        UploadAttachedMediaImpl uploader = new UploadAttachedMediaImpl();

        UploadAttachedMediaResponse response = uploader.upload(request);
        System.out.print("RequestId=" + response.getRequestId() + "\n");
        if (response.isSuccess()) {

            System.out.print("MediaId=" + response.getMediaId() + "\n");

            System.out.print("MediaURL=" + response.getMediaURL() + "\n");

            System.out.print("FileURL=" + response.getFileURL() + "\n");
        } else {

            System.out.print("ErrorCode=" + response.getCode() + "\n");

            System.out.print("ErrorMessage=" + response.getMessage() + "\n");

        }

    }
    private static InputStream getFileStream(String fileName) {
        try {
            return new FileInputStream(fileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
    private static InputStream getUrlStream(String url) {
        try {
            return new URL(url).openStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

高级功能

  • 上传进度条

    sample目录下的PutObjectProgressListener.java文件,为上传进度回调函数示例代码。

    该类必须继承VoDProgressListener类,ProgressEvent是通过OSS上传文件时产生的进度回调通知,您可以自定义各个事件通知的业务处理逻辑

    示例代码如下所示。

    /**
     * 上传进度回调方法类
     * 当您开启上传进度回调时该事件回调才会生效。
     * OSS分片上传成功或失败均触发相应的回调事件,您可根据业务逻辑处理相应的事件回调。
     * 当创建音视频信息成功后,此上传进度回调中的videoId为本次上传生成的视频ID,您可以根据视频ID进行音视频管理。
     * 当创建图片信息成功后,此上传进度回调中的ImageId为本次上传生成的图片ID,您可以根据视频ID进行图片管理。
     */
    
    public class PutObjectProgressListener implements VoDProgressListener {
        /**
         * 已成功上传至OSS的字节数
         */
        private long bytesWritten = 0;
        /**
         * 原始文件的总字节数
         */
        private long totalBytes = -1;
        /**
         * 本次上传成功标记
         */
        private boolean succeed = false;
        /**
         * 视频ID
         */
        private String videoId;
        /**
         * 图片ID
         */
        private String imageId;
    
        public void progressChanged(ProgressEvent progressEvent) {
            long bytes = progressEvent.getBytes();
            ProgressEventType eventType = progressEvent.getEventType();
            switch (eventType) {
                //开始上传事件
                case TRANSFER_STARTED_EVENT:
                    if (videoId != null) {
                        System.out.println("Start to upload videoId "+videoId+"......");
                    }
                    if (imageId != null) {
                        System.out.println("Start to upload imageId "+imageId+"......");
                    }
                    break;
                //计算待上传文件总大小事件通知,只有调用本地文件方式上传时支持该事件
                case REQUEST_CONTENT_LENGTH_EVENT:
                    this.totalBytes = bytes;
                    System.out.println(this.totalBytes + "bytes in total will be uploaded to OSS.");
                    break;
                //已经上传成功文件大小事件通知
                case REQUEST_BYTE_TRANSFER_EVENT:
                    this.bytesWritten += bytes;
                    if (this.totalBytes != -1) {
                        int percent = (int) (this.bytesWritten * 100.0 / this.totalBytes);
                        System.out.println(bytes+" bytes have been written at this time, upload progress: "+
                                percent +"%(" +  this.bytesWritten +  "/"  + this.totalBytes  + ")");
                    } else {
                        System.out.println(bytes + " bytes have been written at this time, upload sub total : " +
                                "(" + this.bytesWritten + ")");
                    }
                    break;
                //文件全部上传成功事件通知
                case TRANSFER_COMPLETED_EVENT:
                    this.succeed = true;
                    if (videoId != null) {
                        System.out.println("Succeed to upload videoId "  + videoId  + " , " + this.bytesWritten + " bytes have been transferred in total.");
                    }
                    if (imageId != null) {
                        System.out.println("Succeed to upload imageId " + imageId + " , " + this.bytesWritten + " bytes have been transferred in total.");
                    }
                    break;
                //文件上传失败事件通知
                case TRANSFER_FAILED_EVENT:
                    if (videoId != null) {
                        System.out.println("Failed to upload videoId " + videoId + " , " + this.bytesWritten + " bytes have been transferred.");
                    }
                    if (imageId != null) {
                        System.out.println("Failed to upload imageId " + imageId + " , " + this.bytesWritten + " bytes have been transferred.");
                    }
                    break;
    
                default:
                    break;
            }
        }
    
        public boolean isSucceed() {
            return succeed;
        }
    
        public void onVidReady(String videoId) {
            setVideoId(videoId);
        }
    
        public void onImageIdReady(String imageId) {
            setImageId(imageId);
        }
    
        public String getVideoId() {
            return videoId;
        }
    
        public void setVideoId(String videoId) {
            this.videoId = videoId;
        }
    
        public String getImageId() {
            return imageId;
        }
    
        public void setImageId(String imageId) {
            this.imageId = imageId;
        }
    }
                        
  • 刷新临时Token

    sample目录下的RefreshSTSTokenImpl.java文件,为刷新临时Token的示例代码。

    示例如下所示。

    /**
     * @author vod
     * 生成STS信息实现类
     * @date 2019/6/5
     */
    public class RefreshSTSTokenImpl implements VoDRefreshSTSTokenListener {
    
        public STSTokenDTO onRefreshSTSToken() {
            STSTokenDTO stsTokenDTO = new STSTokenDTO();
            stsTokenDTO.setAccessKeyId("<your sts AccessKeyId>");
            stsTokenDTO.setAccessKeySecret("<your sts AccessKeySecret>");
            stsTokenDTO.setSecurityToken("<your sts SecurityToken>");
            return stsTokenDTO;
        }
    
    }

常见问题

由于开发环境的不同,您可能会遇到找不到相关依赖等问题。此类问题通常是IDEA环境编译问题导致,如果确定已经导入所需的资源包,您可以尝试以下解决办法:
  • 在Maven项目中,单击右侧Maven,单击m图标,输入mvn idea:module重新加载资源。module
  • 在上方菜单栏,选择Build > Rebuild Project重新编辑您的工程。Rebuild
  • aliyun-java-vod-upload-1.4.14.jar包拷贝到工程的resource目录下,Maven依赖中增加本地依赖,依赖项内容如下:问题
    <dependency>
            <groupId>com.aliyun.vod</groupId>
            <artifactId>upload</artifactId>
            <version>1.4.14</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/aliyun-java-vod-upload-1.4.14.jar</systemPath>
    </dependency>
    添加完成后Maven依赖示例:
       <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>
         <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-vod</artifactId>
            <version>2.15.11</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20170516</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.vod</groupId>
            <artifactId>upload</artifactId>
            <version>1.4.14</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/aliyun-java-vod-upload-1.4.14.jar</systemPath>
        </dependency>

参考信息:完整Demo

详细的上传示例代码,请参见Java上传SDK解压目录中的sample/UploadVideoDemo.java文件。