All Products
Search
Document Center

ApsaraVideo VOD:Upload media files by calling the ApsaraVideo VOD API

Last Updated:Dec 20, 2023

To use AparaVideo VOD to process media files such as audio and video files, you must upload the files to ApsaraVideo VOD. You can perform operations such as transcoding, review, and add watermarks on the media files. This topic describes how to call API operations to upload media files and provides a complete demo.

Background information

If you upload media files by calling the ApsaraVideo VOD API, Object Storage Service (OSS) SDKs are used for the upload. You must specify all upload logic including the logic for obtaining upload URLs and credentials, decoding Base64-encoded upload URLs and credentials, and using OSS capabilities to upload media files. In this case, the operations are complex and prone to errors. This topic provides the upload demo to help you resolve the issue that a media file remains in the Uploading state after you call an API operation to upload the media file.

Note
  • Uploading media files by using the ApsaraVideo VOD API is an OSS-based upload method. For more information, see Overview.

  • This topic provides sample code in Java. For more information about the sample code in other languages, see Upload media files by using OSS SDKs.

  • If you have more questions or suggestions, join the DingTalk group 11370001915 for technical support.

Before you begin

Step 1: Install the ApsaraVideo VOD SDK

For more information, see Installation.

Step 2: Install the OSS SDK

For more information, see Install OSS SDK for Java.

Step 3: Start upload

The following section provides sample code for the following operations: upload local media files, upload network streams based on URLs, upload local M3U8 files, perform multipart upload, and perform resumable upload. For more information about the sample code that can be used to obtain upload URLs and credentials and decode Base64-encoded upload URLs and credentials, see the Sample code section of this topic.

