全部产品
Search
文档中心

ApsaraVideo VOD:Unggah file media dengan memanggil API ApsaraVideo VOD

更新时间:Jul 06, 2025

Untuk memproses file media seperti audio dan video menggunakan ApsaraVideo VOD, Anda harus mengunggah file tersebut ke ApsaraVideo VOD. Setelah diunggah, Anda dapat melakukan operasi seperti transkoding, review, dan menambahkan watermark pada file media. Topik ini menjelaskan cara memanggil operasi API untuk mengunggah file media serta menyediakan demo lengkap.

Informasi latar belakang

Jika Anda mengunggah file media dengan memanggil API ApsaraVideo VOD, SDK Object Storage Service (OSS) digunakan untuk pengunggahan. Anda perlu menentukan semua logika pengunggahan, termasuk mendapatkan URL dan kredensial pengunggahan, mendekode URL dan kredensial yang di-enkode Base64, serta menggunakan kemampuan OSS untuk mengunggah file media. Proses ini kompleks dan rentan terhadap kesalahan. Topik ini menyediakan demo pengunggahan untuk membantu Anda menyelesaikan masalah ketika file media tetap dalam status Uploading setelah memanggil operasi API untuk mengunggah file media.

Catatan
  • Mengunggah file media menggunakan API ApsaraVideo VOD adalah metode berbasis OSS. Untuk informasi lebih lanjut, lihat Ikhtisar.

  • Topik ini menyediakan kode contoh dalam Java. Untuk informasi lebih lanjut tentang kode contoh dalam bahasa lain, lihat Unggah File Media dengan Menggunakan SDK OSS.

  • Jika Anda memiliki pertanyaan atau saran tambahan, bergabunglah dengan grup DingTalk 11370001915 untuk dukungan teknis.

Sebelum Anda mulai

Langkah 1: Instal SDK ApsaraVideo VOD

Untuk informasi lebih lanjut, lihat Instalasi.

Langkah 2: Instal SDK OSS

Untuk informasi lebih lanjut, lihat Instal SDK OSS untuk Java.

Langkah 3: Mulai pengunggahan

Berikut adalah kode contoh untuk beberapa operasi: unggah file media lokal, unggah aliran jaringan berdasarkan URL, unggah file M3U8 lokal, lakukan pengunggahan multipart, dan lakukan pengunggahan yang dapat dilanjutkan. Untuk informasi lebih lanjut tentang kode contoh yang digunakan untuk mendapatkan URL dan kredensial pengunggahan serta mendekode URL dan kredensial yang di-enkode Base64, lihat bagian Kode Contoh dari topik ini.

Unggah file dari PC lokal Anda

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);
            // Jika pengunggahan berhasil, kode status HTTP 200 dikembalikan.
            // Konfigurasikan parameter bilah kemajuan selama pengunggahan. UploadOss menentukan nama kelas yang dipanggil untuk mengunggah file lokal. Ganti UploadOss dengan nama kelas yang ingin Anda panggil dalam penggunaan sebenarnya.
//            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("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                    + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
            System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
            System.out.println("Kode Kesalahan:" + oe.getErrorCode());
            System.out.println("ID Permintaan:" + oe.getRequestId());
            System.out.println("ID Host:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                    + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                    + "seperti tidak dapat mengakses jaringan.");
            System.out.println("Pesan Kesalahan:" + ce.getMessage());
        } finally {
            // Matikan instance OSSClient.
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

Unggah aliran jaringan berdasarkan URL

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);
        // Jika pengunggahan berhasil, kode status HTTP 200 dikembalikan.
        System.out.println(result.getResponse().getStatusCode());
    } catch (OSSException oe) {
        System.out.println("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
        System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
        System.out.println("Kode Kesalahan:" + oe.getErrorCode());
        System.out.println("ID Permintaan:" + oe.getRequestId());
        System.out.println("ID Host:" + oe.getHostId());
    } catch (Throwable ce) {
        System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                + "seperti tidak dapat mengakses jaringan.");
        System.out.println("Pesan Kesalahan:" + ce.getMessage());
    } finally {
        // Matikan instance OSSClient.
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }
}

Unggah file M3U8 lokal

Catatan

