All Products
Search
Document Center

ApsaraVideo VOD:Unggah file menggunakan Android SDK

Last Updated:Aug 25, 2026

Gunakan ApsaraVideo VOD Android Upload SDK untuk mengunggah file media dari perangkat lokal ke penyimpanan ApsaraVideo VOD. Topik ini menjelaskan cara mengintegrasikan SDK, mengonfigurasi unggahan, dan menangani error.

Prasyarat

ItemPersyaratan
Versi Android minimumAPI 14 (Android 4.0)
Versi kompilasicompileSdkVersion 30
Akun Alibaba CloudTelah diperolehAktifkan ApsaraVideo VOD
Layanan otorisasiLayanan backend yang dapat menerbitkan kredensial unggah (UploadAuth)

Batasan penggunaan

  • Android SDK mendukung pengunggahan audio, video, dan gambar. Pengunggahan aset media pendukung tidak didukung.

Integrasikan SDK

Tambahkan dependensi SDK

Tambahkan repositori Maven Alibaba Cloud ke build.gradle tingkat proyek:

allprojects {
    repositories {
        maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
    }
}

Tambahkan dependensi SDK ke build.gradle tingkat modul:

dependencies {
    implementation 'com.aliyun.video.android:upload:2.0.1'
}

OSS Android SDK yang mendasari disertakan secara transitif melalui dependensi api dari VODUpload. Anda tidak perlu mendeklarasikannya lagi.

Konfigurasi proyek

Deklarasikan izin yang diperlukan di AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Izin media granular Android 13+, deklarasikan sesuai kebutuhan -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

Jika Anda mengaktifkan obfuscation kode, tambahkan aturan berikut ke proguard-rules.pro:

-keep class com.alibaba.sdk.android.vod.upload.v2.** { *; }
-keep interface com.alibaba.sdk.android.vod.upload.v2.** { *; }

OSS Android SDK yang mendasari telah menyertakan aturan ProGuard bawaan. Anda tidak perlu mendeklarasikannya lagi.

Penggunaan dasar

Penanganan callback

Upload SDK (v2) menggunakan callback asinkron terpadu VODGetAuthCallback untuk meminta kredensial unggah dari lapisan bisnis. SDK memanggil getAuth dalam skenario berikut dan menggunakan VODAuthContext.getKind() untuk menunjukkan jenis kredensial yang diperlukan:

JenisPemicuOperasi OpenAPI yang dipanggil
CREATE_VIDEOUnggahan pertama file videoCreateUploadVideo
REFRESH_VIDEOUnggah yang dapat dilanjutkan / refresh kredensialRefreshUploadVideo
CREATE_IMAGEUnggah gambarCreateUploadImage

Lapisan bisnis hanya perlu meneruskan respons JSON mentah dari backend OpenAPI kembali ke SDK apa adanya. SDK membaca kunci berikut menggunakan nama bidang OpenAPI yang tepat (sensitif terhadap huruf besar/kecil):

JenisBidang yang diperlukan
CREATE_VIDEO / REFRESH_VIDEOUploadAuth, UploadAddress, VideoId
CREATE_IMAGEUploadAuth, UploadAddress, ImageId, ImageURL (diteruskan ke result.getImageUrl())

Jangan mengganti nama bidang tersebut. Mengganti nama bidang menjadi videoId, imageUrl, atau image_url menyebabkan SDK menguraikannya sebagai null.

Contoh berikut menunjukkan implementasi getAuth yang menangani setiap jenis:

VODGetAuthCallback getAuth = (ctx, completion) -> {
    switch (ctx.getKind()) {
        case CREATE_VIDEO:
            yourBackend.createUploadVideo(ctx.getFileName(), ctx.getFileSize(),
                json -> completion.onSuccess(json),
                err -> completion.onFailure("BIZ.CREATE_VIDEO", err.getMessage()));
            break;
        case REFRESH_VIDEO:
            yourBackend.refreshUploadVideo(ctx.getVideoId(),
                json -> completion.onSuccess(json),
                err -> completion.onFailure("BIZ.REFRESH_VIDEO", err.getMessage()));
            break;
        case CREATE_IMAGE:
            yourBackend.createUploadImage(ctx.getFileName(),
                json -> completion.onSuccess(json),
                err -> completion.onFailure("BIZ.CREATE_IMAGE", err.getMessage()));
            break;
    }
};

Inisialisasi instans unggah