Upload files from your local PC

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

        try {
            File file = new File(localFile);
            PutObjectResult result = ossClient.putObject(bucketName, objectName, file);
            // If the upload is successful, HTTP status code 200 is returned. 
            // Configure the parameters of the progress bar during the upload. UploadOss specifies the name of the class that is called to upload local files. Replace UploadOss with the class name that you want to call in actual use. 
//            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName,objectName, file).
//                    <PutObjectRequest>withProgressListener(new UploadOss()));
//            System.out.println(result.getResponse().getStatusCode());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

Upload network streams based on URLs

public static void uploadURLFile(OSSClient ossClient, JSONObject uploadAddress, String url) {
    String bucketName = uploadAddress.getString("Bucket");
    String objectName = uploadAddress.getString("FileName");

    try {
        InputStream inputStream = new URL(url).openStream();
        PutObjectResult result = ossClient.putObject(bucketName, objectName, inputStream);
        // If the upload is successful, HTTP status code 200 is returned. 
        System.out.println(result.getResponse().getStatusCode());
    } catch (OSSException oe) {
        System.out.println("Caught an OSSException, which means your request made it to OSS, "
                + "but was rejected with an error response for some reason.");
        System.out.println("Error Message:" + oe.getErrorMessage());
        System.out.println("Error Code:" + oe.getErrorCode());
        System.out.println("Request ID:" + oe.getRequestId());
        System.out.println("Host ID:" + oe.getHostId());
    } catch (Throwable ce) {
        System.out.println("Caught an ClientException, which means the client encountered "
                + "a serious internal problem while trying to communicate with OSS, "
                + "such as not being able to access the network.");
        System.out.println("Error Message:" + ce.getMessage());
    } finally {
        // Shut down the OSSClient instance. 
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }
}

Upload local M3U8 files

Note

To upload local M3U8 files including the part files, you must specify the URLs of the M3U8 index files and part URLs.

public static void uploadLocalM3U8(OSSClient ossClient, JSONObject uploadAddress, String indexFile, String[] tsFiles ) {

        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");
        String objectPrefix = uploadAddress.getString("ObjectPrefix");
        System.out.println(uploadAddress.toJSONString());

        try {
            // Upload the index files.
            File index = new File(indexFile);
            ossClient.putObject(bucketName, objectName, index);
            Thread.sleep(200);
            // Upload the TS files.
            for(String filePath : tsFiles){
                File ts = new File(filePath);
                ossClient.putObject(bucketName, objectPrefix + ts.getName(), ts);
                Thread.sleep(200);
            }
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

Perform multipart upload and resumable upload

public static void uploadEnableCheckPointFile(OSSClient ossClient, JSONObject uploadAddress, String localFile) {
    String bucketName = uploadAddress.getString("Bucket");
    String objectName = uploadAddress.getString("FileName");

    try {
        UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName,objectName);
        // Configure a single parameter by using UploadFileRequest. 
        // Specify the full path of the local file that you want to upload. Example: D:\\localpath\\examplefile.mp4. By default, if you do not specify the full path, the local file is uploaded from the path of the project to which the sample program belongs. 
        uploadFileRequest.setUploadFile(localFile);
        // Specify the number of concurrent threads for the upload task. Default value: 1. 
        uploadFileRequest.setTaskNum(5);
        // Specify the size of each part. Unit: bytes. Valid values: 100 KB to 5 GB. Default value: 100 KB. 
        uploadFileRequest.setPartSize(1 * 1024 * 1024);
        // Specify whether to enable resumable upload. By default, resumable upload is disabled. 
        uploadFileRequest.setEnableCheckpoint(true);
        // Specify the checkpoint file that records the upload result of each part. This checkpoint file stores information about the upload progress. If a part fails to be uploaded, the task can be continued based on the progress recorded in the checkpoint file. After the local file is uploaded, the checkpoint file is deleted. 
        // By default, if you do not specify this parameter, the checkpoint file is stored in the same directory as the file that you want to upload. The directory is named ${uploadFile}.ucp. 
        //uploadFileRequest.setCheckpointFile("yourCheckpointFile");
        // Start resumable upload. 
        ossClient.uploadFile(uploadFileRequest);

    } catch (OSSException oe) {
        System.out.println("Caught an OSSException, which means your request made it to OSS, "
                + "but was rejected with an error response for some reason.");
        System.out.println("Error Message:" + oe.getErrorMessage());
        System.out.println("Error Code:" + oe.getErrorCode());
        System.out.println("Request ID:" + oe.getRequestId());
        System.out.println("Host ID:" + oe.getHostId());
    } catch (Throwable ce) {
        System.out.println("Caught an ClientException, which means the client encountered "
                + "a serious internal problem while trying to communicate with OSS, "
                + "such as not being able to access the network.");
        System.out.println("Error Message:" + ce.getMessage());
    } finally {
        // Shut down the OSSClient instance. 
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }
}

Sample code

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.event.ProgressEvent;
import com.aliyun.oss.event.ProgressEventType;
import com.aliyun.oss.event.ProgressListener;
import com.aliyun.oss.model.*;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.*;
import org.apache.commons.codec.binary.Base64;

import java.io.File;
import java.io.InputStream;
import java.net.URL;

/**
 * *****   Usage notes     ******! ! 
 * The following sample code provides an example on how to upload media files to ApsaraVideo VOD by calling API operations in Java. For more information about how to use OSS SDK for Java to upload media files, visit https://www.alibabacloud.com/help/object-storage-service/latest/overview-3.
 * This demo cannot be used as an upload SDK. For more information about how to use upload SDKs, visit https://www.alibabacloud.com/help/apsaravideo-for-vod/latest/upload-sdk-overview.
 * <p>
 * 1. Upload regular audio and video files
 *
 * 1.1 Upload local files. You can use multipart upload to upload local files. Resumable upload is also supported. 
 * 1.1.1 The maximum period of time for which an upload task can run is 3,000 seconds if resumable upload is disabled. The maximum size of a file that can be uploaded varies based on the network bandwidth and the read and write capacities of disks.  For more information, see the description of the uploadEnableCheckPointFile function. 
 * 1.1.2 If you enable resumable upload, you can upload a file of up to 48.8 TB in size. During the resumable upload, ApsaraVideo VOD writes the upload progress to a local disk file. This affects the upload speed. You can choose to enable the resumable upload feature based on your file size.
 *
 * 1.2 Upload network streams. You can specify upload URLs to upload network streams. You can upload a file of up to 48.8 TB in size. For more information, see the description of the uploadURLFile function. 
 *
 * 1.3 Upload file streams. You can upload specific local files. The resumable upload feature is not supported when you upload file streams. You can upload a file of up to 5 GB in size. For more information, see the description of the uploadLocalFile function. 
 *
 * <p>
 * 2. Upload M3U8 files
 * 2.1. Upload local audio and video files in the M3U8 format to ApsaraVideo VOD. You must upload the URLs of the M3U8 index files and part URLs. For more information, see the description of the uploadLocalM3U8 function.
 * 2.2. Upload online M3U8 audio and video files. We recommend that you use URLs to upload online M3U8 audio and video files. 
 *
 * Note:
 * If you want to use URLs to upload online M3U8 audio and video files, the URLs must be accessible. If you want to limit access to the media files, specify URLs that include the signature information and make sure that the URLs remain valid to prevent upload failures due to inaccessible URLs.
 * <p>
 *
 * 3. Listen for the upload progress
 * 3.1 Use the default callback function to listen for the upload progress. You must call the ProgressListener class to use the default callback function. For more information, visit https://www.alibabacloud.com/help/object-storage-service/latest/upload-progress-bars-4.
 * 3.2 Use a custom callback function to listen for the upload progress. You can specify the methods that you want to use to handle different events based on your business requirements by using custom callback functions. 
 * 3.3 For more information about how to use a custom callback function, see line 225 in the sample code.
 *
 * <p>
 *
 * 4. Call API operations
 * 4.1 You can call the CreateUploadVideo or RefreshUploadVideo operation to obtain the upload credential based on your business requirements.
 * 4.2 You can call the RefreshUploadVideo to update the upload credential after it expires. You can also call this operation to overwrite an uploaded media file by using the videoId.
 * 4.3 You can call the CreateUploadImage operation to obtain the upload credential for an image.
 * 4.4 You can call the CreateUploadAttachedMedia operation to obtain the upload credential for an auxiliary media asset.
 * 4.5 For more information about API operations, visit https://www.alibabacloud.com/help/apsaravideo-for-vod/latest/api-doc-vod-2017-03-21-api-overview.
 *
 * <p>
 *
 * Note:
 * Specify the required parameters and delete the optional parameters that you do not need to specify in the sample code based on your business requirements. This prevent errors caused by invalid parameter values. 
 */
public class UploadVodByApiDemo implements ProgressListener {

    // Optional. Specify the parameters related to the upload progress bar.
    private long bytesWritten = 0;
    private long totalBytes = -1;
    private boolean succeed = false;

    public static void main(String[] argv) {
        // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
        // We recommend that you do not include your AccessKey pair (AccessKey ID and AccessKey secret) in your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources within your account may be compromised. 
        // In this example, ApsaraVideo VOD reads the AccessKey pair from the environment variables to implement identity verification for API access. Before you run the sample code, configure the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET. 
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        // Specify the full path of the local video file that you want to upload to ApsaraVideo VOD. The path must contain a file name extension.
        String localFile = "E:/demo/demo.mp4";
        // Specify the address of the network stream. The URL must be accessible.
        String url = "https://bucket-name*****.oss-cn-shanghai.aliyuncs.com/demo/demo.mp4";

        try {
            // Initialize an ApsaraVideo VOD client and obtain an upload URL and an upload credential.
            DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);

            // Obtain the upload credential for a video.
            CreateUploadVideoResponse createUploadVideoResponse = createUploadVideo(vodClient);
            // Update the upload credential.
            //RefreshUploadVideoResponse refreshUploadVideoResponse = refreshUploadVideo(vodClient);
            // Obtain the upload credential for an image.
            //CreateUploadImageResponse createUploadImageResponse = createUploadImage(vodClient);
            // Obtain the upload credential for an auxiliary media asset.
            //CreateUploadAttachedMediaResponse createUploadAttachedMediaResponse = createUploadAttachedMedia(vodClient);

            // If the preceding code is successfully executed, the videoId, uploadAddress, and uploadAuth parameters are returned.
            String videoId = createUploadVideoResponse.getVideoId();
            JSONObject uploadAuth = JSONObject.parseObject(decodeBase64(createUploadVideoResponse.getUploadAuth()));
            JSONObject uploadAddress = JSONObject.parseObject(decodeBase64(createUploadVideoResponse.getUploadAddress()));

            // Use the decoded upload URL and upload credential to initialize an OSS client.
            OSSClient ossClient = initOssClient(uploadAuth, uploadAddress);

            // Specify an upload method based on your business requirements.
            // 1. Upload a local file. Take note that multiple parts are uploaded in a synchronous manner. This may prolong the waiting time. The consumed time depends on the file size and upstream bandwidth.
            uploadLocalFile(ossClient, uploadAddress, localFile);
            // 2. Upload an online file.
            //uploadURLFile(ossClient, uploadAddress, url);
            // 3. Perform multipart upload and resumable upload.
            //uploadEnableCheckPointFile(ossClient, uploadAddress, localFile);
            // 4. Upload an M3U8 file.
            //String indexFile = "E:/demo/demo.m3u8";
            //String[] tsFiles = {"E:/demo/demo_01.ts"};
            //uploadLocalM3U8(ossClient, uploadAddress, indexFile, tsFiles);

            System.out.println("Put local file succeed, VideoId : " + videoId);
        } catch (Exception e) {
            System.out.println("Put local file fail, ErrorMessage : " + e.getLocalizedMessage());
        }
    }

    /**
     * Initialize the ApsaraVideo VOD client.
     * @throws ClientException
     */
    public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
        // Specify the region in which ApsaraVideo VOD is activated. Specify cn-shanghai if ApsaraVideo VOD is activated in the Chinese mainland. For more information about other supported regions, visit https://www.alibabacloud.com/help/apsaravideo-for-vod/latest/vod-centers-and-endpoints.
        String regionId = "cn-shanghai";
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }

    /**
     * Initialize the OSS client.
     * @throws ClientException
     */
    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);
    }

    /**
     * Obtain the upload credential.
     * @throws ClientException
     */
    public static CreateUploadVideoResponse createUploadVideo(DefaultAcsClient vodClient) throws ClientException {
        CreateUploadVideoRequest request = new CreateUploadVideoRequest();
        request.setFileName("vod_test.m3u8");
        request.setTitle("this is title");
        //request.setDescription("this is desc");
        //request.setTags("tag1,tag2");
        //request.setCoverURL("http://vod.****.com/test_cover_url.jpg");
        //request.setCateId(-1L);
        //request.setTemplateGroupId("34f055******c7af499c73");
        //request.setWorkflowId("");
        //request.setStorageLocation("");
        //request.setAppId("app-1000000");

        return vodClient.getAcsResponse(request);
    }

    /**
     * Update the upload credential.
     * @throws ClientException
     */
    public static RefreshUploadVideoResponse refreshUploadVideo(DefaultAcsClient vodClient) throws ClientException {
        RefreshUploadVideoRequest request = new RefreshUploadVideoRequest();
        request.setAcceptFormat(FormatType.JSON);
        request.setVideoId("VideoId");

        // Set the request timeout period.
        request.setSysReadTimeout(1000);
        request.setSysConnectTimeout(1000);

        return vodClient.getAcsResponse(request);
    }

    /**
     * Obtain an upload credential for an image.
     * @throws ClientException
     */
    public static CreateUploadImageResponse createUploadImage(DefaultAcsClient vodClient) throws ClientException {
        CreateUploadImageRequest request = new CreateUploadImageRequest();
        request.setImageType("default");
        request.setAcceptFormat(FormatType.JSON);

        // Set the request timeout period.
        request.setSysReadTimeout(1000);
        request.setSysConnectTimeout(1000);

        return vodClient.getAcsResponse(request);
    }

    /**
     * Obtain an upload credential for an auxiliary media asset.
     * @throws ClientException
     */
    public static CreateUploadAttachedMediaResponse createUploadAttachedMedia(DefaultAcsClient vodClient) throws ClientException {
        CreateUploadAttachedMediaRequest request = new CreateUploadAttachedMediaRequest();
        request.setBusinessType("watermark");
        request.setMediaExt("png");
        request.setAcceptFormat(FormatType.JSON);

        // Set the request timeout period.
        request.setSysReadTimeout(1000);
        request.setSysConnectTimeout(1000);

        return vodClient.getAcsResponse(request);
    }

    /**
     *  Upload local files.
     * @throws Exception
     */
    public static void uploadLocalFile(OSSClient ossClient, JSONObject uploadAddress, String localFile) {
        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");

        try {
            File file = new File(localFile);
            PutObjectResult result = ossClient.putObject(bucketName, objectName, file);
            // If the upload is successful, HTTP status code 200 is returned. 
            // Configure the parameters of the progress bar during the upload. UploadOss specifies the name of the class that is called to upload local files. Replace UploadOss with the class name that you want to call in actual use. 
//            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName,objectName, file).
//                    <PutObjectRequest>withProgressListener(new UploadOss()));
//            System.out.println(result.getResponse().getStatusCode());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *  Upload network streams.
     * @throws Exception
     */
    public static void uploadURLFile(OSSClient ossClient, JSONObject uploadAddress, String url) {
        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");

        try {
            InputStream inputStream = new URL(url).openStream();
            PutObjectResult result = ossClient.putObject(bucketName, objectName, inputStream);
            // If the upload is successful, HTTP status code 200 is returned. 
            System.out.println(result.getResponse().getStatusCode());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *  Start resumable upload.
     * @throws Exception
     */
    public static void uploadEnableCheckPointFile(OSSClient ossClient, JSONObject uploadAddress, String localFile) {
        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");

        try {
            UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName,objectName);
            // Configure a single parameter by using UploadFileRequest. 
            // Specify the full path of the local file that you want to upload. Example: D:\\localpath\\examplefile.mp4. By default, if you do not specify the full path, the local file is uploaded from the path of the project to which the sample program belongs. 
            uploadFileRequest.setUploadFile(localFile);
            // Specify the number of concurrent threads for the upload task. Default value: 1. 
            uploadFileRequest.setTaskNum(5);
            // Specify the size of each part. Unit: bytes. Valid values: 100 KB to 5 GB. Default value: 100 KB. 
            uploadFileRequest.setPartSize(1 * 1024 * 1024);
            // Specify whether to enable resumable upload. By default, resumable upload is disabled. 
            uploadFileRequest.setEnableCheckpoint(true);
            // Specify the checkpoint file that records the upload result of each part. This checkpoint file stores information about the upload progress. If a part fails to be uploaded, the task can be continued based on the progress recorded in the checkpoint file. After the local file is uploaded, the checkpoint file is deleted. 
            // By default, if you do not specify this parameter, the checkpoint file is stored in the same directory as the file that you want to upload. The directory is named ${uploadFile}.ucp. 
            //uploadFileRequest.setCheckpointFile("yourCheckpointFile");
            // Start resumable upload. 
            ossClient.uploadFile(uploadFileRequest);

        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *  Upload local M3U8 media files.
     * @throws Exception
     */
    public static void uploadLocalM3U8(OSSClient ossClient, JSONObject uploadAddress, String indexFile, String[] tsFiles ) {

        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");
        String objectPrefix = uploadAddress.getString("ObjectPrefix");
        System.out.println(uploadAddress.toJSONString());

        try {
            // Upload the index files.
            File index = new File(indexFile);
            ossClient.putObject(bucketName, objectName, index);
            Thread.sleep(200);
            // Upload the TS files.
            for(String filePath : tsFiles){
                File ts = new File(filePath);
                ossClient.putObject(bucketName, objectPrefix + ts.getName(), ts);
                Thread.sleep(200);
            }
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    // Rewrite the callback method to use the progress bar. The following sample code provides an example: 
    @Override
    public void progressChanged(ProgressEvent progressEvent) {
        long bytes = progressEvent.getBytes();
        ProgressEventType eventType = progressEvent.getEventType();
        switch (eventType) {
            case TRANSFER_STARTED_EVENT:
                System.out.println("Start to upload......");
                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 ratio: unknown" + "(" + this.bytesWritten + "/...)");
                }
                break;
            case TRANSFER_COMPLETED_EVENT:
                this.succeed = true;
                System.out.println("Succeed to upload, " + this.bytesWritten + " bytes have been transferred in total");
                break;
            case TRANSFER_FAILED_EVENT:
                System.out.println("Failed to upload, " + this.bytesWritten + " bytes have been transferred");
                break;
            default:
                break;
        }
    }

    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;
    }
}