支援續傳的上傳作業

您可以使用 Google API 的支援續傳上傳通訊協定,更可靠地上傳影片。如因網路中斷或其他傳輸失敗問題,之後可透過此通訊協定繼續執行上傳作業,在網路發生問題時節省時間和頻寬。

在下列情況下,使用支援續傳的上傳作業特別實用:

  • 你正在傳輸大型檔案。
  • 網路中斷的可能性很高。
  • 上傳內容來自頻寬較低或網路連線不穩定的裝置,例如行動裝置。

本指南說明應用程式使用可續傳上傳程序上傳影片時,所發出 HTTP 要求的順序。本指南主要適用於無法使用 Google API 用戶端程式庫的開發人員,其中部分程式庫可原生支援可暫停上傳功能。事實上,「YouTube Data API - 上傳影片」指南說明瞭如何使用 Python 適用的 Google API 用戶端程式庫,透過可暫停上傳的程序上傳影片。

注意:您也可以使用已啟用 HTTPS 記錄功能的 Google API 用戶端程式庫,查看為可暫停上傳或任何其他 API 作業所提出的一系列要求。舉例來說,如要為 Python 啟用 HTTP 追蹤功能,請使用 httplib2 程式庫:

httplib2.debuglevel = 4

步驟 1 - 啟動可續傳的工作階段

如要開始可續傳的影片上傳作業,請將 POST 要求傳送至下列網址。在網址中,將 part 參數值設為適合要求的值。請注意,參數值會標示包含您設定的屬性,也會標示您希望 API 回應包含的部分。請務必為要求網址中的參數值加上網址編碼。

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 資源的 snippetstatus 部分中的屬性,也會擷取資源的 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 狀態碼,且回應會包含 Location HTTP 標頭,指定可繼續的工作階段的 URI。這是用來上傳影片檔案的 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:查看上傳作業狀態

如要查看中斷的支援續傳上傳作業狀態,請將空白 PUT 要求傳送至您在步驟 2 擷取並在步驟 3 中使用的上傳網址。在要求中,將 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:繼續上傳

如要繼續上傳,請將另一個 PUT 要求傳送至步驟 2 中擷取的上傳網址。將要求主體設為影片檔案尚未上傳部分的二進位碼。

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:尚未上傳的內容大小 (以位元組為單位)。如果您要上傳檔案的其餘部分,可以將 FIRST_BYTE 值減去 TOTAL_CONTENT_LENGTH 值來計算這個值。這兩個值都會用於 Content-Range 標頭。

  • Content-Range:您要上傳的檔案部分。標頭值包含三個值:

    • FIRST_BYTE:從中繼續上傳的位元組數,以 0 為起點的數字索引。這個值比先前步驟擷取的 Range 標頭中第二個數字大 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 以上 (跳過位元組) 繼續上傳,系統就不會上傳任何二進位內容。

分塊上傳檔案

應用程式可將檔案分割成多個區塊,然後傳送一系列要求,依序上傳這些區塊,而非嘗試上傳整個檔案,並在網路中斷時續傳上傳作業。這種做法很少必要,而且其實不建議採用,因為這會要求額外的要求,進而影響效能。不過,如果您想在非常不穩定的網路上顯示進度指標,這項功能可能會很實用。

分批上傳檔案的操作說明幾乎與本指南前述的四步驟程序相同。不過,當檔案以區塊上傳時,開始上傳檔案 (上方步驟 3) 和繼續上傳 (上方步驟 4.3) 的要求都會以不同的方式設定 Content-LengthContent-Range 標頭值。

  • Content-Length 標頭值會指定要求傳送的區塊大小。請注意以下關於區塊大小的限制:

    • 區塊大小必須是 256 KB 的倍數。(這項限制不適用於最後一個區塊,因為整個檔案的大小可能不是 256 KB 的倍數)。請注意,較大的區塊效率較高。

    • 上傳序列中的每個要求都必須使用相同的區塊大小,但最後一個要求除外,因為該要求會指定最終區塊的大小。

  • Content-Range 標頭會指定要求上傳的檔案中位元組數。設定這個值時,請參考步驟 4.3 中設定 Content-Range 標頭的操作說明。

    舉例來說,如果值為 bytes 0-524287/2000000,表示要求傳送的是 2,000,000 位元組檔案中的前 524,288 個位元組 (256 x 2048)。

以下範例顯示一系列要求中的第一個要求格式,該要求會以區塊方式上傳 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 標頭中傳回的上限值,決定下一個區塊要從哪裡開始。請繼續傳送 PUT 要求 (如「步驟 4.3:恢復上傳」所述),上傳後續的檔案區塊,直到整個檔案上傳完畢為止。

整個檔案上傳完畢後,伺服器會傳回 201 HTTP 回應碼 (Created),並傳回新建立的影片資源中要求的部分。

如果任何要求中斷,或是應用程式收到任何 5xx 回應碼,請按照步驟 4 所述的程序完成上傳作業。不過,請勿嘗試上傳檔案的其餘部分,而是從中斷處繼續上傳區塊。請務必使用上傳狀態檢查功能,判斷要從哪裡繼續上傳檔案。請勿假設伺服器已收到上一個要求中傳送的所有位元組 (或沒有收到任何位元組)。

注意:您也可以要求已上傳區塊之間的有效上傳狀態。(您不必等待上傳作業中斷,即可擷取上傳狀態)。