Gunakan VODUploadConfig.Builder untuk membuat konfigurasi dan panggil VODUploadClient.create(...) untuk membuat instans unggah:

import com.alibaba.sdk.android.vod.upload.v2.*;

VODUploadConfig config = new VODUploadConfig.Builder()
        .setGetAuth(getAuth)               // Wajib: callback autentikasi. Untuk informasi selengkapnya, lihat "Penanganan callback".
        .build();

VODUploadClient uploader = VODUploadClient.create(context, config);

Instans uploader dapat digunakan kembali. Anda dapat menggunakan instans yang sama untuk mengunggah beberapa file secara konkuren. Panggil uploader.dispose() untuk melepaskan sumber daya saat siklus hidup berakhir.

Kontrol unggah

Panggil upload(...) untuk memulai unggahan. Metode ini mengembalikan handle VODUploadTask yang dapat Anda gunakan untuk membatalkan unggahan:

VODVideoMeta meta = new VODVideoMeta.Builder()
        .setTitle("My Video")
        .setTags("demo")
        .setCateId(1000)
        .build();

VODUploadOptions options = new VODUploadOptions.Builder()
        .setVideoMeta(meta)
        .setOnProgress((percent, uploaded, total) ->
                Log.d("Upload", String.format("%.1f%%", percent * 100)))
        .build();

VODUploadTask task = uploader.upload(filePath, options, new VODUploadResultCallback() {
    @Override public void onSuccess(VODUploadResult r) {
        Log.i("Upload",
                "videoId=" + r.getVideoId()
                + " uploadTaskId=" + r.getUploadTaskId()
                + " etag=" + r.getEtag()
                + " requestId=" + r.getRequestId()
                + " durationMs=" + r.getDurationMs());
    }
    @Override public void onFailure(VODUploadError e) {
        Log.e("Upload", e.getErrorCode() + " : " + e.getErrorMessage(), e.getCause());
    }
});

// Batalkan unggahan di tengah jalan. Unggah yang dapat dilanjutkan diaktifkan secara default. Pemanggilan upload(...) berikutnya untuk file yang sama akan secara otomatis melanjutkan unggahan.
task.cancel();
// task.getUploadTaskId() dapat digunakan untuk mengkorelasikan log atau mengintegrasikan dengan analitik.

upload(...) menyediakan dua overload yang mendukung path file dan URI content:// (kompatibel dengan Scoped Storage Android 10+):

uploader.upload(String filePath, VODUploadOptions options, VODUploadResultCallback callback);
uploader.upload(Uri fileUri, VODUploadOptions options, VODUploadResultCallback callback);

Unggah gambar: SDK secara otomatis menggunakan jalur unggah gambar berdasarkan ekstensi nama file (jpg / jpeg / png / gif / bmp / webp / heic) atau ketika options.imageMeta != null. Di callback sukses, result.getImageId() dan result.getImageUrl() berisi nilai yang valid:

VODImageMeta imgMeta = new VODImageMeta.Builder()
        .setImageType("cover")
        .setTitle("Cover")
        .build();
uploader.upload("/sdcard/cover.jpg",
        new VODUploadOptions.Builder().setImageMeta(imgMeta).build(),
        callback);

Pengaturan lanjutan

Akselerasi unggah

Atur VODVideoMeta.userData ke JSON berikut. Server VOD secara otomatis mengembalikan titik akhir akselerasi transfer global OSS (oss-accelerate.aliyuncs.com) saat menerbitkan UploadAddress. SDK mengunggah langsung ke titik akhir percepatan:

VODVideoMeta meta = new VODVideoMeta.Builder()
        .setTitle("My Video")
        .setUserData("{\"Type\":\"oss\",\"Domain\":\"oss-accelerate.aliyuncs.com\"}")
        .build();

Akselerasi unggah bergantung pada akselerasi transfer global OSS. Anda harus mengaktifkan akselerasi transfer untuk bucket di Konsol OSS. Untuk informasi selengkapnya, lihat Akses OSS menggunakan akselerasi transfer.

Unggah dan transkoding

Tentukan kelompok template transkoding atau alur kerja melalui VODVideoMeta:

