Videos: insert

Todos os vídeos enviados por meio do endpoint videos.insert de projetos de API não verificados criados após 28 de julho de 2020 serão restritos ao modo de visualização particular. Para remover essa restrição, cada projeto de API precisa passar por uma auditoria para verificar a conformidade com os Termos de Serviço. Consulte o histórico de revisões da API para mais detalhes.

Envia um vídeo para o YouTube e, opcionalmente, define os metadados do vídeo.

Este método oferece suporte ao envio de mídia. Os arquivos enviados devem estar de acordo com estas restrições:

  • Tamanho máximo do arquivo:256 GB
  • Tipos MIME de mídia aceitos: video/*, application/octet-stream

Impacto na cota:uma chamada para esse método tem um custo de cota de 1.600 unidades.

Casos de uso comuns

Solicitação

Solicitação HTTP

POST https://www.googleapis.com/upload/youtube/v3/videos

Autorização

Esta solicitação requer autorização com pelo menos um dos seguintes escopos (leia mais sobre autenticação e autorização).

Escopo
https://www.googleapis.com/auth/youtube.upload
https://www.googleapis.com/auth/youtube
https://www.googleapis.com/auth/youtubepartner
https://www.googleapis.com/auth/youtube.force-ssl

Parâmetros

A tabela a seguir lista os parâmetros compatíveis com essa consulta. Todos os parâmetros listados são os parâmetros de consulta.

Parâmetros
Parâmetros obrigatórios
part string
O parâmetro part tem duas finalidades nesta operação. Ele identifica as propriedades que a operação de gravação definirá, bem como as que a resposta da API incluirá.

Nem todas as partes contêm propriedades que podem ser definidas ao inserir ou atualizar um vídeo. Por exemplo, o objeto statistics encapsula estatísticas que o YouTube calcula para um vídeo e não contém valores que podem ser definidos ou modificados. Se o valor do parâmetro especificar um part que não contenha valores mutáveis, esse part ainda será incluído na resposta da API.

A lista a seguir contém os nomes de part que podem ser incluídos no valor do parâmetro:
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
Parâmetros opcionais
notifySubscribers boolean
O parâmetro notifySubscribers indica se o YouTube enviará uma notificação sobre o novo vídeo aos usuários que se inscreverem no canal do vídeo. Um valor de parâmetro de True indica que os inscritos serão notificados sobre os vídeos enviados recentemente. No entanto, um proprietário de canal que envia muitos vídeos pode preferir definir o valor como False para evitar o envio de uma notificação sobre cada vídeo novo aos inscritos do canal. O valor padrão é True.
onBehalfOfContentOwner string
Esse parâmetro só pode ser usado em uma solicitação autorizada corretamente. Observação:esse parâmetro é destinado exclusivamente a parceiros de conteúdo do YouTube.

O parâmetro onBehalfOfContentOwner indica que as credenciais de autorização da solicitação identificam um usuário do CMS do YouTube que atua em nome do proprietário do conteúdo especificado no valor do parâmetro. Este parâmetro destina-se a parceiros de conteúdo do YouTube que possuem e gerenciam vários canais do YouTube diferentes. Ele permite que os proprietários de conteúdo autentiquem uma vez e tenham acesso a todos os dados de seu canal e de seus vídeos sem ter que fornecer credenciais de autenticação para cada canal. A conta do CMS com a qual o usuário autentica deve estar vinculada ao proprietário do conteúdo do YouTube especificado.
onBehalfOfContentOwnerChannel string
Esse parâmetro só pode ser usado em uma solicitação autorizada corretamente. Esse parâmetro só pode ser usado em uma solicitação autorizada adequadamente. Observação: esse parâmetro é destinado exclusivamente a parceiros de conteúdo do YouTube.

O parâmetro onBehalfOfContentOwnerChannel especifica o ID do canal do YouTube ao qual um vídeo está sendo adicionado. Esse parâmetro é necessário quando uma solicitação especifica um valor para o parâmetro onBehalfOfContentOwner e só pode ser usado com ele. Além disso, a solicitação precisa ser autorizada usando uma conta do CMS vinculada ao proprietário do conteúdo especificado pelo parâmetro onBehalfOfContentOwner. Por fim, o canal especificado pelo valor do parâmetro onBehalfOfContentOwnerChannel precisa estar vinculado ao proprietário do conteúdo especificado pelo parâmetro onBehalfOfContentOwner.

Este parâmetro é destinado a parceiros de conteúdo do YouTube que têm e gerenciam muitos canais diferentes. Ele permite que os proprietários do conteúdo autentiquem uma vez e executem ações em nome do canal especificado no valor do parâmetro sem ter que fornecer credenciais de autenticação para cada canal separado.

Corpo da solicitação

Fornecer um recurso de vídeo no corpo da solicitação. Para esse recurso:

  • Você pode definir valores para estas propriedades:

    • snippet.title
    • snippet.description
    • snippet.tags[]
    • snippet.categoryId
    • snippet.defaultLanguage
    • localizations.(key)
    • localizations.(key).title
    • localizations.(key).description
    • status.embeddable
    • status.license
    • status.privacyStatus
    • status.publicStatsViewable
    • status.publishAt
    • status.selfDeclaredMadeForKids
    • recordingDetails.locationDescription (descontinuado)
    • recordingDetails.location.latitude (descontinuado)
    • recordingDetails.location.longitude (descontinuado)
    • recordingDetails.recordingDate

Resposta

Se for bem sucedido, este método retorna um recurso de vídeo no corpo da resposta.

Exemplos

Observação: as amostras de código a seguir podem não representar todas as linguagens de programação compatíveis. Consulte a documentação bibliotecas clientes para uma lista das linguagens suportadas.

Go

Este exemplo de código chama o método videos.insert da API para fazer upload de um vídeo no canal associado à solicitação.

Este exemplo usa a biblioteca de cliente Go.

package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"

	"google.golang.org/api/youtube/v3"
)

var (
	filename    = flag.String("filename", "", "Name of video file to upload")
	title       = flag.String("title", "Test Title", "Video title")
	description = flag.String("description", "Test Description", "Video description")
	category    = flag.String("category", "22", "Video category")
	keywords    = flag.String("keywords", "", "Comma separated list of video keywords")
	privacy     = flag.String("privacy", "unlisted", "Video privacy status")
)

func main() {
	flag.Parse()

	if *filename == "" {
		log.Fatalf("You must provide a filename of a video file to upload")
	}

	client := getClient(youtube.YoutubeUploadScope)

	service, err := youtube.New(client)
	if err != nil {
		log.Fatalf("Error creating YouTube client: %v", err)
	}

	upload := &youtube.Video{
		Snippet: &youtube.VideoSnippet{
			Title:       *title,
			Description: *description,
			CategoryId:  *category,
		},
		Status: &youtube.VideoStatus{PrivacyStatus: *privacy},
	}

	// The API returns a 400 Bad Request response if tags is an empty string.
	if strings.Trim(*keywords, "") != "" {
		upload.Snippet.Tags = strings.Split(*keywords, ",")
	}

	call := service.Videos.Insert("snippet,status", upload)

	file, err := os.Open(*filename)
	defer file.Close()
	if err != nil {
		log.Fatalf("Error opening %v: %v", *filename, err)
	}

	response, err := call.Media(file).Do()
	handleError(err, "")
	fmt.Printf("Upload successful! Video ID: %v\n", response.Id)
}

.NET

O exemplo de código a seguir chama o método videos.insert da API para fazer upload de um vídeo no canal associado à solicitação.

Este exemplo usa a biblioteca cliente .NET.

using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;

namespace Google.Apis.YouTube.Samples
{
  /// <summary>
  /// YouTube Data API v3 sample: upload a video.
  /// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher.
  /// See https://developers.google.com/api-client-library/dotnet/get_started
  /// </summary>
  internal class UploadVideo
  {
    [STAThread]
    static void Main(string[] args)
    {
      Console.WriteLine("YouTube Data API: Upload Video");
      Console.WriteLine("==============================");

      try
      {
        new UploadVideo().Run().Wait();
      }
      catch (AggregateException ex)
      {
        foreach (var e in ex.InnerExceptions)
        {
          Console.WriteLine("Error: " + e.Message);
        }
      }

      Console.WriteLine("Press any key to continue...");
      Console.ReadKey();
    }

    private async Task Run()
    {
      UserCredential credential;
      using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
      {
        credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
            GoogleClientSecrets.Load(stream).Secrets,
            // This OAuth 2.0 access scope allows an application to upload files to the
            // authenticated user's YouTube channel, but doesn't allow other types of access.
            new[] { YouTubeService.Scope.YoutubeUpload },
            "user",
            CancellationToken.None
        );
      }

      var youtubeService = new YouTubeService(new BaseClientService.Initializer()
      {
        HttpClientInitializer = credential,
        ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
      });

      var video = new Video();
      video.Snippet = new VideoSnippet();
      video.Snippet.Title = "Default Video Title";
      video.Snippet.Description = "Default Video Description";
      video.Snippet.Tags = new string[] { "tag1", "tag2" };
      video.Snippet.CategoryId = "22"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
      video.Status = new VideoStatus();
      video.Status.PrivacyStatus = "unlisted"; // or "private" or "public"
      var filePath = @"REPLACE_ME.mp4"; // Replace with path to actual movie file.

      using (var fileStream = new FileStream(filePath, FileMode.Open))
      {
        var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*");
        videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged;
        videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived;

        await videosInsertRequest.UploadAsync();
      }
    }

    void videosInsertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress progress)
    {
      switch (progress.Status)
      {
        case UploadStatus.Uploading:
          Console.WriteLine("{0} bytes sent.", progress.BytesSent);
          break;

        case UploadStatus.Failed:
          Console.WriteLine("An error prevented the upload from completing.\n{0}", progress.Exception);
          break;
      }
    }

    void videosInsertRequest_ResponseReceived(Video video)
    {
      Console.WriteLine("Video id '{0}' was successfully uploaded.", video.Id);
    }
  }
}

Ruby

Este exemplo chama o método videos.insert da API para fazer upload de um vídeo no canal associado à solicitação.

Este exemplo utiliza a biblioteca cliente Ruby.

#!/usr/bin/ruby

require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'google/api_client/auth/installed_app'
require 'trollop'

# A limited OAuth 2 access scope that allows for uploading files, but not other
# types of account access.
YOUTUBE_UPLOAD_SCOPE = 'https://www.googleapis.com/auth/youtube.upload'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'

def get_authenticated_service
  client = Google::APIClient.new(
    :application_name => $PROGRAM_NAME,
    :application_version => '1.0.0'
  )
  youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)

  file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
  if file_storage.authorization.nil?
    client_secrets = Google::APIClient::ClientSecrets.load
    flow = Google::APIClient::InstalledAppFlow.new(
      :client_id => client_secrets.client_id,
      :client_secret => client_secrets.client_secret,
      :scope => [YOUTUBE_UPLOAD_SCOPE]
    )
    client.authorization = flow.authorize(file_storage)
  else
    client.authorization = file_storage.authorization
  end

  return client, youtube
end

def main
  opts = Trollop::options do
    opt :file, 'Video file to upload', :type => String
    opt :title, 'Video title', :default => 'Test Title', :type => String
    opt :description, 'Video description',
          :default => 'Test Description', :type => String
    opt :category_id, 'Numeric video category. See https://developers.google.com/youtube/v3/docs/videoCategories/list',
          :default => 22, :type => :int
    opt :keywords, 'Video keywords, comma-separated',
          :default => '', :type => String
    opt :privacy_status, 'Video privacy status: public, private, or unlisted',
          :default => 'public', :type => String
  end

  if opts[:file].nil? or not File.file?(opts[:file])
    Trollop::die :file, 'does not exist'
  end

  client, youtube = get_authenticated_service

  begin
    body = {
      :snippet => {
        :title => opts[:title],
        :description => opts[:description],
        :tags => opts[:keywords].split(','),
        :categoryId => opts[:category_id],
      },
      :status => {
        :privacyStatus => opts[:privacy_status]
      }
    }

    videos_insert_response = client.execute!(
      :api_method => youtube.videos.insert,
      :body_object => body,
      :media => Google::APIClient::UploadIO.new(opts[:file], 'video/*'),
      :parameters => {
        :uploadType => 'resumable',
        :part => body.keys.join(',')
      }
    )

    videos_insert_response.resumable_upload.send_all(client)

    puts "Video id '#{videos_insert_response.data.id}' was successfully uploaded."
  rescue Google::APIClient::TransmissionError => e
    puts e.result.body
  end
end

main

Erros

A tabela a seguir identifica mensagens de erro que a API pode retornar em resposta a uma chamada para esse método. Consulte a documentação mensagem de erro para mais detalhes.

Tipo de erro Detalhe do erro Descrição
badRequest (400) defaultLanguageNotSet A solicitação está tentando adicionar detalhes de vídeos localizados sem especificar o idioma padrão dos detalhes do vídeo.
badRequest (400) invalidCategoryId A propriedade snippet.categoryId especifica um ID de categoria inválido. Use o método videoCategories.list para recuperar as categorias compatíveis.
badRequest (400) invalidDescription Os metadados da solicitação especificam uma descrição de vídeo inválida.
badRequest (400) invalidFilename O nome de arquivo do vídeo especificado no cabeçalho Slug é inválido.
badRequest (400) invalidPublishAt Os metadados da solicitação especificam um horário de publicação programado inválido.
badRequest (400) invalidRecordingDetails O objeto recordingDetails nos metadados da solicitação especifica detalhes de gravação inválidos.
badRequest (400) invalidTags Os metadados da solicitação especificam palavras-chave de vídeo inválidas.
badRequest (400) invalidTitle Os metadados da solicitação especificam um título de vídeo inválido ou vazio.
badRequest (400) invalidVideoGameRating Os metadados da solicitação especificam uma classificação de video game inv.
badRequest (400) invalidVideoMetadata Os metadados da solicitação são inválidos.
badRequest (400) mediaBodyRequired A solicitação não inclui o conteúdo da vídeo.
badRequest (400) uploadLimitExceeded O usuário excedeu o número de vídeos que ele pode enviar.
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting A solicitação tenta definir uma licença inválida para o vídeo.
forbidden (403) forbiddenPrivacySetting A solicitação tenta definir uma configuração de privacidade inválida para o vídeo.

Confira!

Use o APIs Explorer para chamar a API e ver a solicitação e a resposta da API.