Untuk mengunggah file M3U8 lokal beserta file bagiannya, Anda harus menentukan URL file indeks M3U8 dan URL bagiannya.

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 {
            // Unggah file indeks.
            File index = new File(indexFile);
            ossClient.putObject(bucketName, objectName, index);
            Thread.sleep(200);
            // Unggah file TS.
            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("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                    + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
            System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
            System.out.println("Kode Kesalahan:" + oe.getErrorCode());
            System.out.println("ID Permintaan:" + oe.getRequestId());
            System.out.println("ID Host:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                    + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                    + "seperti tidak dapat mengakses jaringan.");
            System.out.println("Pesan Kesalahan:" + ce.getMessage());
        } finally {
            // Matikan instance OSSClient.
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

Lakukan pengunggahan multipart dan pengunggahan yang dapat dilanjutkan

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);
        // Konfigurasikan parameter dengan menggunakan UploadFileRequest.
        // Tentukan jalur lengkap file lokal yang ingin Anda unggah. Contoh: D:\\localpath\\examplefile.mp4. Secara default, jika Anda tidak menentukan jalur lengkap, file lokal diunggah dari jalur proyek tempat program contoh milik.
        uploadFileRequest.setUploadFile(localFile);
        // Tentukan jumlah thread konkuren untuk tugas pengunggahan. Nilai default: 1.
        uploadFileRequest.setTaskNum(5);
        // Tentukan ukuran setiap bagian. Unit: byte. Nilai valid: 100 KB hingga 5 GB. Nilai default: 100 KB.
        uploadFileRequest.setPartSize(1 * 1024 * 1024);
        // Tentukan apakah akan mengaktifkan pengunggahan yang dapat dilanjutkan. Secara default, pengunggahan yang dapat dilanjutkan dinonaktifkan.
        uploadFileRequest.setEnableCheckpoint(true);
        // Tentukan file yang mencatat hasil pengunggahan setiap bagian. File titik pemeriksaan ini menyimpan informasi tentang kemajuan pengunggahan. Jika sebuah bagian gagal diunggah, tugas dapat dilanjutkan berdasarkan kemajuan yang dicatat dalam file titik pemeriksaan. Setelah file lokal diunggah, file titik pemeriksaan dihapus.
        // Secara default, jika Anda tidak menentukan parameter ini, file titik pemeriksaan disimpan di direktori yang sama dengan file yang ingin Anda unggah. Direktori bernama ${uploadFile}.ucp.
        //uploadFileRequest.setCheckpointFile("yourCheckpointFile");
        // Mulai pengunggahan yang dapat dilanjutkan.
        ossClient.uploadFile(uploadFileRequest);

    } catch (OSSException oe) {
        System.out.println("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
        System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
        System.out.println("Kode Kesalahan:" + oe.getErrorCode());
        System.out.println("ID Permintaan:" + oe.getRequestId());
        System.out.println("ID Host:" + oe.getHostId());
    } catch (Throwable ce) {
        System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                + "seperti tidak dapat mengakses jaringan.");
        System.out.println("Pesan Kesalahan:" + ce.getMessage());
    } finally {
        // Matikan instance OSSClient.
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }
}

Kode contoh

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;

