Tous les produits
Search
Centre de documentation

ApsaraVideo VOD:Téléversement de fichiers à l’aide du SDK JavaScript

Dernière mise à jour :Aug 10, 2026

Le SDK JavaScript ApsaraVideo VOD (aliyun-vod-upload-sdk) permet de téléverser des vidéos et des images depuis un navigateur vers le stockage ApsaraVideo VOD. Le SDK gère la récupération des identifiants, le téléversement en plusieurs parties, la reprise après interruption et le suivi de la progression.

Prérequis navigateurs

Navigateur Version minimale
Chrome 60+
Microsoft Edge 79+ (Chromium)
Firefox 55+
Safari 11+
Navigateur par défaut Android 60+
Navigateur par défaut iOS 11+

Démarrage rapide

Téléchargez le code source de démonstration pour obtenir un exemple fonctionnel complet.

Installation

Installez le SDK avec npm :

npm install aliyun-vod-upload-sdk

Le SDK propose des versions ESM, CJS et UMD, et prend en charge tous les bundlers modernes (Vite, webpack, Rollup et esbuild).

Importation via CDN

Pour utiliser le SDK sans bundler, importez-le depuis un CDN :

<script src="https://g.alicdn.com/apsara-media-box/imp-web-vod-upload/2.0.0/vod-upload.umd.js"></script>
<script>
  const { createUploader, UploadError } = window.VodUpload;
</script>

Prérequis API backend

Le SDK n’appelle pas directement les OpenAPI Alibaba Cloud. Il délègue cette tâche à votre backend via le rappel getAuth afin d’obtenir les identifiants de téléversement. Votre backend doit implémenter les API suivantes, qui correspondent aux opérations OpenAPI VOD :

API backend Opération OpenAPI correspondante Champs de réponse
Création d’identifiants pour le téléversement vidéo CreateUploadVideo { UploadAuth, UploadAddress, VideoId }
Actualisation des identifiants pour le téléversement vidéo RefreshUploadVideo { UploadAuth, UploadAddress, VideoId }
Création d’identifiants pour le téléversement d’image CreateUploadImage { UploadAuth, UploadAddress, ImageId }

La réponse JSON du backend est transmise telle quelle au SDK. Ce dernier gère automatiquement le décodage base64 et le mappage des champs.

Téléversement d’un fichier en cinq lignes de code

L’exemple suivant illustre le code minimal nécessaire pour téléverser un fichier :

import { createUploader } from 'aliyun-vod-upload-sdk';

const uploader = createUploader({
  getAuth: () => fetch('/api/vod/auth').then(r => r.json()),
});

// file is a File object, for example from an <input type="file"> element
const { videoId } = await uploader.upload(file);

Fonctionnalités de base

Téléversement de vidéos

L’exemple ci-dessous crée un téléverseur avec un rappel getAuth qui gère à la fois la création initiale des identifiants et leur actualisation :

import { createUploader } from 'aliyun-vod-upload-sdk';

const uploader = createUploader({
  getAuth: async (ctx) => {
    switch (ctx.kind) {
      case 'create-video':
        return fetch('/api/vod/create-auth', {
          method: 'POST',
          body: JSON.stringify({ fileName: ctx.file.name, ...ctx.meta }),
        }).then(r => r.json());
      case 'refresh-video':
        return fetch(`/api/vod/refresh-auth?videoId=${ctx.videoId}`)
          .then(r => r.json());
    }
  },
});

const result = await uploader.upload(file, {
  meta: { title: 'My Video', cateId: 1000, tags: 'tutorial,example' },
});
console.log('Upload successful, videoId:', result.videoId);

Le rappel getAuth reçoit un paramètre ctx. Le SDK détermine automatiquement la valeur de ctx.kind selon le scénario :

  • **create-video** — Premier téléversement. Le backend doit appeler CreateUploadVideo.

  • **refresh-video** — Actualisation des identifiants lors d’une reprise après interruption. Le backend doit appeler RefreshUploadVideo.

  • **create-image** — Téléversement d’image. Le backend doit appeler CreateUploadImage.

Téléversement d’images

