Вы можете загружать видео более надежно, используя протокол возобновляемой загрузки для API Google. Этот протокол позволяет возобновить операцию загрузки после прерывания сети или другого сбоя передачи, экономя время и пропускную способность в случае сетевых сбоев.
Использование возобновляемых загрузок особенно полезно в любом из следующих случаев:
- Вы передаете большие файлы.
- Вероятность прерывания сети высока.
- Загрузки происходят с устройства с низкой пропускной способностью или нестабильным подключением к Интернету, например с мобильного устройства.
В этом руководстве объясняется последовательность HTTP-запросов, которые приложение делает для загрузки видео с помощью возобновляемого процесса загрузки. Это руководство в первую очередь предназначено для разработчиков, которые не могут использовать клиентские библиотеки Google API , некоторые из которых обеспечивают встроенную поддержку возобновляемой загрузки. На самом деле, YouTube Data API — Руководство по загрузке видео объясняет, как использовать клиентскую библиотеку API Google для Python для загрузки видео с помощью возобновляемого процесса загрузки.
Примечание. Вы также можете просмотреть серию запросов на возобновляемую загрузку или любую другую операцию API, используя одну из клиентских библиотек API Google с включенным ведением журнала 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
в примере соответствует категории видео. Список поддерживаемых категорий можно получить с помощью метода 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 ответит кодом состояния 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 , чтобы завершить загрузку. Однако вместо того, чтобы пытаться загрузить остальную часть файла, просто продолжайте загружать фрагменты с того места, где вы возобновляете загрузку. Обязательно используйте проверку статуса загрузки, чтобы определить, где возобновить загрузку файла. Не предполагайте, что сервер получил все (или ни одного) байты, отправленные в предыдущем запросе.
Примечание. Вы также можете запросить статус активной загрузки между загруженными чанками. (Загрузку не нужно прерывать, прежде чем вы сможете получить ее статус.)