Você pode fazer upload de vídeos de forma mais confiável utilizando o protocolo de upload retomável para APIs do Google. Este protocolo permite retomar uma operação de upload após uma interrupção da rede ou outra falha de transmissão, economizando tempo e largura de banda em caso de falhas na rede.
Usar uploads retomáveis é especialmente útil em um dos seguintes casos:
- Você está transferindo arquivos grandes.
- A probabilidade de uma interrupção de rede é elevada.
- Uploads provenientes de um dispositivo com baixa largura de banda ou conexão de internet instável, como um dispositivo móvel.
Este guia explica a sequência de solicitações HTTP que um aplicativo faz para fazer upload de vídeos utilizando um processo de upload retomável. Destina-se primariamente a desenvolvedores que não conseguem utilizar as bibliotecas de clientes de API do Google, algumas das quais oferecem suporte nativo para a retomada de envios. O guia API Data do YouTube: como fazer o upload de um vídeo explica como usar a biblioteca de cliente das APIs do Google para Python para fazer o upload de um vídeo usando um processo de upload interrompível.
Observação: você também pode ver a série de solicitações feitas para os uploads retomáveis ou qualquer outra operação de API usando uma das bibliotecas de cliente API do Google com registro HTTPS ativado. Por exemplo, para ativar o rastreamento HTTP para Python, use a biblioteca httplib2
:
httplib2.debuglevel = 4
Passo 1 - Iniciar uma sessão retomável
Para iniciar um upload de vídeo retomável, envie uma solicitação POST para o URL a seguir. No URL, defina o valor do parâmetro part
como o valor adequado para sua solicitação. O valor do parâmetro identifica as partes que contêm as propriedades que você está definindo e também as partes que você quer que a resposta da API inclua. Os valores dos parâmetros no URL da solicitação precisam ser codificados para uso em URLs.
https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=PARTS
Defina o corpo da solicitação como um recurso video
. Defina também os seguintes cabeçalhos de solicitação HTTP:
Authorization
: o token de autorização da solicitação.Content-Length
: o número de bytes fornecidos no corpo da solicitação. Não é necessário fornecer esse cabeçalho se você estiver usando a codificação de transferência em partes.Content-Type
: defina o valor comoapplication/json; charset=UTF-8
.X-Upload-Content-Length
: o número de bytes que serão enviados em solicitações subsequentes. Defina este valor para o tamanho do arquivo que você está enviando.x-upload-content-type
: o tipo MIME do arquivo que você está fazendo upload. É possível fazer upload de arquivos com qualquer tipo MIME de vídeo (video/*
) ou um tipo MIME deapplication/octet-stream
.
O exemplo a seguir mostra como iniciar uma sessão retomável para enviar um vídeo. A solicitação define (e recupera) propriedades nas partes snippet
e status
do recurso video
e também recupera propriedades na parte contentdetails
do recurso.
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
O exemplo a seguir mostra uma solicitação POST com todos esses valores preenchidos, exceto o token de autenticação. O valor categoryId
no exemplo corresponde a uma categoria de vídeo. A lista de categorias compatíveis pode ser recuperada usando o método videoCategories.list
da 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" } }
Passo 2 - Salvar o URI da sessão retomável
Se a solicitação for bem-sucedida, o servidor da API vai responder com um código de status HTTP 200
(OK
) e a resposta vai incluir um cabeçalho HTTP Location
que especifica o URI da sessão interrompível. Esse é o URI que você usará para fazer o upload de seu arquivo de vídeo.
O exemplo abaixo mostra um exemplo de resposta de API para a solicitação no passo 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
Passo 3 - Upload do arquivo de vídeo
Depois de extrair o URI de sessão da resposta da API, você precisará fazer upload do conteúdo do arquivo de vídeo real para esse local. O corpo da solicitação é o conteúdo do arquivo binário para o vídeo que você está carregando. O exemplo abaixo mostra o formato da solicitação.
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: CONTENT_LENGTH Content-Type: CONTENT_TYPE BINARY_FILE_DATA
A solicitação define os seguintes cabeçalhos de solicitação HTTP:
Authorization
: o token de autorização da solicitação.Content-Length
: o tamanho do arquivo que você está enviando. Esse valor precisa ser igual ao do cabeçalho de solicitação HTTPX-Upload-Content-Length
na etapa 1.Content-Type
: o tipo MIME do arquivo que você está enviando. Esse valor precisa ser igual ao do cabeçalho de solicitação HTTPX-Upload-Content-Type
na etapa 1.
Passo 4 - Concluir o processo de upload
Sua solicitação levará a um dos seguintes cenários:
-
O upload foi concluído.
O servidor da API responde com um código de resposta HTTP
201
(Created
). O corpo da resposta é o recursovideo
que você criou. -
O upload não foi concluído, mas pode ser retomado.
Você conseguirá retomar um upload em um dos seguintes casos:
-
Sua solicitação é interrompida porque a conexão entre seu aplicativo e o servidor de API está perdida. Neste caso, você não receberá uma resposta da API.
-
A resposta da API especifica qualquer um dos seguintes códigos de resposta
5xx
. O código precisa usar uma estratégia de espera exponencial ao retomar os uploads após receber qualquer um desses códigos de resposta.500
aInternal Server Error
502
aBad Gateway
503
aService Unavailable
504
aGateway Timeout
Para retomar um upload, siga as instruções para verificar o status do upload e retomar um upload abaixo. Lembre-se de que cada URI de sessão retomável tem uma vida finita e expira. Por isso, recomendamos iniciar um upload retomável assim que você receber o URI de sessão e retomar um upload interrompido logo após a interrupção.
-
-
Houve uma falha permanente no upload.
Para uma falha de upload, a resposta contém uma resposta de erro que ajuda a explicar a causa da falha. Para um upload que falhar permanentemente, a resposta da API terá um código de resposta
4xx
ou5xx
diferente dos listados acima.Se você enviar uma solicitação com um URI de sessão expirado, o servidor vai retornar um código de resposta HTTP
404
(Not Found
). Nesse caso, será necessário iniciar um novo upload retomável, conseguir um novo URI de sessão e iniciar o upload desde o início usando o novo URI.
Passo 4.1: verificar o status de um upload
Para verificar o status de um upload retomável interrompido, envie uma solicitação PUT vazia para o URL de upload que você extraiu na etapa 2 e também usou na etapa 3. Na solicitação, defina o valor do cabeçalho Content-Range
como bytes */CONTENT_LENGTH
, em que CONTENT_LENGTH é o tamanho do arquivo que você está enviando.
PUT UPLOAD_URL HTTP/1.1 Authorization: Bearer AUTH_TOKEN Content-Length: 0 Content-Range: bytes */CONTENT_LENGTH
Passo 4.2: processar a resposta da API
Se o upload já foi concluído, independentemente de ter sido bem-sucedido ou ter falhado, a API retornará a mesma resposta enviada quando o upload foi originalmente concluído.
No entanto, se o upload foi interrompido ou ainda está em andamento, a resposta da API terá um código de resposta HTTP 308
(Resume Incomplete
). Na resposta, o cabeçalho Range
especifica quantos bytes do arquivo já foram enviados.
- O valor do cabeçalho é indexado a partir de
0
Assim, um valor de cabeçalho de0-999999
indica que os primeiros1,000,000
bytes do arquivo foram enviados. - Se nada tiver sido enviado, a resposta da API não vai incluir o cabeçalho
Range
.
A resposta de exemplo abaixo mostra o formato de uma resposta da API para um upload retomável:
308 Resume Incomplete Content-Length: 0 Range: bytes=0-999999
Se a resposta da API também incluir o cabeçalho Retry-After
, use o valor desse cabeçalho para determinar quando tentar retomar o upload.
Passo 4.3: retomar o upload
Para retomar o upload, envie outra solicitação PUT
para o URL de upload capturado no passo 2. Defina o corpo da solicitação para o código binário para a parte do arquivo de vídeo que ainda não foi enviada.
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
Você precisa definir os seguintes cabeçalhos de solicitação HTTP:
-
Authorization
: o token de autorização da solicitação. -
Content-Length
: o tamanho, em bytes, do conteúdo que ainda não foi enviado. Se você estiver fazendo o upload do restante de um arquivo, poderá calcular esse valor subtraindo o valor deFIRST_BYTE
do valor deTOTAL_CONTENT_LENGTH
. Ambos os valores são usados no cabeçalhoContent-Range
. -
Content-Range
: a parte do arquivo que você está enviando. O valor do cabeçalho é composto por três valores:-
FIRST_BYTE
- O índice numérico baseado em 0 do número de bytes a partir do qual você está retomando o upload. Esse valor é um número maior que o segundo número no cabeçalhoRange
recuperado na etapa anterior. No exemplo anterior, o valor do cabeçalhoRange
era0-999999
. Portanto, o primeiro byte em um upload retomado subsequente seria1000000
. -
LAST_BYTE
- O índice numérico baseado em 0 do último byte do arquivo binário que você estiver enviando. Normalmente, este é o último byte no arquivo. Por exemplo, se o tamanho do arquivo for3000000
bytes, o último byte no arquivo será o número2999999
. -
TOTAL_CONTENT_LENGTH
- O tamanho total do arquivo de vídeo em bytes. Esse valor é igual ao cabeçalhoContent-Length
especificado na solicitação de upload original.
Observação: você não pode fazer upload de um bloco não contínuo do arquivo binário. Se você tentar fazer upload de um bloco não contínuo, nada do conteúdo binário restante será enviado.
Portanto, o primeiro byte enviado em um upload retomado precisa ser o próximo byte após o último que já foi enviado ao YouTube. Consulte a discussão sobre o cabeçalhoRange
na etapa 4.2.
Portanto, se o último byte no cabeçalhoRange
for999999
, o primeiro byte na solicitação para retomar o upload precisa ser o byte 1000000. (os dois números usam um índice baseado em 0). Se você tentar retomar o upload a partir do byte 999.999 ou inferior (sobrepondo bytes) ou a partir do byte 1.000.001 ou superior (pulando bytes), nenhum dos conteúdos binários será enviado. -
Fazer upload de um arquivo em partes
Em vez de tentar fazer upload de um arquivo inteiro e retomar o upload em caso de interrupção da rede, o aplicativo pode quebrar o arquivo em partes e enviar uma série de solicitações para fazer upload dessas partes em sequência. Esta abordagem raramente é necessária e, na realidade, não indicada, visto que ela requer solicitações adicionais, que têm implicações de desempenho. No entanto, ela pode ser útil se você estiver tentando exibir um indicador de progresso em uma rede muito instável.
As instruções para upload de um arquivo em partes são praticamente idênticas ao processo de quatro passos explicado anteriormente neste guia. No entanto, as solicitações para iniciar o upload de um arquivo (etapa 3 acima) e para retomar um upload (etapa 4.3 acima) definem os valores dos cabeçalhos Content-Length
e Content-Range
de maneira diferente quando um arquivo está sendo enviado em partes.
-
O valor do cabeçalho
Content-Length
especifica o tamanho do bloco que a solicitação está enviando. Observe as seguintes restrições sobre os tamanhos da parte:-
O tamanho do bloco precisa ser um múltiplo de 256 KB. Essa restrição não se aplica ao último fragmento, já que o tamanho do arquivo inteiro pode não ser um múltiplo de 256 KB. Lembre-se de que as partes maiores são mais eficientes.
-
O tamanho da parte deve ser igual para cada solicitação na sequência de upload, com exceção da última solicitação, que especifica o tamanho da parte final.
-
-
O cabeçalho
Content-Range
especifica os bytes no arquivo que a solicitação está enviando. As instruções para definir o cabeçalhoContent-Range
na etapa 4.3 são aplicáveis ao definir esse valor.Por exemplo, um valor de
bytes 0-524287/2000000
mostra que a solicitação está enviando os primeiros 524.288 bytes (256 x 2048) em um arquivo de 2.000.000 bytes.
O exemplo abaixo mostra o formato da primeira de uma série de solicitações que enviará um arquivo de 2.000.000 bytes em partes:
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}
Se uma solicitação diferente da final for bem-sucedida, o servidor da API vai responder com uma resposta 308
(Resume Incomplete
). O formato da resposta será o mesmo descrito na Etapa 4.2: processar a resposta da API acima.
Use o valor superior retornado no cabeçalho Range
da resposta da API para determinar onde iniciar a próxima parte. Continue a enviar solicitações PUT
, conforme descrito na Etapa 4.3: Retomar o upload, para fazer upload de partes de arquivo subsequentes até que o arquivo inteiro seja enviado.
Quando o upload do arquivo inteiro for concluído, o servidor vai responder com um código de resposta HTTP 201
(Created
) e retornar as partes solicitadas do recurso de vídeo recém-criado.
Se uma solicitação for interrompida ou se o app receber um código de resposta 5xx
, siga o procedimento explicado na etapa 4 para concluir o upload. Porém, em vez de tentar fazer upload do restante do arquivo, basta continuar fazendo upload das partes a partir do ponto em que você está retomando o upload. Use a verificação do status do upload para determinar em que ponto o upload do arquivo será retomado. Não pressuponha que o servidor recebeu todos os bytes (ou nenhum deles) enviados na solicitação anterior.
Observação: você também pode solicitar o status de um upload ativo entre partes carregadas (o upload não precisa ter sido interrompido para que você possa recuperar seu status).