Utilisez le SDK de chargement ApsaraVideo VOD pour Android afin de transférer des fichiers multimédias depuis un appareil local vers le stockage ApsaraVideo VOD. Cette rubrique explique comment intégrer le SDK, configurer les chargements et gérer les erreurs.
Prérequis
| Élément | Exigence |
| Version minimale d'Android | API 14 (Android 4.0) |
| Version de compilation | compileSdkVersion 30 |
| Compte Alibaba Cloud | Obtenu Activer ApsaraVideo VOD |
| Service d'autorisation | Un service backend capable d'émettre des identifiants de chargement (UploadAuth) |
Limites d'utilisation
Le SDK Android prend en charge le chargement de fichiers audio, vidéo et images. Le chargement d'actifs multimédias auxiliaires n'est pas pris en charge.
Intégrer le SDK
Ajouter la dépendance du SDK
Ajoutez le dépôt Maven d'Alibaba Cloud au fichier build.gradle au niveau du projet :
allprojects {
repositories {
maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
}
}
Ajoutez la dépendance du SDK au fichier build.gradle au niveau du module :
dependencies {
implementation 'com.aliyun.video.android:upload:2.0.1'
}
Le SDK OSS Android sous-jacent est inclus de manière transitive via la dépendance api de VODUpload. Vous n'avez pas besoin de le déclarer à nouveau.
Configuration du projet
Déclarez les autorisations requises dans le fichier 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+ granular media permissions, declare as needed -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
Si vous activez l'obfuscation du code, ajoutez les règles suivantes au fichier proguard-rules.pro :
-keep class com.alibaba.sdk.android.vod.upload.v2.** { *; }
-keep interface com.alibaba.sdk.android.vod.upload.v2.** { *; }
Le SDK OSS Android sous-jacent inclut des règles ProGuard intégrées. Vous n'avez pas besoin de les déclarer à nouveau.
Utilisation de base
Gestion des rappels
Le SDK de chargement (v2) utilise un rappel asynchrone unifié VODGetAuthCallback pour demander les identifiants de chargement à la couche métier. Le SDK invoque getAuth dans les scénarios suivants et utilise VODAuthContext.getKind() pour indiquer le type d'identifiant requis :
| Type | Déclencheur | Opération OpenAPI à appeler |
CREATE_VIDEO |
Premier chargement d'un fichier vidéo | CreateUploadVideo |
REFRESH_VIDEO |
Reprise du chargement / actualisation des identifiants | RefreshUploadVideo |
CREATE_IMAGE |
Chargement d'image | CreateUploadImage |
La couche métier doit simplement transmettre la réponse JSON brute provenant du backend OpenAPI au SDK telle quelle. Le SDK lit les clés suivantes en utilisant leurs noms de champs OpenAPI exacts (sensibles à la casse) :
| Type | Champs requis |
CREATE_VIDEO / REFRESH_VIDEO |
UploadAuth, UploadAddress, VideoId |
CREATE_IMAGE |
UploadAuth, UploadAddress, ImageId, ImageURL (transmis à result.getImageUrl()) |
Ne renommez pas les champs. Si vous renommez les champs en videoId, imageUrl ou image_url, le SDK les analysera comme étant null.
L'exemple suivant montre une implémentation de getAuth qui gère chaque type :
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;
}
};
Initialiser l'instance de chargement
Utilisez VODUploadConfig.Builder pour construire la configuration et appelez VODUploadClient.create(...) afin de créer une instance de chargement :
import com.alibaba.sdk.android.vod.upload.v2.*;
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth) // Required: authentication callback. For more information, see "Callback handling".
.build();
VODUploadClient uploader = VODUploadClient.create(context, config);
L'instance uploader est réutilisable. Vous pouvez utiliser la même instance pour charger plusieurs fichiers simultanément. Appelez uploader.dispose() pour libérer les ressources à la fin du cycle de vie.
Contrôle du chargement
Appelez upload(...) pour démarrer un chargement. La méthode renvoie un handle VODUploadTask que vous pouvez utiliser pour annuler le chargement :
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());
}
});
// Cancel the upload midway. Resumable upload is enabled by default. The next upload(...) call for the same file automatically resumes the upload.
task.cancel();
// task.getUploadTaskId() can be used to correlate logs or integrate with analytics.
upload(...) propose deux surcharges qui prennent en charge les chemins de fichiers et les URI content:// (compatibles avec le stockage étendu d'Android 10+) :
uploader.upload(String filePath, VODUploadOptions options, VODUploadResultCallback callback);
uploader.upload(Uri fileUri, VODUploadOptions options, VODUploadResultCallback callback);
Chargement d'image : Le SDK utilise automatiquement le chemin de chargement d'image en fonction de l'extension du nom de fichier (jpg / jpeg / png / gif / bmp / webp / heic) ou lorsque options.imageMeta != null. Dans le rappel de succès, result.getImageId() et result.getImageUrl() contiennent des valeurs valides :
VODImageMeta imgMeta = new VODImageMeta.Builder()
.setImageType("cover")
.setTitle("Cover")
.build();
uploader.upload("/sdcard/cover.jpg",
new VODUploadOptions.Builder().setImageMeta(imgMeta).build(),
callback);
Paramètres avancés
Accélération du chargement
Définissez VODVideoMeta.userData sur le JSON suivant. Le serveur VOD renvoie automatiquement l'endpoint d'accélération de transfert global OSS (oss-accelerate.aliyuncs.com) lors de l'émission de UploadAddress. Le SDK charge directement vers l'endpoint d'accélération :
VODVideoMeta meta = new VODVideoMeta.Builder()
.setTitle("My Video")
.setUserData("{\"Type\":\"oss\",\"Domain\":\"oss-accelerate.aliyuncs.com\"}")
.build();
L'accélération du chargement repose sur l'accélération de transfert global OSS. Vous devez activer l'accélération de transfert pour le bucket dans la console OSS. Pour plus d'informations, consultez Accéder à OSS à l'aide de l'accélération de transfert.
Chargement et transcodage
Spécifiez un groupe de modèles de transcodage ou un workflow via 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>") // transcoding template group
.setWorkflowId("<Your workflow ID>") // Workflow (optional)
.setAppId("<Optional: application ID>")
.build();
VODVideoMeta prend en charge les champs suivants : title / description / coverUrl / cateId / tags / userData / storageLocation / templateGroupId / workflowId / appId. Tous les champs sont facultatifs et sont transmis à CreateUploadVideo.
Une fois le chargement terminé, le serveur VOD transcode la vidéo source en fonction du groupe de modèles de transcodage. Si vous ne souhaitez pas déclencher le transcodage, transmettez un groupe de modèles « sans transcodage » dans l'appel CreateUploadVideo depuis votre backend.
Délai d'attente et nouvelle tentative
Configurez le délai d'attente et le nombre de nouvelles tentatives pour les requêtes OSS :
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setTimeout(60 * 1000) // Unit: milliseconds. Default: 60s
.setMaxRetryCount(2) // Default: 2
.build();
timeout contrôle le délai de connexion et de lecture/écriture pour une seule requête OSS (en millisecondes). maxRetryCount contrôle le nombre de nouvelles tentatives pour une requête OSS en cas d'exceptions réseau.
Version de signature
Spécifiez la version de signature OSS :
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setSignature("v4") // Default: "v4". Options: "v1"
.build();
La signature OSS V4 est la version recommandée. À partir du 1er septembre 2025, les buckets nouvellement créés doivent utiliser la signature V4. Il est également conseillé aux clients existants de migrer dès que possible. Définissez explicitement "v1" uniquement si votre bucket ne prend toujours en charge que la signature V1.
Chargement avec reprise
Par défaut, le chargement avec reprise est activé. Le SDK utilise le triplet (lastModified, fileName, fileSize) comme clé de reprise du chargement et le conserve automatiquement dans SharedPreferences.
| Scénario | Comportement du SDK |
task.cancel() est appelé pendant le chargement |
L'enregistrement de reprise du chargement est conservé. Le prochain appel upload(...) pour le même fichier reprendra automatiquement le chargement. |
| Plantage de l'application / arrêt du processus | L'enregistrement de reprise du chargement est conservé. Le prochain appel upload(...) après un redémarrage à froid pour le même fichier reprendra automatiquement le chargement. |
| Toute modification de l'empreinte du fichier | Le fichier est traité comme un nouveau fichier et chargé depuis le début. |
| Expiration de l'uploadId OSS | Le SDK efface automatiquement l'ancien enregistrement et lance un nouveau chargement via CREATE_VIDEO. |
Pour désactiver le chargement avec reprise :
new VODUploadConfig.Builder().setGetAuth(getAuth).setCheckpoint(false).build();
Chargement multipartie
Utilisez partSize pour contrôler la taille des parties et parallel pour contrôler le nombre de parties simultanées :
// Global configuration
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setPartSize(1024 * 1024) // Default: 1 MB
.setParallel(4) // Default: 4
.build();
// Override for a single task
VODUploadOptions options = new VODUploadOptions.Builder()
.setVideoMeta(meta)
.setPartSize(2 * 1024 * 1024)
.setParallel(6)
.build();
Définir la région du service VOD
Spécifiez la région du service ApsaraVideo VOD :
new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setRegion("cn-shanghai") // Default: cn-shanghai
.build();
Pour obtenir la liste des régions prises en charge, consultez ID de région ApsaraVideo VOD.
Rapport de données
Par défaut, le SDK active l'instrumentation du chemin de chargement pour la surveillance de la qualité du produit. Seules les métriques d'exécution du processus de chargement sont collectées. Le contenu des fichiers n'est pas collecté. Pour désactiver le rapport de données :
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setReportEnabled(false) // Default: true
.build();
Gestion des erreurs
VODUploadError étend java.lang.Exception. Les codes d'erreur suivent le format à trois segments UPLOAD.{LAYER}.{TYPE} :
| COUCHE | Code d'erreur | Description |
| AUTH | UPLOAD.AUTH.GET_AUTH_FAILED |
Échec du rappel getAuth. |
| AUTH | UPLOAD.AUTH.DECODE_FAILED |
Échec du décodage de UploadAuth. |
| AUTH | UPLOAD.AUTH.EXPIRED |
L'identifiant a expiré. |
| OSS | UPLOAD.OSS.ACCESS_DENIED |
Accès OSS refusé (problème d'autorisation ou de signature). |
| OSS | UPLOAD.OSS.NO_SUCH_BUCKET |
Le bucket n'existe pas. |
| OSS | UPLOAD.OSS.NO_SUCH_UPLOAD |
L'uploadId a expiré. Le SDK bascule automatiquement vers un nouveau chargement. |
| OSS | UPLOAD.OSS.UPLOAD_FAILED |
Échec du chargement OSS. |
| OSS | UPLOAD.OSS.MERGE_FAILED |
Échec de la fusion multipartie OSS. |
| NETWORK | UPLOAD.NETWORK.TIMEOUT |
Délai d'attente réseau dépassé. |
| NETWORK | UPLOAD.NETWORK.UNREACHABLE |
Réseau inaccessible. |
| FILE | UPLOAD.FILE.NOT_FOUND |
Le fichier n'existe pas. |
| FILE | UPLOAD.FILE.EMPTY |
Le fichier est vide. |
| CANCEL | UPLOAD.CANCEL.USER_CANCELLED |
Le chargement a été annulé par l'utilisateur. |
| INTERNAL | UPLOAD.INTERNAL.DISPOSED |
L'instance a été libérée. |
| INTERNAL | UPLOAD.INTERNAL.INVALID_CONFIG |
Configuration non valide. |
Méthodes publiques de VODUploadError :
String getErrorCode()— Renvoie le code d'erreur.String getErrorMessage()— Renvoie le message d'erreur.String getUploadTaskId()— Renvoie l'ID de la tâche de chargement.String getSuggestion()— Renvoie la suggestion de correction intégrée du SDK.Throwable getCause()— Renvoie l'exception OSS sous-jacente (héritée deException).
L'exemple suivant gère les erreurs en fonction du code d'erreur :
@Override public void onFailure(VODUploadError e) {
if (e.getErrorCode().startsWith("UPLOAD.AUTH.")) {
// Prompt the user to check backend authentication
} else if (VODUploadError.OSS_UPLOAD_FAILED.equals(e.getErrorCode())) {
// Retry or prompt the user to check the network
}
Log.e(TAG, e.getErrorCode() + ": " + e.getErrorMessage()
+ " (suggestion=" + e.getSuggestion() + ")", e.getCause());
}
FAQ
Puis-je lancer plusieurs chargements simultanément ?
Oui. Chaque task est indépendante. En tant que bonne pratique, contrôlez le nombre de chargements simultanés en fonction des conditions réseau afin d'éviter d'amplifier la pression sur la bande passante ascendante lorsqu'ils sont combinés avec parallel.
Le chargement avec reprise ne fonctionne pas après annulation et rechargement
Vérifiez les points suivants :
Vérifiez que le chemin du fichier est identique.
Vérifiez que les valeurs
lastModifiedetsizedu fichier n'ont pas changé.Vérifiez que
config.checkpointest défini surtrue.Vérifiez si l'uploadId a expiré. Lorsque la réponse est
NoSuchUpload, le SDK bascule automatiquement vers un nouveau chargement. Il s'agit d'un comportement attendu.
Quelles sont les valeurs de fileName et fileSize lors du chargement d'une URI content:// ?
Le SDK lit OpenableColumns.DISPLAY_NAME et OpenableColumns.SIZE via ContentResolver.query(...). Si la taille ne peut pas être lue, UPLOAD.FILE.EMPTY est renvoyé.
Que renvoie getCause() ?
La valeur de retour hérite de Exception et conserve l'objet OSS sous-jacent ServerException, ClientException ou IOException, ce qui vous aide à effectuer un dépannage approfondi.