Możesz przesyłać filmy w bardziej niezawodny sposób, korzystając z protokołu umożliwiającego wznowienie przesyłania w interfejsach Google API. Ten protokół umożliwia wznowienie operacji przesyłania po przerwie w działaniu sieci lub innym błędzie transmisji, co pozwala zaoszczędzić czas i przepustowość w przypadku awarii sieci.
Przerywane przesyłanie jest szczególnie przydatne w tych sytuacjach:
- Przenosisz duże pliki.
- Prawdopodobieństwo przerwania połączenia jest wysokie.
- Przesyłanie danych pochodzi z urządzenia o niskiej przepustowości lub niestabilnym połączeniu z internetem, takiego jak urządzenie mobilne.
W tym przewodniku opisujemy sekwencję żądań HTTP, które aplikacja wysyła, aby przesłać filmy za pomocą procesu przerywanego przesyłania. Ten przewodnik jest przeznaczony przede wszystkim dla deweloperów, którzy nie mogą korzystać z bibliotek klienta interfejsu API Google, z których niektóre obsługują wbudowane wznawialne przesyłanie. W przewodniku YouTube Data API – przesyłanie filmu znajdziesz informacje o tym, jak za pomocą biblioteki klienta interfejsów API Google dla języka Python przesłać film przy użyciu procesu umożliwiającego wznowienie przesyłania.
Uwaga: możesz też wyświetlić serię żądań wysłanych w ramach przerywanego przesyłania lub innej operacji interfejsu API, korzystając z jednej z bibliotek klienta interfejsu API Google z włączonym rejestrowaniem HTTPS. Aby na przykład włączyć śledzenie HTTP w Pythonie, użyj biblioteki httplib2
:
httplib2.debuglevel = 4
Krok 1. Rozpocznij sesję z możliwością wznowienia
Aby rozpocząć przerywane przesyłanie filmu, wyślij żądanie POST na ten adres URL. W adresie URL ustaw wartość parametru part
na odpowiednią dla Twojego żądania. Pamiętaj, że wartość parametru identyfikuje części zawierające właściwości, które ustawiasz, a także części, które mają być uwzględnione w odpowiedzi interfejsu API. Wartości parametrów w adresie URL żądania muszą być zakodowane na potrzeby adresu URL.
https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=PARTS
W treści żądania ustaw zasób video
. Ustaw też te nagłówki żądania HTTP:
Authorization
– token autoryzacji żądania.Content-Length
– liczba bajtów podana w treści żądania. Jeśli używasz kodowania transferu w porcjach, nie musisz podawać tego nagłówka.Content-Type
– ustaw wartość naapplication/json; charset=UTF-8
.X-Upload-Content-Length
– liczba bajtów, które zostaną przesłane w kolejnych żądaniach. Ustaw tę wartość na rozmiar pliku, który przesyłasz.x-upload-content-type
– typ MIME pliku, który przesyłasz. Możesz przesyłać pliki z dowolnym typem MIME wideo (video/*
) lub typem MIMEapplication/octet-stream
.
Poniższy przykład pokazuje, jak zainicjować sesję z możliwością wznowienia w celu przesłania filmu. Żądanie ustawia (i pobiera) właściwości w częściach snippet
i status
zasobu video
, a także pobiera właściwości w 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
Ten przykład pokazuje żądanie POST z wszystkimi wypełnionymi wartościami z wyjątkiem tokena uwierzytelniania. Wartość categoryId
w tym 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, którą można wznowić
Jeśli żądanie zakończy się powodzeniem, serwer interfejsu API odpowie kodem stanu HTTP 200
(OK
), a w odpowiedzi znajdzie się nagłówek HTTP Location
, który określa adres URI sesji z możliwością wznowienia. To jest adres URI, którego użyjesz do przesłania pliku wideo.
Przykład poniżej pokazuje przykładową odpowiedź interfejsu API na żądanie z 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ć do tej lokalizacji rzeczywistą zawartość pliku wideo. Treść żądania to zawartość pliku binarnego filmu, który przesyłasz. 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 to ustawia te nagłówki żądania HTTP:
Authorization
– token autoryzacji żądania.Content-Length
– rozmiar przesyłanego pliku. Ta wartość powinna być taka sama jak wartość nagłówka żądania HTTPX-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 HTTPX-Upload-Content-Type
w kroku 1.
Krok 4. Dokończ proces przesyłania
Twoja prośba spowoduje jeden z tych scenariuszy:
-
Przesłanie zostało zakończone.
Serwer interfejsu API odpowiada kodem odpowiedzi HTTP
201
(Created
). Treść odpowiedzi to utworzony przez Ciebie zasóbvideo
. -
Przesłanie nie powiodło się, ale można je wznowić.
Przesyłanie możesz wznowić w jednym z tych przypadków:
-
Twoje żądanie zostało przerwane, ponieważ połączenie między aplikacją a serwerem interfejsu API zostało utracone. W takim przypadku nie otrzymasz odpowiedzi API.
-
Odpowiedź interfejsu API zawiera jeden z tych kodów odpowiedzi:
5xx
. Gdy po otrzymaniu któregokolwiek z tych kodów odpowiedzi wznowisz przesyłanie, Twój kod powinien używać strategii wzrastającego czasu do ponowienia.500
–Internal Server Error
502
–Bad Gateway
503
–Service Unavailable
504
–Gateway Timeout
Aby wznowić przesyłanie, wykonaj instrukcje sprawdzania stanu przesyłania i wznawiania przesyłania. Pamiętaj, że każdy adres URI sesji z możliwością wznowienia ma ograniczony czas trwania i ostatecznie wygasa. Dlatego zalecamy rozpoczęcie przerywanego przesyłania zaraz po uzyskaniu identyfikatora URI sesji i wznowienie przerwanego przesyłania zaraz po przerwaniu.
-
-
Przesłanie nie powiodło się na stałe.
W przypadku nieudanego przesyłania odpowiedź zawiera odpowiedź na błąd, która wyjaśnia przyczynę niepowodzenia. W przypadku trwałego niepowodzenia przesyłania odpowiedź interfejsu API będzie zawierać kod odpowiedzi
4xx
lub5xx
inny niż wymienione powyżej.Jeśli wyślesz żądanie z identyfikatorem URI sesji, której ważność wygasła, serwer zwróci kod odpowiedzi HTTP
404
(Not Found
). W tym przypadku musisz rozpocząć nowe przesyłanie z możliwością wznowienia, uzyskać nowy identyfikator URI sesji i rozpocząć przesyłanie od początku, używając nowego identyfikatora URI.
Krok 4.1. Sprawdź stan przesyłania
Aby sprawdzić stan przerwanego przesyłania, które można wznowić, wyślij puste żądanie PUT do adresu URL przesyłania, który został pobrany w kroku 2 i 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
Jeśli przesyłanie zostało już zakończone, niezależnie od tego, czy było udane, interfejs API zwróci tę samą odpowiedź, którą wysłał podczas pierwotnego przesyłania.
Jeśli jednak przesyłanie zostało przerwane lub jest nadal w toku, odpowiedź interfejsu API będzie miała kod odpowiedzi HTTP 308
(Resume Incomplete
). W odpowiedzi nagłówek Range
określa, ile bajtów pliku zostało już przesłanych.
- Wartość nagłówka jest indeksowana od
0
. Wartość nagłówka0-999999
wskazuje, że przesłano pierwsze1,000,000
bajtów pliku. - Jeśli nic nie zostało jeszcze przesłane, odpowiedź interfejsu API nie będzie zawierać nagłówka
Range
.
Przykładowa odpowiedź poniżej pokazuje format odpowiedzi interfejsu API dla przerywanego przesyłania:
308 Resume Incomplete Content-Length: 0 Range: bytes=0-999999
Jeśli odpowiedź interfejsu API zawiera też nagłówek Retry-After
, użyj jego wartości, aby określić, kiedy spróbować wznowić przesyłanie.
Krok 4.3. Wznów przesyłanie
Aby wznowić przesyłanie, wyślij kolejne żądanie PUT
na adres URL przesyłania danych zarejestrowany w kroku 2. Ustaw treść żądania na kod binarny dla 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) treści, które nie zostały jeszcze przesłane. Jeśli przesyłasz pozostałą część pliku, możesz obliczyć tę wartość, odejmując wartośćFIRST_BYTE
od wartościTOTAL_CONTENT_LENGTH
. Obie wartości są używane w nagłówkuContent-Range
. -
Content-Range
– część pliku, który przesyłasz. Wartość nagłówka składa się z 3 wartości:-
FIRST_BYTE
– liczony od 0 indeks bajtu, od którego wznawiasz przesyłanie. Ta wartość jest o jedną większą od drugiej liczby w nagłówkuRange
pobranym w poprzednim kroku. W poprzednim przykładzie wartość nagłówkaRange
wynosiła0-999999
, więc pierwszy bajt w kolejne wznowione przesyłanie będzie miał wartość1000000
. -
LAST_BYTE
– liczony od 0 numeryczny indeks ostatniego bajtu przesyłanego pliku binarnego. Zwykle jest to ostatni bajt w pliku. Jeśli na przykład rozmiar pliku to3000000
bajtów, ostatni bajt w pliku będzie miał numer2999999
. -
TOTAL_CONTENT_LENGTH
– łączny rozmiar pliku wideo w bajtach. Ta wartość jest taka sama jak nagłówekContent-Length
podany w pierwotnym żądaniu przesłania.
Uwaga: nie możesz przesłać nieciągłego bloku pliku binarnego. Jeśli spróbujesz przesłać blok nieciągły, nie zostanie przesłana żadna pozostała zawartość binarna.
W związku z tym pierwszy bajt przesłany podczas wznawianego przesyłania musi być następnym bajtem po ostatnim bajcie, który został już przesłany do YouTube. (patrz omówienie nagłówkaRange
w kroku 4.2).
Jeśli więc ostatni bajt w nagłówkuRange
to999999
, pierwszy bajt w żądaniu wznowienia przesyłania musi być równy 1000000. (oba numery używają indeksu o wartości 0). Jeśli spróbujesz wznowić przesyłanie od bajtu 999999 lub niższego (nakładające się bajty) albo od bajtu 1000001 lub wyższego (przeskakiwanie bajtów), żadna część danych binarnych nie zostanie przesłana. -
Przesyłanie pliku w częściach
Zamiast próby przesłania całego pliku i wznowienia przesyłania w przypadku przerwy w działaniu sieci aplikacja może podzielić plik na części i wysłać serię próśb o przesłanie tych części kolejno. Takie podejście jest rzadko konieczne i nie zalecamy go, ponieważ wymaga dodatkowych żądań, które mają wpływ na wydajność. Może to być jednak przydatne, jeśli chcesz wyświetlić wskaźnik postępu w bardzo niestabilnej sieci.
Instrukcje przesyłania pliku w kawałkach są prawie 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łówków Content-Length
i Content-Range
inaczej, gdy plik jest przesyłany w kawałkach.
-
Wartość nagłówka
Content-Length
określa rozmiar fragmentu, który jest wysyłany w ramach żądania. Pamiętaj o tych ograniczeniach dotyczących rozmiarów fragmentów:-
Rozmiar fragmentu musi być wielokrotnością 256 KB. (To ograniczenie nie dotyczy ostatniego fragmentu, ponieważ rozmiar całego pliku może nie być wielokrotnością 256 KB). Pamiętaj, że większe fragmenty są bardziej wydajne.
-
Rozmiar części musi być taki sam w przypadku każdego żądania w sekwencji przesyłania, z wyjątkiem ostatniego żądania, które określa rozmiar ostatniej części.
-
-
Nagłówek
Content-Range
określa bajty w pliku, który żądanie przesyła. Podczas ustawiania tej wartości obowiązują instrukcje dotyczące ustawiania nagłówkaContent-Range
podane w kroku 4.3.Wartość
bytes 0-524287/2000000
oznacza na przykład, że żądanie wysyła pierwsze 524 288 bajtów (256 x 2048) z pliku o rozmiarze 2 000 000 bajtów.
Przykład poniżej pokazuje format pierwszego z serii żądań, które prześlą plik o długości 2 000 000 bajtów w porcjach:
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 kodem 308
(Resume Incomplete
). Format odpowiedzi będzie taki sam jak w kroku 4.2: Przetwarzanie odpowiedzi interfejsu API.
Aby określić, gdzie ma się zacząć kolejny fragment, użyj górnej wartości zwróconej w nagłówku Range
odpowiedzi interfejsu API. Kontynuuj wysyłanie żądań PUT
, jak opisano w sekcji Krok 4.3. Wznów przesyłanie, aby przesłać kolejne fragmenty pliku, aż do przesłania całego pliku.
Gdy cały plik zostanie przesłany, serwer odpowie kodem odpowiedzi HTTP 201
(Created
) i zwróci żądane części nowo utworzonego zasobu wideo.
Jeśli żądanie zostanie przerwane lub aplikacja otrzyma kod odpowiedzi 5xx
, wykonaj czynności opisane w kroku 4, aby dokończyć przesyłanie. Zamiast próbować przesłać resztę pliku, kontynuuj przesyłanie fragmentów od miejsca, w którym zostało przerwane. Aby dowiedzieć się, gdzie wznowić przesyłanie pliku, sprawdź jego stan. 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. (przesyłanie nie musi być przerwane, aby można było pobrać jego stan).