Przesyłanie wznowione

Aby przesyłać filmy bardziej niezawodnie, użyj protokołu wznawiania przesyłania w interfejsach API Google. Protokół ten pozwala wznowić operację przesyłania w przypadku awarii sieci lub innej awarii transmisji, co pozwala oszczędzić czas i przepustowość w przypadku awarii sieci.

Przesyłanie z możliwością wznowienia jest szczególnie przydatne w tych przypadkach:

  • Przenosisz duże pliki.
  • Prawdopodobieństwo przerw w działaniu sieci jest wysokie.
  • Przesłane pliki pochodzą z urządzenia o niskiej przepustowości lub niestabilnym połączeniu z internetem (np. na urządzeniu mobilnym).

Ten przewodnik wyjaśnia sekwencję żądań HTTP, które aplikacja wysyła do przesyłania filmów za pomocą procesu wznawiania. Ten przewodnik jest przeznaczony przede wszystkim dla deweloperów, którzy nie mogą korzystać z bibliotek klienta interfejsu API Google. Niektóre z nich umożliwiają natywne przesyłanie treści z możliwością wznowienia. Przewodnik YouTube Data API – przesyłanie filmów wyjaśnia, jak korzystać z biblioteki klienta interfejsów API Google w języku Python do przesyłania filmów z użyciem wznawianego procesu przesyłania.

Uwaga: możesz też zobaczyć serię żądań wznowienia przesyłania lub innych operacji API, korzystając z jednej z bibliotek klienta Google API z włączoną funkcją logowania HTTPS. Aby na przykład włączyć śledzenie HTTP dla Pythona, użyj biblioteki httplib2:

httplib2.debuglevel = 4

Krok 1. Rozpocznij sesję wznawiania

Aby rozpocząć przesyłanie filmu do wznowienia, wyślij żądanie POST na ten URL. W adresie URL ustaw wartość parametru part na odpowiednią dla Twojego żądania. Pamiętaj, że wartość parametru identyfikuje części, które zawierają określone właściwości, oraz części, które interfejs API ma uwzględniać. Wartości parametrów w adresie URL żądania muszą być zakodowane.

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

