Importations avec reprise

Vous pouvez importer des vidéos de manière plus fiable à l'aide du protocole d'importation avec reprise pour les API Google. Ce protocole vous permet de reprendre une opération d'importation après une interruption du réseau ou un autre échec de transmission, ce qui permet de gagner du temps et d'économiser de la bande passante en cas de défaillance du réseau.

Les importations avec reprise sont particulièrement utiles dans les cas suivants:

  • Vous transférez des fichiers volumineux.
  • La probabilité que le réseau soit interrompu est élevée.
  • Les importations proviennent d'un appareil disposant d'une connexion Internet à faible bande passante ou instable (par exemple, un appareil mobile).

Ce guide explique la séquence de requêtes HTTP qu'une application effectue pour importer des vidéos à l'aide d'un processus d'importation avec reprise. Ce guide est principalement destiné aux développeurs qui ne peuvent pas utiliser les bibliothèques clientes des API Google, dont certaines fournissent une compatibilité native avec les importations avec reprise. Le guide API YouTube Data – Mise en ligne d'une vidéo explique comment utiliser la bibliothèque cliente des API Google pour Python afin de mettre en ligne une vidéo à l'aide d'un processus de mise en ligne "réactivable".

Remarque : Vous pouvez également consulter la série de requêtes effectuées pour l'importation avec reprise ou toute autre opération de l'API en utilisant l'une des bibliothèques clientes des API Google avec la journalisation HTTPS activée. Par exemple, pour activer la trace HTTP pour Python, utilisez la bibliothèque httplib2:

httplib2.debuglevel = 4

Étape 1 : Démarrez une session avec reprise

Pour démarrer l'importation d'une vidéo avec reprise, envoyez une requête POST à l'URL suivante. Dans l'URL, définissez la valeur du paramètre part sur la valeur appropriée pour votre requête. Rappelez-vous que la valeur du paramètre identifie les parties des propriétés de conteneur que vous définissez, ainsi que les parties que la réponse de l'API doit inclure. Les valeurs des paramètres dans l'URL de la requête doivent être encodées en URL.

https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=PARTS

