Google API の再開可能なアップロードのプロトコルを使用すると、より確実に動画をアップロードできます。このプロトコルを使用すると、ネットワークの切断あるいはその他の転送の失敗が生じると、ネットワーク障害の場合には時間と帯域幅を節約しながら、アップロード操作を再開します。
再開可能アップロードが特に有効なケースは次のとおりです。
- 大きなファイルを転送する場合。
- ネットワーク中断の可能性が高い場合。
- 携帯端末などの低帯域幅な端末、またはインターネット接続が不安定な端末からアップロードする場合。
このガイドでは、再開可能アップロード プロセスを使用して動画をアップロードするためにアプリケーションが作成する一連の HTTP リクエストについて説明します。Google APIs Client Library では一部で再開可能アップロードのネイティブ サポートを提供していますが、このガイドは主にライブラリを利用できないデベロッパーを対象としています。事実上、YouTube Data API - 動画のアップロードのガイドでは、Python 用 Google API クライアント ライブラリを使用して、再開可能なアップロードのプロセスで動画をアップロードする方法を説明しています。
注: HTTP ロギングを有効化して Google API Client Library を使用することで、再開可能アップロードなどの API 操作のために作成された一連のリクエストを確認できます。たとえば、Python の HTTP トレースを有効にするには、httplib2
ライブラリを使用します。
httplib2.debuglevel = 4
ステップ 1 - 再開可能セッションを開始する
再開可能な動画のアップロードを開始するには、次の URL に POST リクエストを送信します。URL で、part
パラメータ値をリクエストの適切な値に設定します。パラメータ値は、設定しているプロパティを含む部分を識別します。また、API レスポンスに含める部分も識別することに注意してください。リクエスト URL 内のパラメータ値は URL エンコードする必要があります。
https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=PARTS
リクエストの本文を video
リソースに設定します。さらに、次の HTTP リクエスト ヘッダーも設定します。
Authorization
– リクエストの認証トークン。Content-Length
– リクエスト本文に含まれるバイト数。チャンク形式の転送エンコードを使用する場合、このヘッダーを指定する必要はありません。Content-Type
– 値をapplication/json; charset=UTF-8
に設定します。X-Upload-Content-Length
- 後続のリクエストでアップロードされるバイト数。値として、アップロードするファイルのサイズを設定します。x-upload-content-type
– アップロードするファイルの MIME タイプ。任意の MIME タイプ(video/*
)またはapplication/octet-stream
の MIME タイプのファイルをアップロードできます。
次の例は、動画のアップロードを再開可能なセッションを開始する方法を示しています。このリクエストは video
リソースの snippet
部分と status
部分にプロパティを設定(および取得)します。また、リソースの contentdetails
部分のプロパティも取得します。
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
次の例は、認証トークンを除くすべての値が入力された POST リクエストを示しています。この例の categoryId
値は動画のカテゴリに対応しています。サポートされているカテゴリのリストは、API の videoCategories.list
メソッドを使用して取得できます。
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" } }
ステップ 2 - 再開可能セッション URI を保存する
リクエストが成功すると、API サーバーは 200
(OK
)HTTP ステータス コードを返します。レスポンスには、再開可能セッションの URI を示す Location
HTTP ヘッダーが含まれます。これは動画ファイルのアップロードに使用する URI です。
以下は、ステップ 1 でのリクエストに対する API レスポンスの例です。
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
手順 3 - 動画ファイルをアップロードする
API レスポンスからセッション URI を抽出したら、その場所に実際の動画ファイルのコンテンツをアップロードする必要があります。リクエストのボディは、アップロードする動画のバイナリ ファイル コンテンツです。以下はリクエストの形式を示す例です。
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: CONTENT_LENGTH Content-Type: CONTENT_TYPE BINARY_FILE_DATA
リクエストは、次の HTTP リクエスト ヘッダーを設定します。
Authorization
– リクエストの認証トークン。Content-Length
– アップロードするファイルのサイズ。この値は、ステップ 1 のX-Upload-Content-Length
HTTP リクエスト ヘッダーの値と同じにする必要があります。Content-Type
– アップロードするファイルの MIME タイプ。この値は、ステップ 1 のX-Upload-Content-Type
HTTP リクエスト ヘッダーの値と同じにする必要があります。
ステップ 4 - アップロード プロセスを完了する
リクエストの結果は、次のいずれかのシナリオとなります。
-
正常にアップロードされました。
API サーバーは HTTP
201
(Created
)レスポンス コードを返します。レスポンスの本文は、作成したvideo
リソースです。 -
アップロードは成功しませんでしたが、再開できます。
次のいずれかのケースでは、アップロードは再開可能です。
-
アプリケーションと API サーバーの間の接続が失われたためにリクエストが中断した場合。このケースでは API レスポンスを受け取りません。
-
API レスポンスでは、次のいずれかの
5xx
レスポンス コードを指定します。これらのレスポンス コードのいずれかを受け取った後にアップロードを再開する場合は、コードで指数バックオフ戦略を使用する必要があります。500
~Internal Server Error
502
~Bad Gateway
503
~Service Unavailable
504
~Gateway Timeout
アップロードを再開するには、下記のアップロード ステータスを確認するとアップロードを再開するの説明をご覧ください。再開可能セッション URI の存続期間は有限で、最終的には期限切れとなります。このため、セッション URI を取得したら即座に再開可能アップロードを開始し、中断が発生したら速やかにアップロードを再開することをおすすめします。
-
-
アップロードが完全に失敗しました。
アップロードが失敗すると、レスポンスには失敗の原因を説明するエラー レスポンスが含まれます。アップロードに失敗すると、API レスポンスには上記のコード以外の
4xx
レスポンス コードまたは5xx
レスポンス コードが返されます。期限切れのセッション URI を含むリクエストを送信すると、サーバーが
404
HTTP レスポンス コード(Not Found
)を返します。この場合、新しい再開可能なアップロードを開始し、新しいセッション URI を取得して、新しい URI を使用して最初からアップロードを開始する必要があります。
ステップ 4.1: アップロード ステータスを確認する
中断された再開可能アップロードのステータスを確認するには、ステップ 2 で取得し、ステップ 3 で使用したアップロード URL に空の PUT リクエストを送信します。リクエストで、Content-Range
ヘッダー値を bytes */CONTENT_LENGTH
に設定します。CONTENT_LENGTH はアップロードするファイルのサイズです。
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: 0 Content-Range: bytes */CONTENT_LENGTH
ステップ 4.2: API レスポンスを処理する
アップロードが既に完了している場合、成功したか失敗したかにかかわらず、API はアップロードが最初に完了したときに送信したものと同じレスポンスを返します。
ただし、アップロードが中断された場合やアップロードがまだ進行中の場合、API レスポンスには HTTP 308
(Resume Incomplete
)レスポンス コードが含まれます。レスポンスの Range
ヘッダーは、ファイルが正常にアップロードされているバイト数を示します。
- このヘッダー値は
0
から始まります。そのため、ヘッダー値が0-999999
の場合、ファイルの最初の1,000,000
バイトがアップロードされています。 - まだ何もアップロードされていない場合、API レスポンスには
Range
ヘッダーが含まれません。
以下は、再開可能アップロードでの API レスポンスの形式を示すサンプル レスポンスです。
308 Resume Incomplete Content-Length: 0 Range: bytes=0-999999
API レスポンスに Retry-After
ヘッダーも含まれている場合は、そのヘッダーの値を使用してアップロードの再開のタイミングを判断します。
ステップ 4.3: アップロードを再開する
アップロードを再開するには、ステップ 2 で取得されたアップロード URL にもう一度 PUT
リクエストを送ります。リクエスト ボディには、動画ファイル中のアップロード未完了部分のバイナリ コードを設定します。
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
設定する必要がある HTTP リクエスト ヘッダーは次のとおりです。
-
Authorization
– リクエストの認証トークン。 -
Content-Length
– まだアップロードされていないコンテンツのサイズ(バイト単位)。それ以外のファイルをアップロードする場合は、TOTAL_CONTENT_LENGTH
の値からFIRST_BYTE
の値を差し引くことでこの値を計算できます。どちらの値もContent-Range
ヘッダーで使用されます。 -
Content-Range
- アップロードするファイルの部分。このヘッダー値は 3 つの値で構成されます。-
FIRST_BYTE
– 何バイト目からアップロードを再開するかを示す数値的指標(0 から開始)。この値は、前のステップで取得したRange
ヘッダーの 2 番目の数値よりも 1 つ大きい値です。上記の例では、Range
ヘッダー値は0-999999
であったため、その後の再開時のアップロードの最初のバイトは1000000
になります。 -
LAST_BYTE
– アップロードするバイナリ ファイルが何バイト目で終わるかを示す数値的指標(0 から開始)。通常、これはファイル内の最後のバイトです。 たとえば、ファイルサイズが3000000
バイトの場合、ファイルの最後のバイトは2999999
の数字になります。 -
TOTAL_CONTENT_LENGTH
– 動画ファイルの合計サイズ(バイト単位)。この値は、元のアップロード リクエストで指定されているContent-Length
ヘッダーと同じです。
注: 不連続なバイナリ ファイル ブロックをアップロードすることはできません。不連続なブロックをアップロードしようとすると、残りのバイナリ コンテンツは一切アップロードされません。
そのため、再開アップロードにアップロードする最初のバイトは、YouTube に正常にアップロードされた最後のバイトの次のバイトでなければなりません。(ステップ 4.2 のRange
ヘッダーの説明をご覧ください)。
したがって、Range
ヘッダーの最後のバイトが999999
の場合、アップロードを再開するリクエストの最初のバイトは 1000000 バイトにする必要があります。(いずれの数値も 0 からカウントされます)。999999 バイト以下(重複バイト)または 1000001 バイト以上(バイトのスキップ)からアップロードを再開しようとしても、バイナリ コンテンツはアップロードされません。 -
チャンクでファイルをアップロードする
ファイル全体をアップロードしてネットワークが中断した場合にアップロードを再開するのではなく、アプリケーションでファイルをチャンクに分割し、一連のリクエストを送信してチャンクを順番にアップロードすることもできます。この方法が必要になることはほとんどありません。また、多くのリクエストが必要でパフォーマンスに影響を与えるため、実際にはおすすめできません。ただし、非常に不安定なネットワーク上で進捗状況を示す指標を見ようとしている場合には役立ちます。
ファイルをチャンクでアップロードする方法についての説明は、上記の 4 つのステップとほぼ同じです。ただし、ファイルをチャンクでアップロードする場合は、ファイルのアップロードの開始(上記のステップ 3)とアップロードの再開(上記のステップ 4.3)の両方の Content-Length
ヘッダー値と Content-Range
ヘッダー値の設定が異なります。
-
Content-Length
ヘッダー値は、リクエストが送信するチャンクのサイズを指定します。チャンク サイズに関する次の制限に注意してください。-
チャンクサイズは 256 KB の倍数にする必要があります。(ファイル全体のサイズが 256 KB の倍数ではないため、この制限は最後のチャンクには適用されません)。チャンクのサイズは大きいほど効率的です。
-
アップロード シーケンスのすべてのリクエストのチャンク サイズは等しくなければなりません。ただし、最後のチャンクのサイズを指定する最後のリクエストについては例外です。
-
-
Content-Range
ヘッダーは、リクエストがアップロードしているファイル内のバイトを指定します。ステップ 4.3 でContent-Range
ヘッダーを設定する手順は、この値を設定するときに適用できます。たとえば、
bytes 0-524287/2000000
の値は、リクエストが 2, 000,000 バイトのファイルで最初の 524,288 バイト(256 x 2,048)を送信していることを示します。
下記は、2,000,000 バイトのファイルをチャンクでアップロードする一連のリクエストの中の最初のリクエストの形式を示す例です。
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}
最後のリクエスト以外のリクエストが成功すると、API サーバーは 308
(Resume Incomplete
)レスポンスを返します。レスポンスの形式は、上記のステップ 4.2: API レスポンスを処理するで説明したものと同じです。
API レスポンスの Range
ヘッダーで返された上限値を使用して、次のチャンクの開始位置を決定します。ステップ 4.3: アップロードを再開するで説明されているように、引き続き PUT
リクエストを送信して、ファイル全体のアップロードが完了するまで後続のファイル チャンクをアップロードします。
ファイル全体がアップロードされると、サーバーは 201
HTTP レスポンス コード(Created
)で応答し、新しく作成された動画リソースのリクエストされた部分を返します。
リクエストが中断された場合や、アプリケーションで 5xx
レスポンス コードを受信した場合は、ステップ 4 の手順に沿ってアップロードを完了してください。ただし、残りのファイルをアップロードするのではなく、アップロードを再開するポイントからチャンクのアップロードを続けます。ファイル アップロードをどこから再開するかを判別するには、必ずアップロード ステータスを確認してください。前のリクエストで送信されたバイトがすべてサーバーに受信された(あるいはまったく受信されていない)と仮定することはできません。
注: アップロードされたチャンクの間にアクティブ アップロードのステータスをリクエストすることもできます(ステータスを取得する前にアップロードを中断する必要はありません)。