/**
 * *****   Catatan Penggunaan     ******!!
 * Kode contoh berikut memberikan contoh cara mengunggah file media ke ApsaraVideo VOD dengan memanggil operasi API dalam Java. Untuk informasi lebih lanjut tentang cara menggunakan OSS SDK untuk Java untuk mengunggah file media, kunjungi https://www.alibabacloud.com/help/object-storage-service/latest/overview-3.
 * Demo ini tidak dapat digunakan sebagai SDK pengunggahan. Untuk informasi lebih lanjut tentang cara menggunakan SDK pengunggahan, kunjungi https://www.alibabacloud.com/help/apsaravideo-for-vod/latest/upload-sdk-overview.
 * <p>
 * 1. Unggah file audio dan video biasa
 *
 * 1.1 Unggah file lokal. Anda dapat menggunakan pengunggahan multipart untuk mengunggah file lokal. Pengunggahan yang dapat dilanjutkan juga didukung.
 * 1.1.1 Durasi maksimum tugas pengunggahan adalah 3.000 detik jika pengunggahan yang dapat dilanjutkan dinonaktifkan. Ukuran maksimum file yang dapat diunggah bervariasi berdasarkan bandwidth jaringan dan kapasitas baca/tulis disk. Untuk informasi lebih lanjut, lihat deskripsi fungsi uploadEnableCheckPointFile.
 * 1.1.2 Jika Anda mengaktifkan pengunggahan yang dapat dilanjutkan, Anda dapat mengunggah file hingga 48,8 TB. Selama pengunggahan yang dapat dilanjutkan, ApsaraVideo VOD menulis kemajuan pengunggahan ke file disk lokal. Ini memengaruhi kecepatan pengunggahan. Anda dapat memilih untuk mengaktifkan fitur pengunggahan yang dapat dilanjutkan berdasarkan ukuran file Anda.
 *
 * 1.2 Unggah aliran jaringan. Anda dapat menentukan URL pengunggahan untuk mengunggah aliran jaringan. Anda dapat mengunggah file hingga 48,8 TB. Untuk informasi lebih lanjut, lihat deskripsi fungsi uploadURLFile.
 *
 * 1.3 Unggah aliran file. Anda dapat mengunggah file lokal tertentu. Fitur pengunggahan yang dapat dilanjutkan tidak didukung saat Anda mengunggah aliran file. Anda dapat mengunggah file hingga 5 GB. Untuk informasi lebih lanjut, lihat deskripsi fungsi uploadLocalFile.
 *
 * <p>
 * 2. Unggah file M3U8
 * 2.1. Unggah file audio dan video dalam format M3U8 lokal ke ApsaraVideo VOD. Anda harus mengunggah URL file indeks M3U8 dan URL bagian. Untuk informasi lebih lanjut, lihat deskripsi fungsi uploadLocalM3U8.
 * 2.2. Unggah file audio dan video M3U8 online. Kami sarankan Anda menggunakan URL untuk mengunggah file audio dan video M3U8 online.
 *
 * Catatan:
 * Jika Anda ingin menggunakan URL untuk mengunggah file audio dan video M3U8 online, URL tersebut harus dapat diakses. Jika Anda ingin membatasi akses ke file media, tentukan URL yang mencakup informasi tanda tangan dan pastikan URL tetap valid untuk mencegah kegagalan pengunggahan karena URL yang tidak dapat diakses.
 * <p>
 *
 * 3. Dengarkan kemajuan pengunggahan
 * 3.1 Gunakan fungsi callback default untuk mendengarkan kemajuan pengunggahan. Anda harus memanggil kelas ProgressListener untuk menggunakan fungsi callback default. Untuk informasi lebih lanjut, kunjungi https://www.alibabacloud.com/help/object-storage-service/latest/upload-progress-bars-4.
 * 3.2 Gunakan fungsi callback kustom untuk mendengarkan kemajuan pengunggahan. Anda dapat menentukan metode yang ingin Anda gunakan untuk menangani peristiwa berbeda berdasarkan kebutuhan bisnis Anda dengan menggunakan fungsi callback kustom.
 * 3.3 Untuk informasi lebih lanjut tentang cara menggunakan fungsi callback kustom, lihat baris 225 dalam kode contoh.
 *
 * <p>
 *
 * 4. Panggil operasi API
 * 4.1 Anda dapat memanggil operasi CreateUploadVideo atau RefreshUploadVideo untuk mendapatkan kredensial pengunggahan berdasarkan kebutuhan bisnis Anda.
 * 4.2 Anda dapat memanggil operasi RefreshUploadVideo untuk memperbarui kredensial pengunggahan setelah kedaluwarsa. Anda juga dapat memanggil operasi ini untuk menimpa file media yang telah diunggah dengan menggunakan videoId.
 * 4.3 Anda dapat memanggil operasi CreateUploadImage untuk mendapatkan kredensial pengunggahan untuk gambar.
 * 4.4 Anda dapat memanggil operasi CreateUploadAttachedMedia untuk mendapatkan kredensial pengunggahan untuk aset media tambahan.
 * 4.5 Untuk informasi lebih lanjut tentang operasi API, kunjungi https://www.alibabacloud.com/help/apsaravideo-for-vod/latest/api-doc-vod-2017-03-21-api-overview.
 *
 * <p>
 *
 * Catatan:
 * Tentukan parameter yang diperlukan dan hapus parameter opsional yang tidak perlu Anda tentukan dalam kode contoh berdasarkan kebutuhan bisnis Anda. Ini mencegah kesalahan yang disebabkan oleh nilai parameter yang tidak valid.
 */