Définissez le corps de la requête sur une ressource video. Définissez également les en-têtes de requête HTTP suivants:

  • Authorization : jeton d'autorisation de la requête.
  • Content-Length : nombre d'octets fournis dans le corps de la requête. Notez que vous n'avez pas besoin de fournir cet en-tête si vous utilisez l'encodage de transfert fragmenté.
  • Content-Type : définissez la valeur sur application/json; charset=UTF-8.
  • X-Upload-Content-Length : nombre d'octets qui seront importés dans les requêtes ultérieures. Définissez cette valeur sur la taille du fichier que vous importez.
  • x-upload-content-type : type MIME du fichier que vous importez. Vous pouvez importer des fichiers au format MIME de type vidéo (video/*) ou MIME de type application/octet-stream.

L'exemple suivant montre comment lancer une session avec reprise pour importer une vidéo. La requête définit (et récupère les propriétés) des parties snippet et status de la ressource video, et récupère également les propriétés dans la partie contentdetails de la ressource.

post /upload/youtube/v3/videos?uploadType=resumable&part=parts http/1.1
host: www.googleapis.com
authorization: bearer auth_token
content-length: content_length
content-type: application/json; charset=utf-8
x-upload-content-length: x_upload_content_length
X-Upload-Content-Type: X_UPLOAD_CONTENT_TYPE

video resource

L'exemple suivant montre une requête POST dans laquelle toutes ces valeurs sont renseignées, à l'exception du jeton d'authentification. Dans cet exemple, la valeur categoryId correspond à une catégorie de vidéos. Vous pouvez récupérer la liste des catégories acceptées en utilisant la méthode videoCategories.list de l'API.

POST /upload/youtube/v3/videos?uploadType=resumable&part=snippet,status,contentDetails HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer AUTH_TOKEN
Content-Length: 278
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Length: 3000000
X-Upload-Content-Type: video/*

{
  "snippet": {
    "title": "My video title",
    "description": "This is a description of my video",
    "tags": ["cool", "video", "more keywords"],
    "categoryId": 22
  },
  "status": {
    "privacyStatus": "public",
    "embeddable": True,
    "license": "youtube"
  }
}

Étape 2 : Enregistrez l'URI de la session avec reprise

Si votre requête aboutit, le serveur d'API répond avec un code d'état HTTP 200 (OK) et la réponse inclut un en-tête HTTP Location qui spécifie l'URI de la session avec reprise. Il s'agit de l'URI que vous utiliserez pour importer votre fichier vidéo.

L'exemple ci-dessous présente un exemple de réponse de l'API à la requête de l'étape 1:

HTTP/1.1 200 OK
Location: https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&upload_id=xa298sd_f&part=snippet,status,contentDetails
Content-Length: 0

Étape 3 : Importez le fichier vidéo

Après avoir extrait l'URI de session de la réponse de l'API, vous devez importer le contenu réel du fichier vidéo à cet emplacement. Le corps de la requête correspond au contenu du fichier binaire de la vidéo que vous mettez en ligne. L'exemple ci-dessous présente le format de la requête.

PUT UPLOAD_URL HTTP/1.1
Authorization: Bearer AUTH_TOKEN
Content-Length: CONTENT_LENGTH
Content-Type: CONTENT_TYPE

BINARY_FILE_DATA

La requête définit les en-têtes de requête HTTP suivants:

  • Authorization : jeton d'autorisation de la requête.
  • Content-Length : taille du fichier que vous importez. Cette valeur doit être identique à celle de l'en-tête de requête HTTP X-Upload-Content-Length à l'étape 1.
  • Content-Type : type MIME du fichier que vous importez. Cette valeur doit être identique à celle de l'en-tête de requête HTTP X-Upload-Content-Type à l'étape 1.

Étape 4 : Finalisez la mise en ligne

Votre demande entraînera l'un des scénarios suivants:

  • L'importation a bien été effectuée.

    Le serveur d'API répond avec un code de réponse HTTP 201 (Created). Le corps de la réponse est la ressource video que vous avez créée.

  • Votre importation a échoué, mais elle peut reprendre.

    Vous devriez pouvoir reprendre une importation dans les cas suivants:

    • Votre requête est interrompue, car la connexion entre votre application et le serveur d'API est perdue. Dans ce cas, vous ne recevrez pas de réponse de l'API.

    • La réponse de l'API spécifie l'un des codes de réponse 5xx suivants. Votre code doit utiliser un intervalle exponentiel entre les tentatives pour reprendre les importations après avoir reçu l'un de ces codes de réponse.

      • 500 – Internal Server Error
      • 502 – Bad Gateway
      • 503 – Service Unavailable
      • 504 – Gateway Timeout

    Pour reprendre une importation, suivez les instructions pour vérifier l'état de l'importation et reprendre une importation ci-dessous. N'oubliez pas que chaque URI de session avec reprise a une durée de vie limitée et finit par expirer. C'est pourquoi nous vous recommandons de démarrer une importation avec reprise dès que vous obtenez l'URI de la session et de reprendre une importation interrompue peu de temps après.

  • Échec de l'importation.

    En cas d'échec de l'importation, la réponse contient une réponse d'erreur qui permet d'expliquer la cause de l'échec. Pour une importation qui échoue définitivement, la réponse de l'API affichera un code de réponse 4xx ou 5xx autre que ceux répertoriés ci-dessus.

    Si vous envoyez une requête avec un URI de session arrivé à expiration, le serveur renvoie un code de réponse HTTP 404 (Not Found). Dans ce cas, vous devrez lancer une nouvelle importation avec reprise, obtenir un nouvel URI de session et reprendre l'importation depuis le début à l'aide du nouvel URI.

Étape 4.1: Vérifier l'état d'une importation

Pour vérifier l'état d'une importation avec reprise interrompue, envoyez une requête PUT vide à l'URL d'importation que vous avez récupérée à l'étape 2 et également utilisée à l'étape 3. Dans votre requête, définissez la valeur de l'en-tête Content-Range sur bytes */CONTENT_LENGTH, où CONTENT_LENGTH est la taille du fichier que vous importez.

PUT UPLOAD_URL HTTP/1.1
Authorization: Bearer AUTH_TOKEN
Content-Length: 0
Content-Range: bytes */CONTENT_LENGTH

Étape 4.2: Traiter la réponse de l'API

Si l'importation est déjà terminée, qu'elle ait réussi ou non, l'API renvoie la même réponse qu'au moment de l'importation.

Cependant, si l'importation a été interrompue ou est en cours, la réponse de l'API affichera un code de réponse HTTP 308 (Resume Incomplete). Dans la réponse, l'en-tête Range indique le nombre d'octets déjà importés dans le fichier.

  • La valeur d'en-tête est indexée depuis 0. Ainsi, la valeur d'en-tête 0-999999 indique que les 1,000,000 premiers octets du fichier ont été importés.
  • Si rien n'a encore été importé, la réponse de l'API n'inclura pas l'en-tête Range.

L'exemple de réponse ci-dessous présente le format d'une réponse d'API pour une importation avec reprise:

308 Resume Incomplete
Content-Length: 0
Range: bytes=0-999999

Si la réponse de l'API inclut également l'en-tête Retry-After, utilisez la valeur de cet en-tête pour déterminer quand tenter de reprendre l'importation.

Étape 4.3: Reprendre l'importation

Pour reprendre l'importation, envoyez une autre requête PUT à l'URL d'importation capturée à l'étape 2. Définissez le corps de la requête sur le code binaire de la partie du fichier vidéo qui n'a pas encore été mise en ligne.

PUT UPLOAD_URL HTTP/1.1
Authorization: Bearer AUTH_TOKEN
Content-Length: REMAINING_CONTENT_LENGTH
Content-Range: bytes FIRST_BYTE-LAST_BYTE/TOTAL_CONTENT_LENGTH

PARTIAL_BINARY_FILE_DATA

Vous devez définir les en-têtes de requête HTTP suivants:

  • Authorization : jeton d'autorisation de la requête.

  • Content-Length : taille, en octets, du contenu qui n'a pas encore été importé. Si vous importez le reste d'un fichier, vous pouvez calculer cette valeur en soustrayant la valeur FIRST_BYTE de la valeur TOTAL_CONTENT_LENGTH. Ces deux valeurs sont utilisées dans l'en-tête Content-Range.

  • Content-Range : partie du fichier que vous importez. La valeur de l'en-tête comprend trois valeurs:

    • FIRST_BYTE : index numérique basé sur 0 du nombre d'octets à partir duquel vous relancez l'importation. Cette valeur est un chiffre supérieur au second de l'en-tête Range récupéré à l'étape précédente. Dans l'exemple précédent, la valeur de l'en-tête Range était 0-999999. Par conséquent, le premier octet d'une importation réactivée suivante serait 1000000.

    • LAST_BYTE : index numérique (0) du dernier octet du fichier binaire que vous importez. En général, il s'agit du dernier octet du fichier. Ainsi, par exemple, si la taille du fichier est de 3000000 octets, le dernier octet du fichier serait 2999999.

    • TOTAL_CONTENT_LENGTH : taille totale du fichier vidéo en octets. Cette valeur est identique à l'en-tête Content-Length spécifié dans la requête d'importation d'origine.

    Remarque : Vous ne pouvez pas importer un bloc non continu du fichier binaire. Si vous essayez d'importer un bloc non continu, aucun contenu binaire restant ne sera importé.

    Par conséquent, le premier octet mis en ligne doit être le suivant après le dernier octet déjà mis en ligne sur YouTube. (Consultez la discussion sur l'en-tête Range à l'étape 4.2.)

    Par conséquent, si le dernier octet de l'en-tête Range est 999999, le premier octet de la requête pour reprendre l'importation doit être de 1 000 000. (Les deux chiffres utilisent un index de base 0.) Si vous essayez de reprendre l'importation à partir de l'octet 999 999 ou inférieur (octets superposés) ou d'octets 1000001 ou supérieurs (octets ignorés), aucun contenu binaire ne sera importé.

Importer un fichier par fragments

Au lieu d'essayer d'importer un fichier entier et de reprendre l'importation en cas d'interruption du réseau, votre application peut diviser le fichier en fragments et envoyer une série de requêtes pour importer les fragments dans l'ordre. Cette approche est rarement nécessaire et est en réalité déconseillée, car elle nécessite des requêtes supplémentaires, qui ont des conséquences sur les performances. Toutefois, cela peut être utile si vous essayez d'afficher un indicateur de progression sur un réseau très instable.

Les instructions pour importer un fichier par fragments sont presque identiques aux quatre étapes expliquées précédemment dans ce guide. Toutefois, les requêtes de début d'importation d'un fichier (étape 3 ci-dessus) et de reprise d'une importation (étape 4.3 ci-dessus) définissent toutes deux les valeurs d'en-tête Content-Length et Content-Range lorsqu'un fichier est importé en fragments.

  • La valeur de l'en-tête Content-Length spécifie la taille du fragment que la requête envoie. Notez les restrictions suivantes concernant les tailles de fragments:

    • La taille des fragments doit être un multiple de 256 Ko. (Cette restriction ne s'applique pas au dernier fragment, car la taille du fichier entier ne peut pas être un multiple de 256 Ko.) N'oubliez pas que les segments plus volumineux sont plus efficaces.

    • La taille des fragments doit être identique pour chaque requête de la séquence d'importation, à l'exception de la dernière requête, qui spécifie la taille du fragment final.

  • L'en-tête Content-Range spécifie les octets du fichier que la requête importe. Les instructions permettant de définir l'en-tête Content-Range à l'étape 4.3 s'appliquent lorsque vous définissez cette valeur.

    Par exemple, la valeur bytes 0-524287/2000000 indique que la requête envoie les 524 288 premiers octets (256 x 2 048) dans un fichier de 2 000 000 octets.

L'exemple ci-dessous montre le format de la première série de requêtes qui importeront un fichier de 2 000 000 octets en fragments:

PUT UPLOAD_URL HTTP/1.1
Authorization: Bearer AUTH_TOKEN
Content-Length: 524888
Content-Type: video/*
Content-Range: bytes 0-524287/2000000

{bytes 0-524287}

Si une requête autre que la requête finale aboutit, le serveur d'API renvoie une réponse 308 (Resume Incomplete). Le format de réponse sera le même que celui décrit dans l'étape 4.2: Traiter la réponse de l'API ci-dessus.

Utilisez la valeur supérieure affichée dans l'en-tête Range de la réponse de l'API pour déterminer où démarrer le prochain fragment. Continuez à envoyer des requêtes PUT, comme décrit à l'étape 4.3: Reprendre l'importation, pour importer les fragments de fichier suivants jusqu'à ce que l'intégralité du fichier ait été importée.

Une fois l'intégralité du fichier importée, le serveur envoie un code de réponse HTTP 201 (Created) et renvoie les parties demandées de la ressource vidéo créée.

Si une requête est interrompue ou si votre application reçoit un code de réponse 5xx, suivez la procédure expliquée à l'étape 4 pour terminer l'importation. Toutefois, au lieu d'essayer d'importer le reste du fichier, il vous suffit d'importer des fragments à partir du point où vous reprenez l'importation. Pensez à vérifier l'état de l'importation pour déterminer où reprendre le transfert. Ne partez pas du principe que le serveur a reçu la totalité ou une partie des octets envoyés dans la requête précédente.

Remarque : Vous pouvez également demander l'état d'une importation active entre des fragments importés. L'importation ne doit pas nécessairement avoir été interrompue pour que vous puissiez récupérer son état.