Ustaw treść żądania na zasób video. Ustaw też te nagłówki żądań HTTP:

  • Authorization – token autoryzacji żądania.
  • Content-Length – liczba bajtów podanych w treści żądania. Jeśli używasz kodowania fragmentów, nie musisz podawać tego nagłówka.
  • Content-Type – ustaw wartość na application/json; charset=UTF-8.
  • X-Upload-Content-Length – liczba bajtów, które zostaną przesłane w kolejnych żądaniach. Ustaw tę wartość na rozmiar przesyłanego pliku.
  • x-upload-content-type – typ MIME pliku, który przesyłasz. Możesz przesyłać pliki z dowolnym typem MIME filmu (video/*) lub MIME (application/octet-stream).

Poniższy przykład pokazuje, jak rozpocząć sesję wznawiania podczas przesyłania filmu. Żądanie żąda (i pobiera) właściwości w częściach snippet i status zasobu video oraz pobiera właściwości z części contentdetails zasobu.

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

Poniższy przykład pokazuje żądanie POST, które zawiera wszystkie wartości oprócz tokena uwierzytelniania. Wartość categoryId w przykładzie odpowiada kategorii filmu. Listę obsługiwanych kategorii można pobrać za pomocą metody videoCategories.list interfejsu 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"
  }
}

Krok 2. Zapisz identyfikator URI sesji możliwej do wznowienia

Jeśli żądanie się powiedzie, serwer interfejsu API wyśle kod stanu HTTP 200 (OK), a odpowiedź będzie zawierać nagłówek HTTP Location, który określa identyfikator URI sesji możliwej do wznowienia. Jest to identyfikator URI, którego będziesz używać do przesyłania pliku wideo.

Przykład poniżej pokazuje przykładową odpowiedź interfejsu API na żądanie w kroku 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

Krok 3. Prześlij plik wideo

Po wyodrębnieniu identyfikatora URI sesji z odpowiedzi interfejsu API musisz przesłać rzeczywistą zawartość pliku wideo do tej lokalizacji. Treść żądania to treść pliku binarnego przesyłanego filmu. Przykład poniżej pokazuje format żądania.

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

BINARY_FILE_DATA

Żądanie zawiera następujące nagłówki HTTP:

  • Authorization – token autoryzacji żądania.
  • Content-Length – rozmiar przesyłanego pliku. Ta wartość powinna być taka sama jak wartość nagłówka żądania HTTP X-Upload-Content-Length w kroku 1.
  • Content-Type – typ MIME pliku, który przesyłasz. Ta wartość powinna być taka sama jak wartość nagłówka żądania HTTP X-Upload-Content-Type w kroku 1.

Krok 4. Zakończ proces przesyłania

Prośba doprowadzi do jednego z tych scenariuszy:

  • Udało się przesłać.

    Serwer interfejsu API wysyła kod odpowiedzi HTTP 201 (Created). Treść odpowiedzi to utworzony przez Ciebie zasób video.

  • Nie udało się przesłać pliku, ale możesz go wznowić.

    Możesz wznowić przesyłanie w jednym z tych przypadków:

    • Żądanie zostało przerwane, ponieważ połączenie między aplikacją a serwerem interfejsu API zostało przerwane. W takim przypadku nie otrzymasz odpowiedzi interfejsu API.

    • Odpowiedź interfejsu API określa dowolny z tych kodów odpowiedzi 5xx. Aby wznowić przesyłanie po otrzymaniu dowolnego z tych kodów odpowiedzi, użyj kodu wykładniczego ponowienia.

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

    Aby wznowić przesyłanie, wykonaj poniższe instrukcje sprawdzania jego stanu i wznowienia przesyłania. Pamiętaj, że każdy identyfikator URI sesji możliwej do wznowienia ma ograniczony czas trwania i w końcu wygasa. Dlatego zalecamy rozpoczęcie przesyłania od razu po otrzymaniu identyfikatora URI sesji i wznowienie przerwanego przesyłania zaraz po tym, jak już wystąpi.

  • Nie udało się przesłać

    W przypadku nieudanego przesyłania odpowiedź zawiera odpowiedź z błędem, która pomaga wyjaśnić jej przyczynę. W przypadku nieudanego przesyłania danych odpowiedź interfejsu API będzie miała kod odpowiedzi 4xx lub 5xx inny niż te wymienione powyżej.

    Jeśli wyślesz żądanie z nieaktualnym identyfikatorem URI sesji, serwer zwróci kod odpowiedzi HTTP 404 (Not Found). W takim przypadku musisz przesłać nowy plik do wznowienia, uzyskać nowy identyfikator URI sesji i zacząć przesyłanie od początku, używając nowego identyfikatora URI.

Krok 4.1. Sprawdź stan przesyłania

Aby sprawdzić stan przerwania wznawianego przesyłania, wyślij puste żądanie PUT na adres URL przesyłania pobrany w kroku 2, który został też użyty w kroku 3. W żądaniu ustaw wartość nagłówka Content-Range na bytes */CONTENT_LENGTH, gdzie CONTENT_LENGTH to rozmiar przesyłanego pliku.

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

Krok 4.2. Przetwarzanie odpowiedzi interfejsu API

Niezależnie od tego, czy przesyłanie się udało, czy nie, interfejs API zwróci tę samą odpowiedź, która została wysłana po zakończeniu przesyłania.

Jeśli jednak przesyłanie zostało przerwane lub wciąż trwa, odpowiedź interfejsu API będzie zawierać kod odpowiedzi HTTP 308 (Resume Incomplete). Nagłówek Range określa w odpowiedzi, ile bajtów pliku zostało już przesłanych.

  • Wartość nagłówka jest zindeksowana z 0. W związku z tym wartość nagłówka 0-999999 wskazuje, że przesłano pierwsze 1,000,000 bajty pliku.
  • Jeśli nic nie zostało jeszcze przesłane, odpowiedź interfejsu API nie będzie zawierać nagłówka Range.

Poniższa przykładowa odpowiedź pokazuje format odpowiedzi interfejsu API służącej do wznawiania przesyłania:

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

Jeśli odpowiedź interfejsu API zawiera również nagłówek Retry-After, użyj wartości tego nagłówka, aby określić, kiedy należy wznowić przesyłanie.

Krok 4.3. Wznów przesyłanie

Aby wznowić przesyłanie, wyślij kolejną prośbę PUT na adres URL przesłany w kroku 2. Ustaw kod żądania jako kod binarny części pliku wideo, która nie została jeszcze przesłana.

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

Musisz ustawić te nagłówki żądania HTTP:

  • Authorization – token autoryzacji żądania.

  • Content-Length – rozmiar (w bajtach) zawartości, która nie została jeszcze przesłana. Jeśli przesyłasz pozostałą część pliku, możesz obliczyć tę wartość, odejmując wartość FIRST_BYTE od wartości TOTAL_CONTENT_LENGTH. Obie wartości są używane w nagłówku Content-Range.

  • Content-Range – część pliku, który przesyłasz. Wartość nagłówka składa się z 3 wartości:

    • FIRST_BYTE – oparty na 0 indeks liczbowy liczby bajtów, od których wznawiasz przesyłanie. Ta wartość jest o 1 liczba większa od wartości drugiej w nagłówku Range pobranym w poprzednim kroku. W poprzednim przykładzie wartość nagłówka Range wynosiła 0-999999, więc pierwszym bajtem w kolejnym wznowionym pliku będzie 1000000.

    • LAST_BYTE – oparty na 0 indeks liczbowy ostatniego bajtu przesłanego pliku binarnego. Zwykle jest to ostatni bajt w pliku. Jeśli na przykład rozmiar pliku wynosi 3000000 B, ostatnim bajtem w pliku będzie 2999999.

    • TOTAL_CONTENT_LENGTH – łączny rozmiar pliku wideo w bajtach. Ta wartość jest taka sama jak nagłówek Content-Length określony w pierwotnym żądaniu przesłania.

    Uwaga: nie możesz przesłać nieciągłego bloku pliku binarnego. Jeśli spróbujesz przesłać nieciągły blok, żadne pozostałe treści binarne nie zostaną przesłane.

    Pierwszy bajt przesłany w ramach wznowionego przesyłania musi następować po kolejnym bajcie, który został już przesłany do YouTube. Zapoznaj się z omówieniem nagłówka Range w kroku 4.2.

    Jeśli więc ostatni bajt w nagłówku Range to 999999, pierwszy bajt w żądaniu wznowienia przesyłania musi być bajtem 1000000. (W przypadku obu numerów stosowany jest indeks oparty na 0). Jeśli spróbujesz wznowić przesyłanie z bajtu 999999 lub niższego (pokrywające się bajty) albo z bajtu 1000001 lub nowszego (pomijane bajty), nie zostaną przesłane żadne treści binarne.

Prześlij plik na fragmenty

Zamiast przesyłać cały plik i wznawiać przesyłanie w przypadku przerw w sieci, aplikacja może podzielić plik na kilka części i wysyłać serie żądań po kolei. Takie podejście jest rzadko konieczne i nie jest zalecane, ponieważ wymaga dodatkowych żądań, co ma wpływ na wydajność. Może się jednak przydać, gdy chcesz wyświetlić wskaźnik postępu w bardzo niestabilnej sieci.

Instrukcje dotyczące przesyłania plików podzielonych na części są praktycznie identyczne z 4-etapowym procesem opisanym wcześniej w tym przewodniku. Jednak żądania rozpoczęcia przesyłania pliku (krok 3 powyżej) i wznowienia przesyłania (krok 4.3 powyżej) ustawiają wartości nagłówka Content-Length i Content-Range podczas przesyłania pliku na kilka grup.

  • Wartość nagłówka Content-Length określa rozmiar fragmentu, który wysyła żądanie. Zwróć uwagę na te ograniczenia dotyczące rozmiarów fragmentów:

    • Rozmiar fragmentu musi być wielokrotnością rozmiaru 256 KB. (To ograniczenie nie dotyczy ostatniego fragmentu, bo rozmiar całego pliku nie może być wielokrotnością 256 KB). Pamiętaj, że większe kawałki są skuteczniejsze.

    • Rozmiar każdego fragmentu musi być taki sam dla każdego żądania w sekwencji przesyłania. Wyjątkiem jest ostatnie żądanie, które określa rozmiar końcowego fragmentu.

  • Nagłówek Content-Range określa bajty w pliku, który jest przesyłany. Podczas ustawiania tej wartości obowiązują instrukcje dotyczące ustawienia nagłówka Content-Range w kroku 4.3.

    Na przykład wartość bytes 0-524287/2000000 oznacza, że żądanie wysyła pierwsze 524 288 bajtów (256 x 2048) w pliku 2 000 000 bajtów.

Przykład poniżej pokazuje format pierwszego z żądań żądań, które przesyła 2 000 000 bajtów w fragmentach:

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}

