Вы можете загружать видео более надежно, используя протокол возобновляемой загрузки для API Google. Этот протокол позволяет возобновить операцию загрузки после сбоя в сети или другого сбоя передачи, экономя время и пропускную способность в случае сбоев сети.
Использование возобновляемых загрузок особенно полезно в любом из следующих случаев:
- Вы передаете большие файлы.
- Вероятность прерывания работы сети высока.
- Загрузки происходят с устройства с низкой пропускной способностью или нестабильным подключением к Интернету, например с мобильного устройства.
В этом руководстве объясняется последовательность HTTP-запросов, которые приложение выполняет для загрузки видео с использованием возобновляемого процесса загрузки. Это руководство в первую очередь предназначено для разработчиков, которые не могут использовать клиентские библиотеки Google API , некоторые из которых предоставляют встроенную поддержку возобновляемых загрузок. Фактически, руководство по API данных YouTube — загрузка видео объясняет, как использовать клиентскую библиотеку Google API для Python для загрузки видео с помощью возобновляемого процесса загрузки.
Примечание. Вы также можете просмотреть серию запросов на возобновление загрузки или любую другую операцию API, используя одну из клиентских библиотек Google API с включенным ведением журнала HTTPS. Например, чтобы включить трассировку HTTP для Python, используйте библиотеку httplib2
:
httplib2.debuglevel = 4
Шаг 1. Запустите возобновляемый сеанс.
Чтобы начать возобновляемую загрузку видео, отправьте запрос POST по следующему URL-адресу. В 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/*
) или MIME-типомapplication/octet-stream
.
В следующем примере показано, как инициировать возобновляемый сеанс для загрузки видео. запрос устанавливает (и будет получать) свойства в частях snippet
и status
video
, а также получит свойства в части 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
в примере соответствует категории видео. Список поддерживаемых категорий можно получить с помощью метода videoCategories.list
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" } }
Шаг 2. Сохраните URI возобновляемого сеанса.
Если ваш запрос будет успешным, сервер API ответит кодом состояния HTTP 200
( OK
), а ответ будет включать HTTP-заголовок Location
, который указывает URI для возобновляемого сеанса. Это URI, который вы будете использовать для загрузки видеофайла.
В примере ниже показан пример ответа API на запрос на шаге 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
Шаг 3. Загрузите видеофайл.
После извлечения URI сеанса из ответа API вам необходимо загрузить фактическое содержимое видеофайла в это место. Тело запроса представляет собой содержимое двоичного файла загружаемого вами видео. В примере ниже показан формат запроса.
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
– размер загружаемого файла. Это значение должно быть таким же, как значение заголовка HTTP-запросаX-Upload-Content-Length
на шаге 1. -
Content-Type
– MIME-тип загружаемого файла. Это значение должно быть таким же, как значение заголовка HTTP-запросаX-Upload-Content-Type
на шаге 1.
Шаг 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 сеанса с истекшим сроком действия, сервер возвращает код ответа HTTP
404
(Not Found
). В этом случае вам потребуется начать новую возобновляемую загрузку, получить новый URI сеанса и начать загрузку с самого начала, используя новый URI.
Шаг 4.1. Проверьте статус загрузки
Чтобы проверить статус прерванной возобновляемой загрузки, отправьте пустой запрос PUT на URL-адрес загрузки, который вы получили на шаге 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
на URL-адрес загрузки, полученный на шаге 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
, полученном на предыдущем шаге. В предыдущем примере значение заголовкаRange
было0-999999
, поэтому первый байт в последующей возобновленной загрузке будет1000000
.LAST_BYTE
– числовой индекс последнего байта загружаемого двоичного файла, отсчитываемый от 0. Обычно это последний байт файла. Так, например, если размер файла составлял3000000
байт, последний байт в файле будет иметь номер2999999
.TOTAL_CONTENT_LENGTH
– общий размер видеофайла в байтах. Это значение совпадает с заголовкомContent-Length
указанным в исходном запросе на загрузку .
Примечание. Вы не можете загрузить прерывистый блок двоичного файла. Если вы попытаетесь загрузить прерывистый блок, оставшийся двоичный контент не будет загружен.
Таким образом, первый байт, загружаемый при возобновленной загрузке, должен быть следующим байтом после последнего байта, который уже был успешно загружен на YouTube. (См. обсуждение заголовкаRange
в шаге 4.2 .
Таким образом, если последний байт в заголовкеRange
—999999
, первый байт в запросе на возобновление загрузки должен быть байтом 1000000. (Оба числа используют индекс, начинающийся с 0.) Если вы попытаетесь возобновить загрузку с байта 999999 или меньше (перекрывающиеся байты) или байт 1000001 или выше (пропуск байтов), двоичный контент не будет загружен.
Загружать файл частями
Вместо того, чтобы пытаться загрузить весь файл и возобновлять загрузку в случае сбоя в сети, ваше приложение может разбить файл на фрагменты и отправить серию запросов для последовательной загрузки фрагментов. Этот подход редко бывает необходим и на самом деле не рекомендуется, поскольку требует дополнительных запросов, которые влияют на производительность. Однако это может быть полезно, если вы пытаетесь отобразить индикатор прогресса в очень нестабильной сети.
Инструкции по загрузке файла частями практически идентичны четырехэтапному процессу, описанному ранее в этом руководстве. Однако запросы на начало загрузки файла (шаг 3 выше) и на возобновление загрузки (шаг 4.3 выше) устанавливают значения заголовков Content-Length
и Content-Range
по-разному, когда файл загружается частями.
Значение заголовка
Content-Length
указывает размер фрагмента, отправляемого запросом. Обратите внимание на следующие ограничения на размеры блоков:Размер чанка должен быть кратен 256 КБ. (Это ограничение не распространяется на последний фрагмент, поскольку размер всего файла не может быть кратен 256 КБ.) Помните, что более крупные фрагменты более эффективны.
Размер фрагмента должен быть одинаковым для каждого запроса в последовательности загрузки, за исключением последнего запроса, который определяет размер окончательного фрагмента.
Заголовок
Content-Range
указывает байты в файле, который загружает запрос. Инструкции по настройке заголовкаContent-Range
на шаге 4.3 применимы при установке этого значения.Например, значение
bytes 0-524287/2000000
показывает, что запрос отправляет первые 524 288 байт (256 x 2048) в файле размером 2 000 000 байт.
В примере ниже показан формат первого из серии запросов, которые загружают файл размером 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 выше.
Используйте верхнее значение, возвращаемое в заголовке Range
ответа API, чтобы определить, с чего начать следующий фрагмент. Продолжайте отправлять запросы PUT
, как описано в шаге 4.3: Возобновление загрузки , чтобы загружать последующие фрагменты файла, пока не будет загружен весь файл.
Когда весь файл загружен, сервер отвечает кодом ответа HTTP 201
( Created
) и возвращает запрошенные части вновь созданного видеоресурса.
Если какой-либо запрос прерван или ваше приложение получает код ответа 5xx
, выполните процедуру, описанную в шаге 4, чтобы завершить загрузку. Однако вместо того, чтобы пытаться загрузить остальную часть файла, просто продолжайте загрузку фрагментов с того места, где вы возобновляете загрузку. Обязательно используйте проверку статуса загрузки, чтобы определить, где возобновить загрузку файла. Не предполагайте, что сервер получил все (или ни одного) байты, отправленные в предыдущем запросе.
Примечание. Вы также можете запросить статус активной загрузки между загруженными фрагментами. (Загрузка не обязательно должна быть прервана, прежде чем вы сможете узнать ее статус.)