Le téléversement d’images utilise la même méthode upload(). Le SDK détecte automatiquement le type de fichier en se basant sur file.type (les types image/* utilisent le chemin de téléversement dédié aux images) :

const uploader = createUploader({
  getAuth: async (ctx) => {
    if (ctx.kind === 'create-image') {
      return fetch('/api/vod/image-auth', {
        method: 'POST',
        body: JSON.stringify({ imageType: 'default' }),
      }).then(r => r.json());
    }
  },
});

const result = await uploader.upload(imageFile);
console.log('Image upload successful, imageId:', result.imageId);

Suivi de la progression du téléversement

Utilisez le rappel onProgress pour suivre la progression du téléversement :

const result = await uploader.upload(file, {
  onProgress: (percent, loaded, total) => {
    // percent: 0..1 (e.g. 0.5 means 50%)
    // loaded:  bytes uploaded
    // total:   total file size in bytes
    progressBar.value = percent;
    console.log(`${(percent * 100).toFixed(1)}% - ${loaded} / ${total}`);
  },
});

Le SDK garantit que percent est égal à 1 lorsque le téléversement est terminé.

Annulation d’un téléversement

Annulez un téléversement soit via la méthode task.abort(), soit à l’aide d’un AbortSignal.

  • Méthode 1 : task.abort() — Approche la plus simple

const task = uploader.upload(file);

cancelBtn.onclick = () => task.abort();

try {
  const result = await task;
} catch (e) {
  if (e.name === 'AbortError') {
    console.log('Upload canceled by user');
  }
}
  • Méthode 2 : AbortSignal — Adaptée aux cycles de vie des composants React/Vue

const ctrl = new AbortController();
cancelBtn.onclick = () => ctrl.abort();

try {
  const result = await uploader.upload(file, { signal: ctrl.signal });
} catch (e) {
  if (e.name === 'AbortError') {
    console.log('Upload canceled');
  }
}

Après l’annulation, le point de contrôle est conservé. Le prochain appel à upload(file) reprendra automatiquement le téléversement à partir du point d’interruption.

Reprise après interruption

La reprise après interruption est activée par défaut et ne nécessite aucune configuration supplémentaire. Cette fonctionnalité est prise en charge uniquement pour les téléversements vidéo. Les téléversements d’images n’utilisent pas la reprise après interruption. Le SDK effectue automatiquement les actions suivantes :

  • Stocke la progression des parties terminées dans localStorage.

  • Reprend le téléversement là où il a été interrompu lorsque upload(file) est appelé de nouveau après un rafraîchissement de la page.

  • Associe les points de contrôle selon la règle : même file.name + file.size + file.lastModified.

// First upload (user closes the page at 40% progress)
await uploader.upload(file);

// User reopens the page and uploads the same file again
// The SDK automatically resumes from 40% without re-uploading
const result = await uploader.upload(file);

Pour désactiver la reprise après interruption :

const uploader = createUploader({
  getAuth: myGetAuth,
  checkpoint: false,  // Disable resumable upload
});

Fonctionnalités avancées

Téléversement par lot

Le SDK fournit une API upload() pour un fichier unique. Pour les téléversements par lot, utilisez les primitives asynchrones JavaScript standard.

Téléversement séquentiel (le plus simple)

for (const file of files) {
  const result = await uploader.upload(file, {
    onProgress: p => updateProgress(file.name, p),
  });
  console.log(`${file.name} complete, videoId: ${result.videoId}`);
}

Téléversement concurrent (bande passante élevée et fichiers de petite taille)

const results = await Promise.all(
  files.map(f => uploader.upload(f)),
);

(Recommandé) Téléversement avec limitation de la concurrence (fichiers volumineux)

import pLimit from 'p-limit';

const limit = pLimit(2); // Upload at most 2 files simultaneously
const results = await Promise.all(
  files.map(f => limit(() => uploader.upload(f, {
    onProgress: p => updateItemProgress(f, p),
  }))),
);

Mise en pause et reprise

Le SDK ne dispose pas d’une API explicite de mise en pause. Obtenez cet effet en combinant annulation et reprise :

// Pause: cancel the current upload
task.abort();

// Resume: re-upload the same file, automatically resumes from checkpoint
const result = await uploader.upload(file);

Délai d’expiration et annulation multi-sources

Utilisez AbortSignal.timeout() et AbortSignal.any() pour mettre en œuvre une annulation basée sur un délai d’expiration ou combinée :

// Auto-cancel after 60 seconds
await uploader.upload(file, {
  signal: AbortSignal.timeout(60_000),
});

// Multi-source cancellation: user manual cancel OR 60-second timeout
const userCtrl = new AbortController();
await uploader.upload(file, {
  signal: AbortSignal.any([
    userCtrl.signal,
    AbortSignal.timeout(60_000),
  ]),
});

Intégration avec React et Vue

React

Exemple de Hook React

import { useEffect, useState, useRef } from 'react';
import { createUploader, UploadError } from 'aliyun-vod-upload-sdk';

function useUploader(getAuth) {
  const uploaderRef = useRef(createUploader({ getAuth }));

  useEffect(() => {
    return () => uploaderRef.current.dispose(); // Release on unmount
  }, []);

  return uploaderRef.current;
}

function UploadButton({ file }) {
  const uploader = useUploader(myGetAuth);
  const [progress, setProgress] = useState(0);

  const handleUpload = () => {
    const ctrl = new AbortController();

    uploader.upload(file, {
      signal: ctrl.signal,
      onProgress: p => setProgress(p),
    }).then(result => {
      console.log('Success', result.videoId);
    }).catch(e => {
      if (e.name !== 'AbortError') {
        console.error('Failed', e);
      }
    });
  };

  return <button onClick={handleUpload}>Upload ({(progress * 100).toFixed(0)}%)</button>;
}

Vue 3

Exemple de Composable Vue 3

import { onUnmounted, ref } from 'vue';
import { createUploader } from 'aliyun-vod-upload-sdk';

export function useUploader(getAuth) {
  const uploader = createUploader({ getAuth });
  const progress = ref(0);

  onUnmounted(() => uploader.dispose());

  async function upload(file) {
    return uploader.upload(file, {
      onProgress: p => { progress.value = p; },
    });
  }

  return { upload, progress };
}

Référence de l’API

createUploader(config)

Crée une instance Uploader.

import { createUploader } from 'aliyun-vod-upload-sdk';

const uploader = createUploader(config);

UploaderConfig

Paramètre Type Obligatoire Par défaut Description
getAuth GetAuth Oui — Rappel de récupération des identifiants. Pour plus d’informations, consultez le rappel getAuth.
retry RetryPolicy Non { count: 3 } Politique de nouvelle tentative automatique en cas d’échec du téléversement en plusieurs parties OSS.
checkpoint false \ { store?: CheckpointStore } Non localStorage

Configuration de la reprise après interruption. Définissez sur false pour désactiver. Définissez sur { store } pour injecter un magasin personnalisé.

parallel number Non 4 Nombre de parties OSS concurrentes.
partSize number Non 1048576 (1 Mo) Taille des parties OSS en octets.
timeout number Non 60000 Délai d’expiration des requêtes réseau en millisecondes.
cname string Non — Nom de domaine OSS personnalisé.
refreshSTSTokenInterval number Non 300000 (5 min) Intervalle de vérification de l’actualisation des identifiants STS en millisecondes.

RetryPolicy

Champ Type Par défaut Description
count number 3 Nombre maximal de nouvelles tentatives.

uploader.upload(file, options?)

Téléverse un fichier unique. Renvoie une UploadTask, qui est à la fois une Promise<UploadResult> et un objet disposant d’une méthode .abort().

const task = uploader.upload(file, options);

UploadOptions

Paramètre Type Description
meta VodVideoMeta \ VodImageMeta

Métadonnées multimédias (titre, catégorie, tags, etc.).

signal AbortSignal Signal d’annulation standard Web.
onProgress (percent, loaded, total) => void Rappel de progression. La valeur percent varie de 0 à 1.
partSize number Remplace la valeur globale partSize.
parallel number Remplace la valeur globale parallel.

VodVideoMeta (métadonnées vidéo)

Champ Type Description
title string Titre de la vidéo.
description string Description de la vidéo.
cateId number ID de catégorie.
tags string Tags, séparés par des virgules.
templateGroupId string ID du groupe de modèles de transcodage.
storageLocation string Adresse de stockage.
coverUrl string URL de l’image de couverture.
workflowId string ID du workflow.
appId string ID de l’application.
userData Record Données personnalisées.

VodImageMeta (métadonnées image)

Champ Type Description
title string Titre de l’image.
description string Description de l’image.
imageType 'default' \ 'cover' \

'watermark'

Type d’image.

imageExt string Extension du fichier image.
tags string Tags.
cateId number ID de catégorie.
storageLocation string Adresse de stockage.

UploadResult

Champ Type Description
videoId string? ID vidéo. Renvoyé pour les téléversements vidéo.
imageId string? ID image. Renvoyé pour les téléversements d’images.
etag string ETag OSS.
requestId string ID de requête OSS.
durationMs number Durée du téléversement en millisecondes.
uploadTaskId string ID unique de la tâche de téléversement. Peut être utilisé pour le dépannage avec le support technique.

UploadTask

L’objet renvoyé par upload() est à la fois une Promise<UploadResult> et un objet disposant d’une méthode .abort().

type UploadTask = Promise<UploadResult> & {
  abort(): void;
};

La méthode .abort() est perdue après chaînage. task.then(fn) renvoie une Promise standard. Pour conserver la capacité d’annulation après chaînage, utilisez options.signal.

uploader.dispose()

Libère les ressources : annule tous les téléversements en cours et efface l’état interne.

uploader.dispose();

Après cet appel, l’instance uploader ne peut plus être réutilisée. Appelez cette méthode lors du démontage d’un composant React ou Vue pour éviter les fuites de mémoire.

Rappel getAuth

type GetAuth = (ctx: AuthContext) => Promise<AuthResult>;

AuthContext

Le SDK transmet différentes valeurs de ctx selon le scénario de téléversement :

ctx.kind Scénario déclencheur Champs ctx supplémentaires
'create-video' Premier téléversement vidéo file, meta?
'refresh-video' Actualisation des identifiants lors d’une reprise après interruption file, videoId
'create-image' Téléversement d’image file, meta?

AuthResult

JSON brut renvoyé par le backend à partir de la réponse OpenAPI. Le SDK le décode automatiquement :

Champ Type Obligatoire Description
UploadAuth string Oui Identifiants STS encodés en base64.
UploadAddress string Oui Adresse de téléversement OSS encodée en base64.
VideoId string Obligatoire pour create-video ID vidéo.
ImageId string Obligatoire pour create-image ID image.
ImageURL string Non URL de l’image (transmise telle quelle).

Implémentation getAuth la plus simple :

// Unified backend route
createUploader({
  getAuth: ctx => fetch('/api/vod/auth', {
    method: 'POST',
    body: JSON.stringify(ctx),
  }).then(r => r.json()),
});

Secours automatique en cas d’échec de refresh-video : Lorsque l’actualisation des identifiants lors d’une reprise après interruption échoue, le SDK bascule automatiquement vers create-video pour retéléverser le fichier. Ce processus est totalement transparent pour l’appelant.

Gestion des erreurs

Structure UploadError

Toutes les erreurs de téléversement sont des instances de UploadError (qui étend Error) :

import { UploadError } from 'aliyun-vod-upload-sdk';

class UploadError extends Error {
  readonly code: string;           // Structured error code, e.g. 'UPLOAD.OSS.ACCESS_DENIED'
  readonly message: string;        // Error description
  readonly suggestion: string;     // Fix suggestion
  readonly cause?: unknown;        // Original underlying error
  readonly uploadTaskId?: string;  // Upload task ID (for troubleshooting)
}

L’annulation d’un téléversement initiée par l’utilisateur n’est pas une UploadError. Il s’agit d’une DOMException standard (name === 'AbortError').

Codes d’erreur

Format du code d’erreur : UPLOAD.{layer}.{type}

Code d’erreur Description Correction suggérée
UPLOAD.AUTH.GET_AUTH_FAILED Le rappel getAuth a levé une erreur ou renvoyé une structure invalide. Vérifiez si le rappel getAuth renvoie correctement un JSON contenant les champs UploadAuth et UploadAddress. Assurez-vous que le service backend est disponible et que le format de la réponse est correct.
UPLOAD.OSS.ACCESS_DENIED Erreur d’autorisation OSS (403). Vérifiez si les identifiants de téléversement (jeton STS) sont valides et n’ont pas expiré, et si la stratégie RAM accorde les autorisations d’écriture OSS.
UPLOAD.OSS.NO_SUCH_BUCKET Le bucket n’existe pas. Vérifiez si le nom du bucket dans l’adresse de téléversement est correct et assurez-vous que le bucket a bien été créé dans la région correspondante.
UPLOAD.OSS.NO_SUCH_UPLOAD La session de téléversement en plusieurs parties a expiré. La session de téléversement en plusieurs parties a expiré (éventuellement après plus de 24 heures). Le SDK retéléverse automatiquement le fichier. Aucune action manuelle n’est requise.
UPLOAD.OSS.UNKNOWN Erreur OSS inconnue. Consultez la console du navigateur pour obtenir des détails sur l’erreur ou contactez le support technique.
UPLOAD.NETWORK.TIMEOUT La requête a expiré. Ouvrez le panneau Network dans les outils de développement du navigateur pour afficher les détails de la requête ayant échoué. Vérifiez si la connexion réseau est stable ou essayez d’augmenter la valeur du délai d’expiration.
UPLOAD.NETWORK.ERROR Erreur de connexion réseau. Ouvrez le panneau Network dans les outils de développement du navigateur pour afficher le code d’état et la réponse de la requête ayant échoué. Assurez-vous que le navigateur peut accéder à l’adresse du service OSS. Vérifiez si un proxy ou un pare-feu bloque la requête.
UPLOAD.NETWORK.OFFLINE Le navigateur est hors ligne. Vérifiez l’état du réseau et retentez le téléversement après reconnexion.
UPLOAD.FILE.EMPTY La taille du fichier est de 0. La taille du fichier est de 0. Les fichiers vides ne peuvent pas être téléversés. Vérifiez si le fichier sélectionné est correct.
UPLOAD.INTERNAL.DISPOSED L’instance Uploader a été libérée. Appelez de nouveau createUploader() pour créer une nouvelle instance.

Utilisation des constantes de code d’erreur

(Il est recommandé) d’utiliser les constantes ErrorCode plutôt que des littéraux de chaîne :

import { ErrorCode, UploadError } from 'aliyun-vod-upload-sdk';

try {
  await uploader.upload(file);
} catch (e) {
  if (e instanceof UploadError) {
    switch (e.code) {
      case ErrorCode.AUTH_GET_AUTH_FAILED:
        showToast('Failed to obtain credentials. Refresh the page and try again.');
        break;
      case ErrorCode.NETWORK_TIMEOUT:
      case ErrorCode.NETWORK_ERROR:
        showToast('Network error. Check your network and try again.');
        break;
      case ErrorCode.OSS_ACCESS_DENIED:
        showToast('Insufficient upload permissions. Contact the administrator.');
        break;
      default:
        showToast(`Upload failed: ${e.suggestion || e.message}`);
    }
  }
}

Dépannage

Chaque UploadError contient un uploadTaskId, qui constitue un ID de trace global pour l’ensemble du téléversement. Vous pouvez fournir cet ID au support technique Alibaba Cloud pour identifier rapidement le problème :

catch (e) {
  if (e instanceof UploadError) {
    // Send to your technical support team
    const diagnostic = {
      code: e.code,
      message: e.message,
      uploadTaskId: e.uploadTaskId,
      suggestion: e.suggestion,
    };
    reportToSupport(diagnostic);
  }
}

Le champ UploadResult.uploadTaskId peut également être utilisé pour corréler les journaux après un téléversement réussi :

const result = await uploader.upload(file);
myLogger.info('Upload successful', { videoId: result.videoId, uploadTaskId: result.uploadTaskId });