Videos: insert

Todos los videos subidos a través del extremo videos.insert desde proyectos de API sin verificar creados después del 28 de julio de 2020 estarán restringidos al modo de reproducción privada. Para levantar esta restricción, cada proyecto de API debe someterse a una auditoría para verificar el cumplimiento de las Condiciones del Servicio. Consulta el Historial de revisión de la API para obtener más información.

Sube un video a YouTube y configura opcionalmente sus metadatos.

Este método admite la carga de medios. Los archivos cargados deben cumplir con los siguientes requisitos:

  • Tamaño máximo del archivo: 256 GB
  • Tipos de MIME de contenido multimedia aceptados: video/*, application/octet-stream

Impacto en la cuota: Una llamada a este método tiene un costo de cuota de 1,600 unidades.

Casos de uso habituales

Solicitud

Solicitud HTTP

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

Autorización

Esta solicitud requiere autorización con al menos uno de los siguientes alcances (obtén más información acerca de la autenticación y autorización).

Alcance
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

En la siguiente tabla, se enumeran los parámetros que admite esta consulta. Todos los parámetros mencionados son parámetros de consulta.

Parámetros
Parámetros obligatorios
part string
El parámetro part tiene dos propósitos en esta operación. Identifica las propiedades que establecerá la operación de escritura, así como las que incluirá la respuesta de la API.

Ten en cuenta que no todas las partes contienen propiedades que se pueden establecer cuando se inserta o actualiza un video. Por ejemplo, el objeto statistics encapsula las estadísticas que YouTube calcula para un video y no contiene valores que puedas establecer o modificar. Si el valor del parámetro especifica un part que no contiene valores mutables, ese part se incluirá de todas formas en la respuesta de la API.

La siguiente lista contiene los nombres part que puedes incluir en el valor del parámetro:
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • paidProductPlacementDetails
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
Parámetros opcionales
notifySubscribers boolean
El parámetro notifySubscribers indica si YouTube debe enviar una notificación sobre el video nuevo a los usuarios que se suscriben al canal del video. Un valor de parámetro de True indica que se notificará a los suscriptores sobre los videos subidos recientemente. Sin embargo, el propietario de un canal que sube muchos videos podría establecer el valor en False para evitar enviar una notificación sobre cada video nuevo a los suscriptores del canal. El valor predeterminado es True.
onBehalfOfContentOwner string
Este parámetro solo se puede usar en una solicitud autorizada correctamente. Nota: Este parámetro está dirigido exclusivamente a socios de contenido de YouTube.

El parámetro onBehalfOfContentOwner indica que las credenciales de autorización de la solicitud identifican a un usuario del CMS de YouTube que actúa en nombre del propietario del contenido especificado en el valor del parámetro. Este parámetro está dirigido a socios de contenido de YouTube que poseen y administran muchos canales de YouTube diferentes. Permite a los propietarios del contenido autenticarse una vez y tener acceso a todos los datos de sus videos y canales, sin tener que proporcionar credenciales de autenticación para cada canal. La cuenta de CMS con la que se autentica el usuario debe estar relacionada con el propietario del contenido de YouTube especificado.
onBehalfOfContentOwnerChannel string
Este parámetro solo se puede usar en una solicitud autorizada correctamente. Este parámetro solo se puede usar en una solicitud autorizada de forma correcta. Nota: Este parámetro está dirigido exclusivamente a socios de contenido de YouTube.

El parámetro onBehalfOfContentOwnerChannel especifica el ID del canal de YouTube del canal al que se agrega un video. Este parámetro es obligatorio cuando una solicitud especifica un valor para el parámetro onBehalfOfContentOwner y solo se puede usar junto con ese parámetro. Además, la solicitud debe estar autorizada con una cuenta de CMS vinculada al propietario del contenido que especifica el parámetro onBehalfOfContentOwner. Por último, el canal que especifica el valor del parámetro onBehalfOfContentOwnerChannel debe estar vinculado al propietario del contenido que especifica el parámetro onBehalfOfContentOwner.

Este parámetro está dirigido a socios de contenido de YouTube que poseen y administran muchos canales de YouTube diferentes. Permite a los propietarios de contenido autenticarse una vez y llevar a cabo acciones en nombre del canal especificado en el valor del parámetro, sin tener que proporcionar credenciales de autenticación para cada canal por separado.

Cuerpo de la solicitud

Proporciona un recurso de video en el cuerpo de la solicitud. Para ese recurso:

  • Puedes establecer los valores de las siguientes propiedades:

    • 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
    • status.containsSyntheticMedia
    • recordingDetails.recordingDate

Respuesta

Si se aplica correctamente, este método muestra un recurso de video en el cuerpo de la respuesta.

Ejemplos

Nota: Es posible que las siguientes muestras de código no representen todos los lenguajes de programación admitidos. Consulta la documentación de las bibliotecas cliente para obtener una lista de los idiomas admitidos.

Go

Esta muestra de código llama al método videos.insert de la API para subir un video al canal asociado con la solicitud.

En este ejemplo, se usa la biblioteca cliente de 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

En la siguiente muestra de código, se llama al método videos.insert de la API para subir un video al canal asociado con la solicitud.

En este ejemplo se utiliza la 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

En este ejemplo, se llama al método videos.insert de la API para subir un video al canal asociado con la solicitud.

En este ejemplo se utiliza la 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

Errores

En la siguiente tabla, se identifican los mensajes de error que podría mostrar la API en respuesta a una llamada a este método. Consulta la documentación sobre mensajes de error para obtener más información.

Tipo de error Detalle del error Descripción
badRequest (400) defaultLanguageNotSet La solicitud intenta agregar detalles de video localizados sin especificar el idioma predeterminado de los detalles del video.
badRequest (400) invalidCategoryId La propiedad snippet.categoryId especifica un ID de categoría no válido. Usa el método videoCategories.list para recuperar las categorías admitidas.
badRequest (400) invalidDescription Los metadatos de la solicitud especifican una descripción del video no válida.
badRequest (400) invalidFilename El nombre de archivo de video especificado en el encabezado Slug no es válido.
badRequest (400) invalidPublishAt Los metadatos de la solicitud especifican una hora de publicación programada no válida.
badRequest (400) invalidRecordingDetails El objeto recordingDetails de los metadatos de la solicitud especifica detalles de registro no válidos.
badRequest (400) invalidTags Los metadatos de la solicitud especifican palabras clave de video no válidas.
badRequest (400) invalidTitle Los metadatos de la solicitud especifican un título de video no válido o vacío.
badRequest (400) invalidVideoGameRating Los metadatos de la solicitud especifican una calificación de videojuego no válida.
badRequest (400) invalidVideoMetadata Los metadatos de la solicitud no son válidos.
badRequest (400) mediaBodyRequired La solicitud no incluye el contenido del video.
badRequest (400) uploadLimitExceeded El usuario superó la cantidad de videos que puede subir.
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting La solicitud intenta establecer una licencia no válida para el video.
forbidden (403) forbiddenPrivacySetting La solicitud intenta establecer una configuración de privacidad no válida para el video.

Pruébalo

Usa APIs Explorer para llamar a esta API y ver la solicitud y la respuesta de la API.