public class UploadVodByApiDemo implements ProgressListener {

    // Opsional. Tentukan parameter terkait bilah kemajuan pengunggahan.
    private long bytesWritten = 0;
    private long totalBytes = -1;
    private boolean succeed = false;

    public static void main(String[] argv) {
        // Pasangan AccessKey akun Alibaba Cloud memiliki izin untuk semua operasi API. Kami sarankan Anda menggunakan pengguna RAM untuk memanggil operasi API atau melakukan pemeliharaan rutin.
        // Kami sarankan Anda tidak menyimpan pasangan AccessKey (AccessKey ID dan AccessKey secret) di kode proyek Anda. Jika tidak, pasangan AccessKey mungkin bocor. Akibatnya, keamanan semua sumber daya dalam akun Anda terancam.
        // Dalam contoh ini, ApsaraVideo VOD membaca pasangan AccessKey dari variabel lingkungan untuk mengimplementasikan verifikasi identitas untuk akses API. Sebelum menjalankan kode contoh, konfigurasikan variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET.
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        // Tentukan jalur lengkap file video lokal yang ingin Anda unggah ke ApsaraVideo VOD. Jalur tersebut harus berisi ekstensi nama file.
        String localFile = "E:/demo/demo.mp4";
        // Tentukan alamat aliran jaringan. URL tersebut harus dapat diakses.
        String url = "https://bucket-name*****.oss-cn-shanghai.aliyuncs.com/demo/demo.mp4";

        try {
            // Inisialisasi klien ApsaraVideo VOD dan dapatkan URL pengunggahan serta kredensial pengunggahan.
            DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);

            // Dapatkan kredensial pengunggahan untuk video.
            CreateUploadVideoResponse createUploadVideoResponse = createUploadVideo(vodClient);
            // Perbarui kredensial pengunggahan.
            //RefreshUploadVideoResponse refreshUploadVideoResponse = refreshUploadVideo(vodClient);
            // Dapatkan kredensial pengunggahan untuk gambar.
            //CreateUploadImageResponse createUploadImageResponse = createUploadImage(vodClient);
            // Dapatkan kredensial pengunggahan untuk aset media tambahan.
            //CreateUploadAttachedMediaResponse createUploadAttachedMediaResponse = createUploadAttachedMedia(vodClient);

            // Jika kode sebelumnya berhasil dieksekusi, parameter videoId, uploadAddress, dan uploadAuth dikembalikan.
            String videoId = createUploadVideoResponse.getVideoId();
            JSONObject uploadAuth = JSONObject.parseObject(decodeBase64(createUploadVideoResponse.getUploadAuth()));
            JSONObject uploadAddress = JSONObject.parseObject(decodeBase64(createUploadVideoResponse.getUploadAddress()));

            // Gunakan URL pengunggahan yang didekode dan kredensial pengunggahan untuk menginisialisasi klien OSS.
           // Tentukan uploadAuth dan uploadAddress dengan menggunakan klien OSS untuk mengunggah file video ke OSS.
            OSSClient ossClient = initOssClient(uploadAuth, uploadAddress);

            // Tentukan metode pengunggahan berdasarkan kebutuhan bisnis Anda.
            // 1. Unggah file lokal. Harap perhatikan bahwa beberapa bagian diunggah secara sinkron. Ini dapat memperpanjang waktu tunggu. Waktu yang dibutuhkan bergantung pada ukuran file dan bandwidth upstream.
            uploadLocalFile(ossClient, uploadAddress, localFile);
            // 2. Unggah file online.
            //uploadURLFile(ossClient, uploadAddress, url);
            // 3. Lakukan pengunggahan multipart dan pengunggahan yang dapat dilanjutkan.
            //uploadEnableCheckPointFile(ossClient, uploadAddress, localFile);
            // 4. Unggah file M3U8.
            //String indexFile = "E:/demo/demo.m3u8";
            //String[] tsFiles = {"E:/demo/demo_01.ts"};
            //uploadLocalM3U8(ossClient, uploadAddress, indexFile, tsFiles);

            System.out.println("Unggah file lokal berhasil, VideoId : " + videoId);
        } catch (Exception e) {
            System.out.println("Unggah file lokal gagal, Pesan Kesalahan : " + e.getLocalizedMessage());
        }
    }

    /**
     * Inisialisasi klien ApsaraVideo VOD.
     * @throws ClientException
     */
    public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
        // Tentukan wilayah tempat ApsaraVideo VOD diaktifkan. Tentukan cn-shanghai jika ApsaraVideo VOD diaktifkan di Tiongkok Daratan. Untuk informasi lebih lanjut tentang wilayah lain yang didukung, kunjungi 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;
    }

    /**
     * Inisialisasi klien OSS.
     * @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);
    }

    /**
     * Dapatkan kredensial pengunggahan.
     * @throws ClientException
     */
    public static CreateUploadVideoResponse createUploadVideo(DefaultAcsClient vodClient) throws ClientException {
        CreateUploadVideoRequest request = new CreateUploadVideoRequest();
        request.setFileName("vod_test.m3u8");
        request.setTitle("ini adalah judul");
        //request.setDescription("ini adalah deskripsi");
        //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);
    }

    /**
     * Perbarui kredensial pengunggahan.
     * @throws ClientException
     */
    public static RefreshUploadVideoResponse refreshUploadVideo(DefaultAcsClient vodClient) throws ClientException {
        RefreshUploadVideoRequest request = new RefreshUploadVideoRequest();
        request.setAcceptFormat(FormatType.JSON);
        request.setVideoId("VideoId");

        // Atur periode timeout permintaan.
        request.setSysReadTimeout(1000);
        request.setSysConnectTimeout(1000);

        return vodClient.getAcsResponse(request);
    }

    /**
     * Dapatkan kredensial pengunggahan untuk gambar.
     * @throws ClientException
     */
    public static CreateUploadImageResponse createUploadImage(DefaultAcsClient vodClient) throws ClientException {
        CreateUploadImageRequest request = new CreateUploadImageRequest();
        request.setImageType("default");
        request.setAcceptFormat(FormatType.JSON);

        // Atur periode timeout permintaan.
        request.setSysReadTimeout(1000);
        request.setSysConnectTimeout(1000);

        return vodClient.getAcsResponse(request);
    }

    /**
     * Dapatkan kredensial pengunggahan untuk aset media tambahan.
     * @throws ClientException
     */
    public static CreateUploadAttachedMediaResponse createUploadAttachedMedia(DefaultAcsClient vodClient) throws ClientException {
        CreateUploadAttachedMediaRequest request = new CreateUploadAttachedMediaRequest();
        request.setBusinessType("watermark");
        request.setMediaExt("png");
        request.setAcceptFormat(FormatType.JSON);

        // Atur periode timeout permintaan.
        request.setSysReadTimeout(1000);
        request.setSysConnectTimeout(1000);

        return vodClient.getAcsResponse(request);
    }

    /**
     *  Unggah file lokal.
     * @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);
            // Jika pengunggahan berhasil, kode status HTTP 200 dikembalikan.
            // Konfigurasikan parameter bilah kemajuan selama pengunggahan. UploadOss menentukan nama kelas yang dipanggil untuk mengunggah file lokal. Ganti UploadOss dengan nama kelas yang ingin Anda panggil dalam penggunaan sebenarnya.
//            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("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                    + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
            System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
            System.out.println("Kode Kesalahan:" + oe.getErrorCode());
            System.out.println("ID Permintaan:" + oe.getRequestId());
            System.out.println("ID Host:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                    + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                    + "seperti tidak dapat mengakses jaringan.");
            System.out.println("Pesan Kesalahan:" + ce.getMessage());
        } finally {
            // Matikan instance OSSClient.
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *  Unggah aliran jaringan.
     * @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);
            // Jika pengunggahan berhasil, kode status HTTP 200 dikembalikan.
            System.out.println(result.getResponse().getStatusCode());
        } catch (OSSException oe) {
            System.out.println("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                    + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
            System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
            System.out.println("Kode Kesalahan:" + oe.getErrorCode());
            System.out.println("ID Permintaan:" + oe.getRequestId());
            System.out.println("ID Host:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                    + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                    + "seperti tidak dapat mengakses jaringan.");
            System.out.println("Pesan Kesalahan:" + ce.getMessage());
        } finally {
            // Matikan instance OSSClient.
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *  Mulai pengunggahan yang dapat dilanjutkan.
     * @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);
            // Konfigurasikan parameter dengan menggunakan UploadFileRequest.
            // Tentukan jalur lengkap file lokal yang ingin Anda unggah. Contoh: D:\\localpath\\examplefile.mp4. Secara default, jika Anda tidak menentukan jalur lengkap, file lokal diunggah dari jalur proyek tempat program contoh milik.
            uploadFileRequest.setUploadFile(localFile);
            // Tentukan jumlah thread konkuren untuk tugas pengunggahan. Nilai default: 1.
            uploadFileRequest.setTaskNum(5);
            // Tentukan ukuran setiap bagian. Unit: byte. Nilai valid: 100 KB hingga 5 GB. Nilai default: 100 KB.
            uploadFileRequest.setPartSize(1 * 1024 * 1024);
            // Tentukan apakah akan mengaktifkan pengunggahan yang dapat dilanjutkan. Secara default, pengunggahan yang dapat dilanjutkan dinonaktifkan.
            uploadFileRequest.setEnableCheckpoint(true);
            // Tentukan file yang mencatat hasil pengunggahan setiap bagian. File titik pemeriksaan ini menyimpan informasi tentang kemajuan pengunggahan. Jika sebuah bagian gagal diunggah, tugas dapat dilanjutkan berdasarkan kemajuan yang dicatat dalam file titik pemeriksaan. Setelah file lokal diunggah, file titik pemeriksaan dihapus.
            // Secara default, jika Anda tidak menentukan parameter ini, file titik pemeriksaan disimpan di direktori yang sama dengan file yang ingin Anda unggah. Direktori bernama ${uploadFile}.ucp.
            //uploadFileRequest.setCheckpointFile("yourCheckpointFile");
            // Mulai pengunggahan yang dapat dilanjutkan.
            ossClient.uploadFile(uploadFileRequest);

        } catch (OSSException oe) {
            System.out.println("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                    + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
            System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
            System.out.println("Kode Kesalahan:" + oe.getErrorCode());
            System.out.println("ID Permintaan:" + oe.getRequestId());
            System.out.println("ID Host:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                    + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                    + "seperti tidak dapat mengakses jaringan.");
            System.out.println("Pesan Kesalahan:" + ce.getMessage());
        } finally {
            // Matikan instance OSSClient.
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     *  Unggah file media M3U8 lokal.
     * @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 {
            // Unggah file indeks.
            File index = new File(indexFile);
            ossClient.putObject(bucketName, objectName, index);
            Thread.sleep(200);
            // Unggah file TS.
            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("Tangkap OSSException, yang berarti permintaan Anda sampai ke OSS, "
                    + "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
            System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
            System.out.println("Kode Kesalahan:" + oe.getErrorCode());
            System.out.println("ID Permintaan:" + oe.getRequestId());
            System.out.println("ID Host:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Tangkap ClientException, yang berarti klien mengalami "
                    + "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
                    + "seperti tidak dapat mengakses jaringan.");
            System.out.println("Pesan Kesalahan:" + ce.getMessage());
        } finally {
            // Matikan instance OSSClient.
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    // Tulis ulang metode callback untuk menggunakan bilah kemajuan. Kode contoh berikut memberikan contoh:
    @Override
    public void progressChanged(ProgressEvent progressEvent) {
        long bytes = progressEvent.getBytes();
        ProgressEventType eventType = progressEvent.getEventType();
        switch (eventType) {
            case TRANSFER_STARTED_EVENT:
                System.out.println("Mulai mengunggah......");
                break;
            case REQUEST_CONTENT_LENGTH_EVENT:
                this.totalBytes = bytes;
                System.out.println(this.totalBytes + " byte total akan diunggah ke 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 + " byte telah ditulis saat ini, kemajuan pengunggahan: " + percent + "%(" + this.bytesWritten + "/" + this.totalBytes + ")");
                } else {
                    System.out.println(bytes + " byte telah ditulis saat ini, rasio pengunggahan: tidak diketahui" + "(" + this.bytesWritten + "/...)");
                }
                break;
            case TRANSFER_COMPLETED_EVENT:
                this.succeed = true;
                System.out.println("Berhasil mengunggah, " + this.bytesWritten + " byte telah ditransfer secara total");
                break;
            case TRANSFER_FAILED_EVENT:
                System.out.println("Gagal mengunggah, " + this.bytesWritten + " byte telah ditransfer");
                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;
    }
}