Tải lên tiếp nối

Bạn có thể tải video lên một cách đáng tin cậy hơn bằng cách sử dụng giao thức tải lên tiếp nối cho các API của Google. Giao thức này cho phép bạn tiếp tục hoạt động tải lên sau các gián đoạn mạng hoặc lỗi truyền khác, tiết kiệm thời gian và băng thông trong trường hợp lỗi mạng.

Việc sử dụng tính năng tải lên tiếp nối đặc biệt hữu ích trong bất kỳ trường hợp nào sau đây:

  • Bạn đang chuyển các tệp lớn.
  • Khả năng bị gián đoạn mạng là rất cao.
  • Nội dung tải lên bắt nguồn từ một thiết bị có kết nối Internet băng thông thấp hoặc không ổn định, chẳng hạn như thiết bị di động.

Hướng dẫn này giải thích trình tự các yêu cầu HTTP mà ứng dụng thực hiện để tải video lên bằng quy trình tải lên tiếp nối. Hướng dẫn này chủ yếu dành cho những nhà phát triển không thể sử dụng thư viện ứng dụng API của Google. Một số thư viện trong đó cung cấp tính năng hỗ trợ gốc cho tính năng tiếp tục tải lên. Trên thực tế, hướng dẫn API Dữ liệu YouTube – Tải video lên giải thích cách sử dụng Thư viện ứng dụng Python cho API của Google để tải video lên bằng quy trình tải lên tiếp nối.

Lưu ý: Bạn cũng có thể xem một loạt các yêu cầu được tiếp tục để tải lên có thể tiếp tục hoặc bất kỳ hoạt động nào khác của API bằng cách sử dụng một trong những thư viện ứng dụng API của Google có bật tính năng ghi nhật ký HTTPS. Ví dụ: để bật tính năng theo dõi HTTP cho Python, hãy sử dụng thư viện httplib2:

httplib2.debuglevel = 4

Bước 1 – Bắt đầu một phiên hoạt động có thể tiếp tục

Để bắt đầu tải lên video có thể tiếp tục, gửi yêu cầu POST tới URL sau. Trong URL này, hãy đặt giá trị tham số part thành giá trị thích hợp cho yêu cầu của bạn. Hãy nhớ rằng giá trị tham số xác định các phần trong thuộc tính mà bạn đang thiết lập, đồng thời cũng xác định các phần mà bạn muốn phản hồi API đưa vào. Các giá trị tham số trong URL yêu cầu phải được mã hoá URL.

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