VODVideoMeta meta = new VODVideoMeta.Builder()
        .setTitle("My Video")
        .setDescription("Video description")
        .setCoverUrl("https://example.com/cover.jpg")
        .setCateId(1000)
        .setTags("tag1,tag2")
        .setStorageLocation("<Opsional: wilayah penyimpanan kustom>")
        .setTemplateGroupId("<ID kelompok template Anda>")    // kelompok template transkoding
        .setWorkflowId("<ID alur kerja Anda>")          // Alur kerja (opsional)
        .setAppId("<Opsional: ID aplikasi>")
        .build();

VODVideoMeta mendukung bidang berikut: title / description / coverUrl / cateId / tags / userData / storageLocation / templateGroupId / workflowId / appId. Semua bidang bersifat opsional dan diteruskan ke CreateUploadVideo.

Setelah unggahan selesai, server VOD melakukan transkoding video sumber berdasarkan kelompok template transkoding. Jika Anda tidak ingin memicu transkoding, teruskan kelompok template "tanpa transkoding" dalam pemanggilan CreateUploadVideo dari backend Anda.

Timeout dan retry

Konfigurasikan timeout dan jumlah retry untuk permintaan OSS:

VODUploadConfig config = new VODUploadConfig.Builder()
        .setGetAuth(getAuth)
        .setTimeout(60 * 1000)        // Satuan: milidetik. Default: 60 detik
        .setMaxRetryCount(2)          // Default: 2
        .build();

timeout mengontrol timeout koneksi dan baca/tulis untuk satu permintaan OSS (dalam milidetik). maxRetryCount mengontrol jumlah retry untuk permintaan OSS saat terjadi exception jaringan.

Versi signature

Tentukan versi signature OSS:

VODUploadConfig config = new VODUploadConfig.Builder()
        .setGetAuth(getAuth)
        .setSignature("v4")          // Default: "v4". Opsi: "v1"
        .build();

Signature OSS V4 adalah versi yang direkomendasikan. Mulai 1 September 2025, bucket yang baru dibuat harus menggunakan signature V4. Pelanggan yang sudah ada juga disarankan untuk segera migrasi. Atur "v1" secara eksplisit hanya jika bucket Anda masih hanya mendukung signature V1.

Unggah yang dapat dilanjutkan

Secara default, unggah yang dapat dilanjutkan diaktifkan. SDK menggunakan triplet (lastModified, fileName, fileSize) sebagai kunci unggah yang dapat dilanjutkan dan secara otomatis menyimpannya ke SharedPreferences.

SkenarioPerilaku SDK
task.cancel() dipanggil selama unggahanCatatan unggah yang dapat dilanjutkan dipertahankan. Pemanggilan upload(...) berikutnya untuk file yang sama secara otomatis melanjutkan unggahan.
Crash aplikasi / terminasi prosesCatatan unggah yang dapat dilanjutkan dipertahankan. Pemanggilan upload(...) cold start berikutnya untuk file yang sama secara otomatis melanjutkan unggahan.
Adanya perubahan pada sidik jari fileFile dianggap sebagai file baru dan diunggah dari awal.
Kedaluwarsa uploadId OSSSDK secara otomatis menghapus catatan lama dan memulai unggahan baru melalui CREATE_VIDEO.

Untuk menonaktifkan unggah yang dapat dilanjutkan:

new VODUploadConfig.Builder().setGetAuth(getAuth).setCheckpoint(false).build();

Unggah multipart

Gunakan partSize untuk mengontrol ukuran part dan parallel untuk mengontrol jumlah part konkuren:

// Konfigurasi global
VODUploadConfig config = new VODUploadConfig.Builder()
        .setGetAuth(getAuth)
        .setPartSize(1024 * 1024)     // Default: 1 MB
        .setParallel(4)               // Default: 4
        .build();

// Timpa untuk satu task
VODUploadOptions options = new VODUploadOptions.Builder()
        .setVideoMeta(meta)
        .setPartSize(2 * 1024 * 1024)
        .setParallel(6)
        .build();

Tentukan wilayah layanan VOD

Tentukan wilayah layanan ApsaraVideo VOD:

new VODUploadConfig.Builder()
        .setGetAuth(getAuth)
        .setRegion("cn-shanghai")     // Default: cn-shanghai
        .build();

Untuk daftar wilayah yang didukung, lihat ID wilayah ApsaraVideo VOD.

Pelaporan data

Secara default, SDK mengaktifkan instrumentasi jalur unggah untuk pemantauan kualitas produk. Hanya metrik waktu proses dari proses unggah yang dikumpulkan. Konten file tidak dikumpulkan. Untuk menonaktifkan pelaporan data:

