Videos: insert

Wszystkie filmy przesłane przez punkt końcowy videos.insert z niezweryfikowanych projektów API utworzonych po 28 lipca 2020 r. będą dostępne wyłącznie w trybie wyświetlania prywatnego. Aby znieść to ograniczenie, każdy projekt interfejsu API musi przejść kontrolę, aby potwierdzić zgodność z Warunkami korzystania z usługi. Więcej informacji znajdziesz w historii wersji interfejsu API.

Przesłanie filmu do YouTube i opcjonalnie ustawienie jego metadanych.

Ta metoda obsługuje przesyłanie multimediów. Przesyłane pliki muszą być zgodne z tymi ograniczeniami:

  • Maksymalny rozmiar pliku: 256 GB
  • Akceptowane typy MIME multimediów: video/*, application/octet-stream

Wpływ limitu: poniższy koszt wywołań tej metody wynosi 1600 jednostek.

Typowe przypadki użycia

Żądanie

Żądanie HTTP

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

Upoważnienie

To żądanie wymaga autoryzacji z co najmniej jednym z poniższych zakresów (więcej informacji o uwierzytelnianiu i autoryzacji).

Zakres
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

Parametry

W poniższej tabeli podano parametry obsługiwane przez to zapytanie. Wszystkie wymienione parametry są parametrami zapytania.

Parametry
Parametry wymagane
part string
Parametr part spełnia 2 cele w tej operacji. Określa właściwości, które ustawi operacja zapisu, oraz właściwości, które będzie uwzględniać odpowiedź interfejsu API.

Pamiętaj, że nie wszystkie części zawierają właściwości, które można ustawić podczas wstawiania lub aktualizowania filmu. Na przykład obiekt statistics zawiera statystyki obliczone przez YouTube dla filmu i nie zawiera wartości, które można ustawić lub zmodyfikować. Jeśli wartość parametru zawiera zmienną part, która nie zawiera zmiennych, ten parametr part nadal będzie uwzględniany w odpowiedzi interfejsu API.

Ta lista zawiera nazwy part, które możesz uwzględnić w wartości parametru:
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
Parametry opcjonalne
notifySubscribers boolean
Parametr notifySubscribers wskazuje, czy YouTube ma wysyłać powiadomienia o nowym filmie do użytkowników, którzy subskrybują kanał. Wartość True oznacza, że subskrybenci będą powiadamiani o nowo przesłanych filmach. Właściciel kanału, który przesyła wiele filmów, może jednak ustawić tę wartość na False, aby uniknąć wysyłania powiadomień o nowych filmach do subskrybentów kanału. Wartością domyślną jest True.
onBehalfOfContentOwner string
Ten parametr może być używany tylko w poprawnie autoryzowanym żądaniu. Uwaga: ten parametr jest przeznaczony wyłącznie dla partnerów w sieci reklamowej YouTube.

Parametr onBehalfOfContentOwner wskazuje, że dane logowania żądania autoryzacji to użytkownik YouTube, który działa w imieniu właściciela treści określonego w wartości parametru. Ten parametr jest przeznaczony dla partnerów w sieci reklamowej YouTube, którzy mają wiele kanałów YouTube i zarządzają nimi. Umożliwia właścicielom treści uwierzytelnianie tylko raz oraz dostęp do wszystkich filmów i kanałów bez konieczności podawania danych uwierzytelniających dla każdego kanału z osobna. Konto CMS, za pomocą którego użytkownik się uwierzytelni, musi być połączone z określonym właścicielem treści w YouTube.
onBehalfOfContentOwnerChannel string
Ten parametr może być używany tylko w poprawnie autoryzowanym żądaniu. Tego parametru można używać tylko w odpowiednim autoryzowanym żądaniu. Uwaga: ten parametr jest przeznaczony tylko dla dostawców treści w YouTube.

Parametr onBehalfOfContentOwnerChannel określa identyfikator kanału YouTube, do którego jest dodawany film. Ten parametr jest wymagany, gdy żądanie określa wartość parametru onBehalfOfContentOwner i można go używać tylko w połączeniu z tym parametrem. Dodatkowo żądanie musi być autoryzowane za pomocą konta CMS połączonego z właścicielem treści, które jest określone w parametrze onBehalfOfContentOwner. Na koniec kanał, który określa parametr onBehalfOfContentOwnerChannel, musi być powiązany z właścicielem treści, który jest określony przez parametr onBehalfOfContentOwner.

Ten parametr jest przeznaczony dla partnerów w sieci reklamowej YouTube, którzy mają wiele kanałów YouTube i zarządzają nimi. Umożliwia właścicielom treści uwierzytelnianie raz i wykonywanie działań w imieniu kanału określonego w wartości parametru, bez konieczności podawania danych uwierzytelniających dla każdego kanału z osobna.

Treść żądania

Umieść zasób wideo w treści żądania. Dla tego zasobu:

  • Możesz ustawić wartości tych właściwości:

    • 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 (wycofane)
    • recordingDetails.location.latitude (wycofane)
    • recordingDetails.location.longitude (wycofane)
    • recordingDetails.recordingDate

Odpowiedź

Jeśli operacja się uda, ta metoda zwróci zasób wideo w treści odpowiedzi.

Przykłady

Uwaga: poniższe przykłady kodu mogą nie prezentować wszystkich obsługiwanych języków programowania. Listę obsługiwanych języków znajdziesz w dokumentacji bibliotek klienta.

Go

Ten przykładowy kod wywołuje metodę videos.insert interfejsu API, aby przesłać film do kanału powiązanego z żądaniem.

W tym przykładzie użyto biblioteki klienta 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

Ten przykładowy kod wywołuje metodę videos.insert interfejsu API, aby przesłać film do kanału powiązanego z żądaniem.

W tym przykładzie użyto biblioteki klienta .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

W tym przykładzie wywołana jest metoda videos.insert interfejsu API, która pozwala przesłać film na kanał powiązany z żądaniem.

W tym przykładzie użyto biblioteki klienta 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

Błędy

W tabeli poniżej znajdziesz komunikaty o błędach, które interfejs API może zwrócić w odpowiedzi na wywołanie tej metody. Więcej informacji znajdziesz w dokumentacji komunikatów o błędach.

Typ błędu Szczegóły błędu Opis
badRequest (400) defaultLanguageNotSet Żądanie próbuje dodać zlokalizowane szczegóły filmu bez określania domyślnego języka szczegółów filmu.
badRequest (400) invalidCategoryId Właściwość snippet.categoryId określa nieprawidłowy identyfikator kategorii. Aby pobrać obsługiwane kategorie, użyj metody videoCategories.list.
badRequest (400) invalidDescription Metadane żądania podaj nieprawidłowy opis filmu.
badRequest (400) invalidFilename Nazwa pliku wideo podana w nagłówku Slug jest nieprawidłowa.
badRequest (400) invalidPublishAt Metadane żądania wskazują nieprawidłowy czas publikacji.
badRequest (400) invalidRecordingDetails Obiekt recordingDetails w metadanych żądania określa nieprawidłowe szczegóły nagrania.
badRequest (400) invalidTags Metadane żądania określają nieprawidłowe słowa kluczowe wideo.
badRequest (400) invalidTitle Metadane żądania podają nieprawidłowy lub pusty tytuł filmu.
badRequest (400) invalidVideoGameRating Metadane żądania wskazują nieprawidłową ocenę gry wideo.
badRequest (400) invalidVideoMetadata Metadane żądania są nieprawidłowe.
badRequest (400) mediaBodyRequired Prośba nie zawiera treści wideo.
badRequest (400) uploadLimitExceeded Użytkownik przekroczył liczbę przesłanych filmów.
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting Żądanie próbuje ustawić nieprawidłową licencję na film.
forbidden (403) forbiddenPrivacySetting Żądanie próbuje skonfigurować nieprawidłowe ustawienie prywatności filmu.

Wypróbuj

Użyj APIs Explorer, aby wywołać ten interfejs API i wyświetlić żądanie oraz odpowiedź interfejsu API.