Retomada de envios

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. Este guia destina-se principalmente para desenvolvedores que não podem usar as bibliotecas de cliente API do Google, algumas das quais oferecem suporte nativo para uploads retomáveis. Na verdade, o guia API de dados do YouTube - upload de um vídeo explica como usar a Biblioteca do Cliente de APIs do Google para Python para fazer upload de um vídeo usando um processo de upload retomável.

Nota: 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 permitir o rastreamento de 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 POST request to the following URL. In the URL, set the part parameter value to the appropriate value for your request. Remember that the parameter value identifies the parts the contain properties that you are setting, and it also identifies the parts that you want the API response to include. Parameter values in the request URL must be URL-encoded.

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

Defina o corpo da solicitação para um recurso de video. Defina também os seguintes cabeçalhos de solicitação HTTP:

  • Authorization - O token de autorização para a solicitação.
  • Content-Length - O número de bytes fornecido no corpo da solicitação. Observe que você não precisa fornecer este cabeçalho se estiver usando a codificação de transferência por partes.
  • Content-Type - Defina o valor como application/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á enviando. Você pode fazer upload de arquivos com qualquer tipo MIME de vídeo (video/*) ou um tipo MIME de application/octet-stream.

O exemplo a seguir mostra como iniciar uma sessão retomável para fazer upload de um vídeo. A solicitação define (e recuperará) propriedades no video do recurso do snippet e partes do status e também recuperará 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 de POST que tem todos esses valores preenchidos, com exceção do token de autenticação. O valor de categoryId no exemplo corresponde a uma categoria de vídeo. A lista de categorias suportadas 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 sua solicitação for bem-sucedida, o servidor API responderá com um código de status HTTP 200 (OK), e a resposta incluirá um cabeçalho HTTP de Location que especifica o URI para a sessão retomá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 para a solicitação.
  • Content-Length - O tamanho do arquivo que você está enviando. Este valor deve ser igual ao valor do cabeçalho da solicitação HTTP X-Upload-Content-Length no passo 1.
  • Content-Type - O tipo MIME do arquivo que você está enviando. Este valor deve ser igual ao valor do cabeçalho da solicitação HTTP X-Upload-Content-Type no passo 1.

Passo 4 - Concluir o processo de upload

Sua solicitação levará a um dos seguintes cenários:

  • Seu upload foi bem-sucedido.

    O servidor de API responde com código de resposta de HTTP 201 (Created). O corpo da resposta é o recurso de vídeo video que você criou.

  • Seu upload não foi bem-sucedido, 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 5xx códigos de resposta a seguir. Seu código deve usar uma estratégia de backoff exponencial ao retomar uploads depois de receber qualquer um desses códigos de resposta.

      • 500Internal Server Error
      • 502Bad Gateway
      • 503Service Unavailable
      • 504Gateway 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.

  • Seu upload falhou permanentemente.

    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 falha de forma permanente, a resposta da API terá um código de resposta 4xx ou um código de resposta 5xx diferentes dos listados acima.

    Se você enviar uma solicitação com um URI de sessão expirada, o servidor retornará um código de resposta HTTP 404 (Not Found). Neste caso, você precisará iniciar um novo upload retomável, obter um novo URI de sessão e iniciar o upload desde o início usando o URI novo.

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ê recuperou no passo 2 e também usou no passo 3. Em sua 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 com sucesso.

  • O valor do cabeçalho é indexado a partir de {0/}. Como tal, um valor de cabeçalho de 0-999999 indica que os primeiros 1.000.000 bytes do arquivo foram enviados.
  • Se nada ainda foi enviado, a resposta da API não 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 para a solicitação.

  • Content-Length - O tamanho, em bytes, do conteúdo que ainda não foi enviado. Se você estiver fazendo upload do restante de um arquivo, poderá calcular esse valor, subtraindo o valor FIRST_BYTE do valor TOTAL_CONTENT_LENGTH. Ambos os valores são usados ​​no cabeçalho Content-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. Este valor é um número maior que o segundo número no cabeçalho Range recuperado no passo anterior. No exemplo anterior, o valor do cabeçalho Range era 0-999999, portanto, o primeiro byte em um próximo upload retomado seria 1000000.

    • 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. Assim, por exemplo, se o tamanho do arquivo era 3000000 bytes, o último byte no arquivo seria o número 2999999.

    • TOTAL_CONTENT_LENGTH - O tamanho total do arquivo de vídeo em bytes. Este valor é igual ao cabeçalho Content-Length especificado na solicitação de upload original.

    Nota: 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.

    Como tal, o primeiro byte enviado em um upload retomado deve ser o próximo byte após o último byte que já tinha sido enviado com sucesso para o YouTube (veja a discussão do cabeçalho Range no passo 4.2).

    Assim, se o último byte no cabeçalho Range for 999999, o primeiro byte na solicitação para retomar o upload deverá ser o byte 1.000.000 (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.

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 (passo 3 acima) e retomar um upload (passo 4.3 acima) definem os valores de cabeçalho Content-Length e Content-Range de forma diferente quando um arquivo está sendo enviado em partes.

  • O valor de cabeçalho Content-Length especifica o tamanho da parte que a solicitação está enviando. Observe as seguintes restrições sobre os tamanhos da parte:

    • O tamanho da parte deve ser um múltiplo de 256 KB.(Esta restrição não se aplica à última parte, 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 configurar o cabeçalho Content-Range no passo 4.3 são aplicáveis durante a configuração deste valor.

    Por exemplo, um valor de bytes 0-524287/2000000 mostra que a solicitação está enviando os primeiros 524.288 bytes (256 x 2.048) 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 outra solicitação que não seja a última for bem-sucedida, o servidor responderá com uma resposta 308 (Resume Incomplete). O formato da resposta será igual ao descrito no Passo 4.2: Processar a resposta da API acima.

Use o valor superior retornado no cabeçalho Range da resposta da API para determinar onde começar a próxima parte. Continue a enviar solicitações PUT, conforme descrito no Passo 4.3: Retomar o upload, para fazer upload de partes de arquivos subsequentes até que todo o arquivo seja enviado.

Quando todo o arquivo for carregado, o servidor responderá com um código de resposta HTTP 201 (Created) e retornará as partes solicitadas do recurso de vídeo recém-criado.

Se alguma solicitação for interrompida ou seu aplicativo receber algum código de resposta 5xx, siga o procedimento explicado no passo 4 para concluir o carregamento. 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.

Nota: 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).