VODUploadConfig config = new VODUploadConfig.Builder()
        .setGetAuth(getAuth)
        .setReportEnabled(false)     // Default: true
        .build();

Penanganan error

VODUploadError merupakan turunan dari java.lang.Exception. Kode error mengikuti format tiga segmen UPLOAD.{LAYER}.{TIPE}:

LAYERKode errorDeskripsi
AUTHUPLOAD.AUTH.GET_AUTH_FAILEDCallback getAuth gagal.
AUTHUPLOAD.AUTH.DECODE_FAILEDGagal mengurai UploadAuth.
AUTHUPLOAD.AUTH.EXPIREDKredensial telah kedaluwarsa.
OSSUPLOAD.OSS.ACCESS_DENIEDAkses OSS ditolak (masalah izin/signature).
OSSUPLOAD.OSS.NO_SUCH_BUCKETBucket tidak ada.
OSSUPLOAD.OSS.NO_SUCH_UPLOADuploadId telah kedaluwarsa. SDK secara otomatis kembali ke unggahan baru.
OSSUPLOAD.OSS.UPLOAD_FAILEDUnggahan OSS gagal.
OSSUPLOAD.OSS.MERGE_FAILEDPenggabungan multipart OSS gagal.
NETWORKUPLOAD.NETWORK.TIMEOUTTimeout jaringan.
NETWORKUPLOAD.NETWORK.UNREACHABLEJaringan tidak dapat dijangkau.
FILEUPLOAD.FILE.NOT_FOUNDFile tidak ada.
FILEUPLOAD.FILE.EMPTYFile kosong.
CANCELUPLOAD.CANCEL.USER_CANCELLEDUnggahan dibatalkan oleh pengguna.
INTERNALUPLOAD.INTERNAL.DISPOSEDInstans telah di-dispose.
INTERNALUPLOAD.INTERNAL.INVALID_CONFIGKonfigurasi tidak valid.

Metode publik dari VODUploadError:

  • String getErrorCode() — Mengembalikan kode error.

  • String getErrorMessage() — Mengembalikan pesan error.

  • String getUploadTaskId() — Mengembalikan ID task unggah.

  • String getSuggestion() — Mengembalikan saran perbaikan bawaan dari SDK.

  • Throwable getCause() — Mengembalikan exception OSS mendasar (diwariskan dari Exception).

Contoh berikut menangani error berdasarkan kode error:

@Override public void onFailure(VODUploadError e) {
    if (e.getErrorCode().startsWith("UPLOAD.AUTH.")) {
        // Prompt pengguna untuk memeriksa autentikasi backend
    } else if (VODUploadError.OSS_UPLOAD_FAILED.equals(e.getErrorCode())) {
        // Coba ulang atau prompt pengguna untuk memeriksa jaringan
    }
    Log.e(TAG, e.getErrorCode() + ": " + e.getErrorMessage()
            + " (suggestion=" + e.getSuggestion() + ")", e.getCause());
}

FAQ

Apakah saya dapat memulai beberapa unggahan secara simultan?

Ya. Setiap task bersifat independen. Sebagai praktik terbaik, kendalikan jumlah unggahan konkuren berdasarkan kondisi jaringan untuk menghindari peningkatan tekanan bandwidth upstream saat dikombinasikan dengan parallel.

Unggah yang dapat dilanjutkan tidak berfungsi setelah pembatalan dan unggah ulang

Periksa hal berikut:

  • Verifikasi bahwa path file sama.

  • Verifikasi bahwa nilai lastModified dan size file tidak berubah.

  • Verifikasi bahwa config.checkpoint diatur ke true.

  • Verifikasi apakah uploadId telah kedaluwarsa. Saat respons adalah NoSuchUpload, SDK secara otomatis kembali ke unggahan baru. Ini adalah perilaku yang diharapkan.

Apa nilai fileName dan fileSize saat mengunggah URI content://?

SDK membaca OpenableColumns.DISPLAY_NAME dan OpenableColumns.SIZE melalui ContentResolver.query(...). Jika ukuran tidak dapat dibaca, UPLOAD.FILE.EMPTY dikembalikan.

Apa yang dikembalikan oleh getCause()?

Nilai kembali diwariskan dari Exception dan mempertahankan ServerException, ClientException, atau IOException OSS mendasar, yang membantu Anda melakukan troubleshooting secara mendalam.