Đặt nội dung của yêu cầu thành tài nguyên video. Đồng thời, đặt các tiêu đề của yêu cầu HTTP sau:

  • Authorization – Mã thông báo uỷ quyền cho yêu cầu.
  • Content-Length – Số byte được cung cấp trong phần nội dung của yêu cầu. Lưu ý rằng bạn không cần cung cấp tiêu đề này nếu bạn đang sử dụng mã hóa chuyển dữ liệu chia nhỏ.
  • Content-Type – Đặt giá trị thành application/json; charset=UTF-8.
  • X-Upload-Content-Length – Số byte sẽ được tải lên trong các yêu cầu tiếp theo. Đặt giá trị này thành kích thước của tệp mà bạn đang tải lên.
  • x-upload-content-type – loại MIME của tệp mà bạn đang tải lên. Bạn có thể tải tệp lên có bất kỳ loại MIME video nào (video/*) hoặc loại MIME application/octet-stream.

Ví dụ sau đây minh họa cách bắt đầu một phiên có thể tiếp tục để tải video lên. yêu cầu đặt (và sẽ truy xuất) các thuộc tính trong phần snippetstatus của tài nguyên video, đồng thời cũng sẽ truy xuất các thuộc tính trong phần contentdetails của tài nguyên.

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

Ví dụ sau đây cho thấy một yêu cầu POST có chứa tất cả các giá trị này, ngoại trừ mã xác thực. Giá trị categoryId trong ví dụ này tương ứng với một danh mục video. Bạn có thể truy xuất danh sách danh mục được hỗ trợ bằng phương thức videoCategories.list của 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"
  }
}

Bước 2 – Lưu URI phiên có thể tiếp tục

Nếu yêu cầu của bạn thành công, máy chủ API sẽ phản hồi bằng mã trạng thái HTTP 200 (OK), và phản hồi sẽ bao gồm tiêu đề HTTP Location chỉ định URI cho phiên có thể tiếp tục. Đây là URI mà bạn sẽ sử dụng để tải tệp video lên.

Ví dụ dưới đây minh họa phản hồi API mẫu cho yêu cầu ở bước 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

Bước 3 – Tải tệp video lên

Sau khi trích xuất URI phiên hoạt động từ phản hồi API, bạn cần tải nội dung tệp video thực tế lên vị trí đó. Nội dung của yêu cầu là nội dung tệp nhị phân cho video mà bạn đang tải lên. Ví dụ dưới đây trình bày định dạng của yêu cầu.

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

BINARY_FILE_DATA

Yêu cầu này đặt ra các tiêu đề của yêu cầu HTTP sau đây:

  • Authorization – Mã thông báo uỷ quyền cho yêu cầu.
  • Content-Length – Kích thước của tệp mà bạn đang tải lên. Giá trị này phải giống với giá trị của tiêu đề yêu cầu HTTP X-Upload-Content-Length trong bước 1.
  • Content-Type – Loại MIME của tệp mà bạn đang tải lên. Giá trị này phải giống với giá trị của tiêu đề yêu cầu HTTP X-Upload-Content-Type trong bước 1.

Bước 4 – Hoàn tất quy trình tải lên

Yêu cầu của bạn sẽ dẫn đến một trong các trường hợp sau:

  • Bạn đã tải lên xong.

    Máy chủ API phản hồi bằng mã phản hồi HTTP 201 (Created). Nội dung của phản hồi là tài nguyên video mà bạn đã tạo.

  • Việc tải lên của bạn không thành công nhưng có thể tiếp tục.

    Bạn có thể tiếp tục tải lên trong một trong các trường hợp sau:

    • Yêu cầu của bạn bị gián đoạn vì kết nối giữa ứng dụng của bạn và máy chủ API bị mất. Trong trường hợp này, bạn sẽ không nhận được phản hồi của API.

    • Phản hồi API chỉ định bất kỳ mã phản hồi 5xx nào sau đây. Mã của bạn nên sử dụng một chiến lược thời gian đợi lũy thừa khi tiếp tục tải lên sau khi nhận được bất kỳ mã phản hồi nào trong số này.

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

    Để tiếp tục tải lên, hãy làm theo hướng dẫn để kiểm tra trạng thái của tệp tải lêntiếp tục quá trình tải lên ở bên dưới. Hãy nhớ rằng mỗi URI phiên có thể tiếp tục đều có thời gian tồn tại nhất định và sẽ hết hạn. Vì lý do này, bạn nên bắt đầu tải lên tiếp ngay khi bạn nhận được URI phiên và tiếp tục tải lên bị gián đoạn ngay sau khi gián đoạn xảy ra.

  • Tải lên vĩnh viễn không thành công.

    Đối với cách tải lên không thành công, phản hồi chứa phản hồi lỗi giúp giải thích nguyên nhân lỗi. Đối với lần tải lên không thành công vĩnh viễn, phản hồi API sẽ có mã phản hồi 4xx hoặc mã phản hồi 5xx ngoài những mã được liệt kê ở trên.

    Nếu bạn gửi yêu cầu với URI phiên đã hết hạn, máy chủ sẽ trả về mã phản hồi HTTP 404 (Not Found). Trong trường hợp này, bạn cần bắt đầu quá trình tải lên có thể tiếp nối, lấy URI phiên mới và bắt đầu tải lên từ đầu bằng cách sử dụng URI mới.

Bước 4.1: Kiểm tra trạng thái của tệp tải lên

Để kiểm tra trạng thái tải lên tiếp nối bị gián đoạn, hãy gửi yêu cầu PUT trống đến URL tải lên mà bạn đã truy xuất ở bước 2 và cũng đã sử dụng ở bước 3. Trong yêu cầu của bạn, hãy đặt giá trị tiêu đề Content-Range thành bytes */CONTENT_LENGTH, trong đó CONTENT_LENGTH là kích thước của tệp mà bạn đang tải lên.

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

Bước 4.2: Xử lý phản hồi API

Nếu quá trình tải lên đã hoàn tất, bất kể tải lên thành công hay không, API sẽ trả về cùng một phản hồi mà hệ thống đã gửi khi tải lên xong.

Tuy nhiên, nếu quá trình tải lên bị gián đoạn hoặc vẫn đang diễn ra, phản hồi API sẽ có mã phản hồi HTTP 308 (Resume Incomplete). Trong phản hồi, tiêu đề Range chỉ định số byte mà tệp đã tải lên thành công.

  • Giá trị của tiêu đề được lập chỉ mục từ 0. Do đó, giá trị tiêu đề của 0-999999 cho biết rằng 1,000,000 byte đầu tiên của tệp đã được tải lên.
  • Nếu chưa có gì được tải lên, phản hồi của API sẽ không bao gồm tiêu đề Range.

Phản hồi mẫu dưới đây cho thấy định dạng của phản hồi API để tải lên tiếp:

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

Nếu phản hồi API cũng bao gồm tiêu đề Retry-After, hãy sử dụng giá trị của tiêu đề đó để xác định thời điểm cố gắng tiếp tục tải lên.

Bước 4.3: Tiếp tục tải lên

Để tiếp tục tải lên, hãy gửi một yêu cầu PUT khác đến URL mà bạn tải lên ở bước 2. Đặt nội dung yêu cầu thành mã nhị phân cho phần tệp video chưa được tải lên.

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

Bạn cần đặt các tiêu đề của yêu cầu HTTP sau đây:

  • Authorization – Mã thông báo uỷ quyền cho yêu cầu.

  • Content-Length – Kích thước, tính bằng byte, của nội dung chưa được tải lên. Nếu đang tải các tệp còn lại lên, bạn có thể tính giá trị này bằng cách trừ giá trị FIRST_BYTE cho giá trị TOTAL_CONTENT_LENGTH. Cả hai giá trị này đều được dùng trong tiêu đề Content-Range.

  • Content-Range – Phần của tệp mà bạn đang tải lên. Giá trị tiêu đề bao gồm ba giá trị:

    • FIRST_BYTE – Chỉ mục số 0 dựa trên số byte mà từ đó bạn đang tiếp tục tải lên. Giá trị này cao hơn một số so với số thứ hai trong tiêu đề Range được truy xuất ở bước trước. Trong ví dụ trước, giá trị tiêu đề Range0-999999, vì vậy byte đầu tiên trong quá trình tải lên tiếp theo sẽ là 1000000.

    • LAST_BYTE – Chỉ mục số 0 dựa trên byte cuối cùng của tệp nhị phân bạn đang tải lên. Thông thường, đây là byte cuối cùng trong tệp. Ví dụ: nếu kích thước tệp là 3000000 byte, byte cuối cùng trong tệp sẽ là số 2999999.

    • TOTAL_CONTENT_LENGTH – Tổng kích thước của tệp video tính bằng byte. Giá trị này giống với tiêu đề Content-Length được chỉ định trong yêu cầu tải lên ban đầu.

    Lưu ý: Bạn không thể tải khối nhị phân không liên tục lên tệp. Nếu bạn cố gắng tải một khối không liên tục lên, hệ thống sẽ không tải nội dung nhị phân còn lại lên.

    Do đó, byte đầu tiên được tải lên trong một lần tải lên tiếp tục phải là byte tiếp theo sau byte cuối cùng được tải lên YouTube thành công. (Xem phần thảo luận về tiêu đề Range trong bước 4.2.

    Do đó, nếu byte cuối cùng trong tiêu đề Range999999, thì byte đầu tiên trong yêu cầu tiếp tục tải lên phải là byte 1000000. (Cả hai số đều sử dụng chỉ mục dựa trên 0.) Nếu bạn cố gắng tiếp tục tải lên từ byte 999999 trở xuống (byte byte) hoặc byte 1000001 trở lên (bỏ qua byte), thì sẽ không có nội dung nhị phân nào được tải lên.

Tải tệp lên theo từng phần

Thay vì cố gắng tải toàn bộ tệp lên và tiếp tục tải lên trong trường hợp bị gián đoạn mạng, ứng dụng của bạn có thể chia tệp thành nhiều phần và gửi một loạt yêu cầu để tải các đoạn theo trình tự. Phương pháp này ít khi cần thiết và thực sự không được khuyến khích vì phương pháp này cần thêm các yêu cầu, điều này có ảnh hưởng đến hiệu suất. Tuy nhiên, tính năng này có thể hữu ích nếu bạn đang cố gắng hiển thị chỉ báo tiến trình trên một mạng rất không ổn định.

Hướng dẫn tải tệp lên theo từng phần gần như giống với quy trình gồm 4 bước được giải thích trước đó trong hướng dẫn này. Tuy nhiên, các yêu cầu bắt đầu tải tệp lên (bước 3 ở trên) và tiếp tục tải lên (bước 4.3 ở trên) đều đặt giá trị tiêu đề Content-LengthContent-Range theo cách khác nhau khi tải tệp lên theo từng phần.

  • Giá trị tiêu đề Content-Length chỉ định kích thước của phân đoạn mà yêu cầu đang gửi. Hãy lưu ý các hạn chế sau về kích thước phân đoạn:

    • Kích thước phân đoạn phải là bội số của 256 KB. (Hạn chế này không áp dụng cho phần cuối cùng vì kích thước của toàn bộ tệp có thể không phải là bội số của 256 KB.) Hãy nhớ rằng các đoạn lớn hơn sẽ hiệu quả hơn.

    • Kích thước phân đoạn phải giống nhau cho mỗi yêu cầu trong trình tự tải lên, ngoại trừ yêu cầu cuối cùng sẽ chỉ định kích thước của phân đoạn cuối cùng.

  • Tiêu đề Content-Range chỉ định các byte trong tệp mà yêu cầu đang tải lên. Bạn có thể áp dụng hướng dẫn đặt tiêu đề Content-Range trong bước 4.3 khi đặt giá trị này.

    Ví dụ: Giá trị của bytes 0-524287/2000000 cho thấy yêu cầu đang gửi 524.288 byte đầu tiên (256 x 2048) trong một tệp chứa 2.000.000 byte.

Ví dụ bên dưới cho thấy định dạng của yêu cầu đầu tiên trong loạt yêu cầu sẽ tải tệp 2.000.000 byte lên theo từng phần:

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}

Nếu một yêu cầu khác ngoài yêu cầu cuối cùng thành công, máy chủ API sẽ phản hồi bằng một phản hồi 308 (Resume Incomplete). Định dạng phản hồi sẽ giống như định dạng được mô tả trong Bước 4.2: Xử lý phản hồi API ở trên.

Sử dụng giá trị trên được trả về trong tiêu đề Range của phản hồi API để xác định vị trí bắt đầu phần tiếp theo. Tiếp tục gửi PUT yêu cầu, như được mô tả trong Bước 4.3: Tiếp tục tải lên, để tải lên các tệp tệp tiếp theo cho đến khi toàn bộ tệp được tải lên.

Khi toàn bộ tệp được tải lên, máy chủ phản hồi bằng mã phản hồi HTTP 201 (Created) và trả về các phần yêu cầu của tài nguyên video mới tạo.

Nếu có bất kỳ yêu cầu nào bị gián đoạn hoặc ứng dụng của bạn nhận được mã phản hồi 5xx, hãy làm theo quy trình được giải thích trong bước 4 để hoàn tất quá trình tải lên. Tuy nhiên, thay vì cố gắng tải phần còn lại của tệp lên, bạn chỉ cần tiếp tục tải các phần lên từ thời điểm bạn tiếp tục tải lên. Hãy nhớ sử dụng trạng thái tải lên để xác định nơi tiếp tục quá trình tải tệp lên. Đừng giả định rằng máy chủ đã nhận được tất cả (hoặc không nhận được) số byte được gửi trong yêu cầu trước đó.

Lưu ý: Bạn cũng có thể yêu cầu xem trạng thái của một tệp tải lên đang hoạt động giữa các phân đoạn đã tải lên hay không. (Quá trình tải lên không cần bị gián đoạn trước khi bạn có thể truy xuất trạng thái của quá trình này.)