ApsaraVideo VOD Android アップロード SDK を使用して、ローカルデバイスから ApsaraVideo VOD ストレージにメディアファイルをアップロードします。このトピックでは、SDK の統合、アップロードの設定、およびエラーの処理方法について説明します。
前提条件
| 項目 | 要件 |
| Android の最小バージョン | API 14 (Android 4.0) |
| コンパイルバージョン | compileSdkVersion 30 |
| Alibaba Cloud アカウント | 取得済みApsaraVideo VOD の有効化 |
| 認証サービス | アップロード認証情報 (UploadAuth) を発行できるバックエンドサービス |
制限事項
Android SDK は、音声、動画、および画像のアップロードをサポートしています。補助メディアアセットのアップロードはサポートされていません。
SDK の統合
SDK 依存関係の追加
プロジェクトレベルの build.gradle に Alibaba Cloud Maven リポジトリを追加します。
allprojects {
repositories {
maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
}
}モジュールレベルの build.gradle に SDK の依存関係を追加します。
dependencies {
implementation 'com.aliyun.video.android:upload:2.0.1'
}基盤となる OSS Android SDK は、VODUpload の api 依存関係を通じて推移的に含まれます。再度宣言する必要はありません。
プロジェクトの設定
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" />
<!-- Android 13+ の詳細なメディア権限、必要に応じて宣言 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />コードの難読化を有効にする場合は、次のルールを proguard-rules.pro に追加します。
-keep class com.alibaba.sdk.android.vod.upload.v2.** { *; }
-keep interface com.alibaba.sdk.android.vod.upload.v2.** { *; }基盤となる OSS Android SDK には、組み込みの ProGuard ルールが含まれています。再度宣言する必要はありません。
基本的な使用方法
コールバックの処理
アップロード SDK (v2) は、統一された VODGetAuthCallback 非同期コールバックを使用して、ビジネスレイヤーからアップロード認証情報をリクエストします。SDK は、次のシナリオで getAuth を呼び出し、VODAuthContext.getKind() を使用して必要な認証情報のタイプを示します。
| Kind | トリガー | 呼び出す OpenAPI オペレーション |
CREATE_VIDEO | 動画ファイルの初回アップロード | CreateUploadVideo |
REFRESH_VIDEO | 再開可能なアップロード / 認証情報のリフレッシュ | RefreshUploadVideo |
CREATE_IMAGE | 画像のアップロード | CreateUploadImage |
ビジネスレイヤーは、バックエンド OpenAPI からの未加工の JSON 応答をそのまま SDK に渡すだけで済みます。SDK は、次のキーを OpenAPI の正確なフィールド名 (大文字と小文字を区別) で読み取ります。
| Kind | 必須フィールド |
CREATE_VIDEO / REFRESH_VIDEO | UploadAuth、UploadAddress、VideoId |
CREATE_IMAGE | UploadAuth、UploadAddress、ImageId、ImageURL (result.getImageUrl() に渡される) |
フィールド名を変更しないでください。フィールド名を videoId、imageUrl、または image_url に変更すると、SDK はそれらを null として解析します。
次の例は、各 kind を処理する getAuth の実装を示しています。
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;
}
};アップロードインスタンスの初期化
VODUploadConfig.Builder を使用して構成をビルドし、VODUploadClient.create(...) を呼び出してアップロードインスタンスを作成します。
import com.alibaba.sdk.android.vod.upload.v2.*;
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth) // 必須: 認証コールバック。詳細については、「コールバックの処理」をご参照ください。
.build();
VODUploadClient uploader = VODUploadClient.create(context, config);uploader インスタンスは再利用可能です。同じインスタンスを使用して、複数のファイルを同時にアップロードできます。ライフサイクルが終了したら、uploader.dispose() を呼び出してリソースを解放します。
アップロードの制御
upload(...) を呼び出してアップロードを開始します。このメソッドは、アップロードのキャンセルに使用できる VODUploadTask ハンドルを返します。
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());
}
});
// アップロードを途中でキャンセルします。再開可能なアップロードはデフォルトで有効になっています。同じファイルに対する次回の upload(...) 呼び出しで、アップロードが自動的に再開されます。
task.cancel();
// task.getUploadTaskId() は、ログの関連付けや分析との統合に使用できます。upload(...) は、ファイルパスと content:// URI (Android 10+ の Scoped Storage と互換性あり) をサポートする 2 つのオーバーロードを提供します。
uploader.upload(String filePath, VODUploadOptions options, VODUploadResultCallback callback);
uploader.upload(Uri fileUri, VODUploadOptions options, VODUploadResultCallback callback);画像のアップロード: SDK は、ファイル名拡張子 (jpg / jpeg / png / gif / bmp / webp / heic) に基づいて、または options.imageMeta != null の場合に、自動的に画像アップロードパスを使用します。成功コールバックでは、result.getImageId() と result.getImageUrl() に有効な値が含まれます。
VODImageMeta imgMeta = new VODImageMeta.Builder()
.setImageType("cover")
.setTitle("Cover")
.build();
uploader.upload("/sdcard/cover.jpg",
new VODUploadOptions.Builder().setImageMeta(imgMeta).build(),
callback);詳細設定
アップロードアクセラレーション
VODVideoMeta.userData を次の JSON に設定します。VOD サーバーは、UploadAddress を発行する際に、OSS グローバル転送アクセラレーションエンドポイント (oss-accelerate.aliyuncs.com) を自動的に返します。SDK はアクセラレーションエンドポイントに直接アップロードします。
VODVideoMeta meta = new VODVideoMeta.Builder()
.setTitle("My Video")
.setUserData("{\"Type\":\"oss\",\"Domain\":\"oss-accelerate.aliyuncs.com\"}")
.build();アップロードアクセラレーションは、OSS グローバル転送アクセラレーションに依存します。OSS コンソールでバケットの転送アクセラレーションを有効にする必要があります。詳細については、「転送アクセラレーションを使用した OSS へのアクセス」をご参照ください。
アップロードとトランスコード
VODVideoMeta を介してトランスコードテンプレートグループまたはワークフローを指定します。
VODVideoMeta meta = new VODVideoMeta.Builder()
.setTitle("My Video")
.setDescription("Video description")
.setCoverUrl("https://example.com/cover.jpg")
.setCateId(1000)
.setTags("tag1,tag2")
.setStorageLocation("<Optional: custom storage region>")
.setTemplateGroupId("<Your template group ID>") // トランスコードテンプレートグループ
.setWorkflowId("<Your workflow ID>") // ワークフロー (オプション)
.setAppId("<Optional: application ID>")
.build();VODVideoMeta は、title / description / coverUrl / cateId / tags / userData / storageLocation / templateGroupId / workflowId / appId の各フィールドをサポートしています。すべてのフィールドはオプションであり、CreateUploadVideo に渡されます。
アップロードが完了すると、VOD サーバーはトランスコードテンプレートグループに基づいてソースビデオをトランスコードします。トランスコードをトリガーしたくない場合は、バックエンドからの CreateUploadVideo 呼び出しで「トランスコードなし」のテンプレートグループを渡します。
タイムアウトとリトライ
OSS リクエストのタイムアウトとリトライ回数を設定します。
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setTimeout(60 * 1000) // 単位: ミリ秒。デフォルト: 60 秒
.setMaxRetryCount(2) // デフォルト: 2
.build();timeout は、単一の OSS リクエストの接続および読み取り/書き込みタイムアウト (ミリ秒単位) を制御します。maxRetryCount は、ネットワーク例外発生時の OSS リクエストのリトライ回数を制御します。
署名バージョン
OSS 署名バージョンを指定します。
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setSignature("v4") // デフォルト: "v4"。オプション: "v1"
.build();OSS V4 署名は推奨バージョンです。2025 年 9 月 1 日以降、新しく作成されたバケットは V4 署名を使用する必要があります。既存のお客様も、できるだけ早く移行することをお勧めします。バケットが V1 署名のみをサポートしている場合にのみ、明示的に "v1" を設定してください。
再開可能なアップロード
デフォルトでは、再開可能なアップロードが有効になっています。SDK は (lastModified, fileName, fileSize) の 3 つ組を再開可能なアップロードキーとして使用し、自動的に SharedPreferences に永続化します。
| シナリオ | SDK の動作 |
task.cancel() はアップロード中に呼び出されます | 再開可能なアップロードレコードは保持されます。同じファイルに対する次回の upload(...) 呼び出しで、アップロードが自動的に再開されます。 |
| アプリのクラッシュ / プロセスの終了 | 再開可能なアップロードレコードは保持されます。次回のコールドスタート時に同じファイルに対して upload(...) を呼び出すと、アップロードが自動的に再開されます。 |
| ファイルの指紋の変更 | ファイルは新しいファイルとして扱われ、最初からアップロードされます。 |
| OSS uploadId の有効期限切れ | SDK は古いレコードを自動的にクリアし、CREATE_VIDEO を介して新しいアップロードを開始します。 |
再開可能なアップロードを無効にするには:
new VODUploadConfig.Builder().setGetAuth(getAuth).setCheckpoint(false).build();マルチパートアップロード
partSize を使用してパートサイズを制御し、parallel を使用して同時パート数を制御します。
// グローバル設定
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setPartSize(1024 * 1024) // デフォルト: 1 MB
.setParallel(4) // デフォルト: 4
.build();
// 単一タスクのオーバーライド
VODUploadOptions options = new VODUploadOptions.Builder()
.setVideoMeta(meta)
.setPartSize(2 * 1024 * 1024)
.setParallel(6)
.build();VOD サービスリージョンの設定
ApsaraVideo VOD サービスのリージョンを指定します。
new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setRegion("cn-shanghai") // デフォルト: cn-shanghai
.build();サポートされているリージョンの一覧については、「ApsaraVideo VOD のリージョン ID」をご参照ください。
データレポート
デフォルトでは、SDK はプロダクト品質のモニタリングのためにアップロードパスのイベントトラッキングを有効にします。アップロードプロセスのランタイムメトリックのみが収集され、ファイルコンテンツは収集されません。データレポートを無効にするには:
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setReportEnabled(false) // デフォルト: true
.build();エラー処理
VODUploadError は java.lang.Exception を継承します。エラーコードは UPLOAD.{LAYER}.{TYPE} の 3 セグメント形式に従います。
| LAYER | エラーコード | 説明 |
| AUTH | UPLOAD.AUTH.GET_AUTH_FAILED | getAuth コールバックが失敗しました。 |
| AUTH | UPLOAD.AUTH.DECODE_FAILED | UploadAuth のデコードに失敗しました。 |
| AUTH | UPLOAD.AUTH.EXPIRED | 認証情報が期限切れです。 |
| OSS | UPLOAD.OSS.ACCESS_DENIED | OSS アクセスが拒否されました (権限/署名の問題)。 |
| OSS | UPLOAD.OSS.NO_SUCH_BUCKET | バケットが存在しません。 |
| OSS | UPLOAD.OSS.NO_SUCH_UPLOAD | uploadId が期限切れです。SDK は自動的に新しいアップロードにフォールバックします。 |
| OSS | UPLOAD.OSS.UPLOAD_FAILED | OSS アップロードが失敗しました。 |
| OSS | UPLOAD.OSS.MERGE_FAILED | OSS マルチパートマージが失敗しました。 |
| NETWORK | UPLOAD.NETWORK.TIMEOUT | ネットワークタイムアウト。 |
| NETWORK | UPLOAD.NETWORK.UNREACHABLE | ネットワークに到達できません。 |
| FILE | UPLOAD.FILE.NOT_FOUND | ファイルが存在しません。 |
| FILE | UPLOAD.FILE.EMPTY | ファイルが空です。 |
| CANCEL | UPLOAD.CANCEL.USER_CANCELLED | アップロードはユーザーによってキャンセルされました。 |
| INTERNAL | UPLOAD.INTERNAL.DISPOSED | インスタンスは破棄されました。 |
| INTERNAL | UPLOAD.INTERNAL.INVALID_CONFIG | 無効な設定です。 |
VODUploadError のパブリックメソッド:
String getErrorCode()— エラーコードを返します。String getErrorMessage()— エラーメッセージを返します。String getUploadTaskId()— アップロードタスク ID を返します。String getSuggestion()— SDK からの組み込みの修正提案を返します。Throwable getCause()— 基になる OSS 例外を返します (Exceptionから継承)。
次の例では、エラーコードに基づいてエラーを処理します。
@Override public void onFailure(VODUploadError e) {
if (e.getErrorCode().startsWith("UPLOAD.AUTH.")) {
// ユーザーにバックエンド認証の確認を促す
} else if (VODUploadError.OSS_UPLOAD_FAILED.equals(e.getErrorCode())) {
// リトライするか、ユーザーにネットワークの確認を促す
}
Log.e(TAG, e.getErrorCode() + ": " + e.getErrorMessage()
+ " (suggestion=" + e.getSuggestion() + ")", e.getCause());
}よくある質問
複数のアップロードを同時に開始できますか?
はい。各 task は独立しています。ベストプラクティスとして、parallel と組み合わせた場合にアップストリーム帯域幅への負荷が増大するのを避けるため、ネットワーク状況に基づいて同時アップロード数を制御してください。
キャンセルして再アップロードした後、再開可能なアップロードが機能しない
以下を確認してください。
ファイルパスが同じであることを確認します。
ファイルの
lastModifiedとsizeの値が変更されていないことを確認します。config.checkpointがtrueに設定されていることを確認します。uploadId が期限切れになっていないか確認します。応答が
NoSuchUploadの場合、SDK は自動的に新しいアップロードにフォールバックします。これは期待される動作です。
content:// URI をアップロードするときの fileName と fileSize の値は何ですか?
SDK は ContentResolver.query(...) を介して OpenableColumns.DISPLAY_NAME と OpenableColumns.SIZE を読み取ります。サイズが読み取れない場合、UPLOAD.FILE.EMPTY が返されます。
getCause() は何を返しますか?
戻り値は Exception を継承し、基になる OSS の ServerException、ClientException、または IOException を保持するため、詳細なトラブルシューティングに役立ちます。