Jeśli żądanie inne niż ostatnie zostanie zrealizowane, serwer interfejsu API odpowie 308 (Resume Incomplete). Format odpowiedzi będzie taki sam jak opisany powyżej w sekcji Krok 4.2 Przetwarzanie odpowiedzi interfejsu API.

Użyj górnej wartości zwróconej w nagłówku Range odpowiedzi interfejsu API, aby określić, gdzie zacząć następny fragment. Nadal wysyłaj żądania PUT (zgodnie z opisem w Kroku 4.3: Wznów przesyłanie), aby przesyłać kolejne fragmenty do momentu przesłania całego pliku.

Po przesłaniu całego pliku serwer wysyła kod odpowiedzi HTTP 201 (Created) i zwraca żądaną część nowo utworzonego zasobu wideo.

Jeśli jakiekolwiek żądanie zostanie przerwane lub aplikacja otrzyma kod odpowiedzi 5xx, wykonaj czynności opisane w kroku 4, aby przesłać dane. Jednak zamiast próby przesłania pozostałej części pliku, przesyłaj tylko fragmenty od momentu, gdy wznowisz przesyłanie. Sprawdź stan przesyłania, aby dowiedzieć się, gdzie wznowić przesyłanie plików. Nie zakładaj, że serwer otrzymał wszystkie (lub żadne) bajty wysłane w poprzednim żądaniu.

Uwaga: możesz też poprosić o stan aktywnego przesyłania między przesłanymi fragmentami. (Nie trzeba przerywać przesyłania, zanim będzie można pobrać jego stan).