Videos: insert

Wszystkie filmy z niezweryfikowanych projektów API utworzonych po 28 lipca 2020 r. przesłane za pomocą punktu końcowego videos.insert będą ograniczone do wyświetlania prywatnego. Aby usunąć to ograniczenie, każdy projekt interfejsu API musi przejść kontrolę w celu zweryfikowania zgodności z Warunkami korzystania z usługi. Więcej informacji znajdziesz w historii zmian interfejsu API.

Przesyła film do YouTube i opcjonalnie ustawia jego metadane.

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

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

Wpływ na limit: wywołanie tej metody ma koszt limitu wynoszący 1600 jednostek.

Typowe przypadki użycia

Prośba

Żądanie HTTP

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

Upoważnienie

To żądanie wymaga autoryzacji z użyciem co najmniej jednego z tych 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 tabeli poniżej znajdziesz parametry obsługiwane przez to zapytanie. Wszystkie wymienione parametry są parametrami zapytania.

Parametry
Parametry wymagane
part string
Parametr part służy w tej operacji do 2 celów. Wskazuje on właściwości, które ustawi operacja zapisu, a także właściwości uwzględnione w odpowiedzi 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 filmu obliczane przez YouTube i nie zawiera wartości, które można ustawić lub zmienić. Jeśli wartość parametru określa element part, który nie zawiera wartości zmiennych, będzie on nadal uwzględniony w odpowiedzi interfejsu API.

Na poniższej liście znajdziesz nazwy part, które możesz uwzględnić w wartości parametru:
    part
  • 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ć powiadomienie o nowym filmie do użytkowników, którzy subskrybują kanał tego filmu. Wartość parametru True oznacza, że subskrybenci będą powiadamiani o nowych filmach. Właściciel kanału, który przesyła wiele filmów, może jednak ustawić wartość False, aby uniknąć wysyłania powiadomień o każdym nowym filmie do subskrybentów kanału. Wartością domyślną jest True.
onBehalfOfContentOwner string
Tego parametru można używać tylko w prawidłowo autoryzowanym żądaniu. Uwaga: ten parametr jest przeznaczony wyłącznie dla dostawców treści w YouTube.

Parametr onBehalfOfContentOwner wskazuje, że dane uwierzytelniające żądanie identyfikują użytkownika YouTube CMS działającego w imieniu właściciela treści określonego w wartości parametru. Jest on przeznaczony dla dostawców treści w YouTube, którzy mają wiele różnych kanałów w YouTube i nimi zarządzają. Dzięki niej właściciele treści mogą jednorazowo uwierzytelnić się i uzyskiwać dostęp do wszystkich swoich filmów oraz danych dotyczących kanałów bez konieczności podawania danych uwierzytelniających dla każdego kanału z osobna. Konto CMS, za pomocą którego użytkownik uwierzytelnia się, musi być powiązane z określonym właścicielem treści YouTube.
onBehalfOfContentOwnerChannel string
Tego parametru można używać tylko w prawidłowo autoryzowanym żądaniu. Tego parametru można używać tylko w prawidłowo autoryzowanym żądaniu. Uwaga: ten parametr jest przeznaczony wyłącznie dla dostawców treści w YouTube.

Parametr onBehalfOfContentOwnerChannel określa identyfikator kanału w YouTube, do którego jest dodawany film. Ten parametr jest wymagany, gdy w żądaniu określona jest wartość parametru onBehalfOfContentOwner i można go używać tylko w połączeniu z tym parametrem. Prośba musi być dodatkowo autoryzowana za pomocą konta CMS połączonego z właścicielem treści określonym w parametrze onBehalfOfContentOwner. Kanał wskazany za pomocą parametru onBehalfOfContentOwnerChannel musi być połączony z właścicielem treści określonym w parametrze onBehalfOfContentOwner.

Ten parametr jest przeznaczony dla partnerów dostarczających treści do YouTube, którzy są właścicielami wielu różnych kanałów YouTube i nimi zarządzają. Pozwala właścicielom treści jednorazowo uwierzytelnić się i wykonywać działania 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

W treści żądania podaj zasób wideo. W przypadku tego zasobu:

  • Możesz ustawić wartości dla 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 (wycofano)
    • recordingDetails.location.latitude (wycofano)
    • recordingDetails.location.longitude (wycofano)
    • recordingDetails.recordingDate

Odpowiedź

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

Przykłady

Uwaga: poniższe przykłady kodu mogą nie obejmować 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 na kanał powiązany z żądaniem.

W tym przykładzie korzystamy z biblioteki klienta w 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

Poniższy przykładowy kod wywołuje metodę videos.insert interfejsu API, aby przesłać film na kanał powiązany z żądaniem.

W tym przykładzie korzystamy z 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

Ten przykład wywołuje metodę videos.insert interfejsu API, aby przesłać film na kanał powiązany z żądaniem.

W tym przykładzie korzystamy z 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 szczegółów znajdziesz w dokumentacji komunikatów o błędach.

Typ błędu Szczegóły błędu Opis
badRequest (400) defaultLanguageNotSet Żądanie ma na celu dodanie zlokalizowanych szczegółów filmu bez określenia 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 określają nieprawidłowy opis filmu.
badRequest (400) invalidFilename Nazwa pliku wideo podana w nagłówku Slug jest nieprawidłowa.
badRequest (400) invalidPublishAt Metadane żądania określają nieprawidłowy czas zaplanowanej 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 określają nieprawidłowy lub pusty tytuł filmu.
badRequest (400) invalidVideoGameRating Metadane żądania określają nieprawidłową ocenę gry wideo.
badRequest (400) invalidVideoMetadata Metadane żądania są nieprawidłowe.
badRequest (400) mediaBodyRequired W żądaniu nie ma treści wideo.
badRequest (400) uploadLimitExceeded Użytkownik przekroczył liczbę filmów, które może przesłać.
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting To żądanie próbuje ustawić nieprawidłową licencję dla filmu.
forbidden (403) forbiddenPrivacySetting Żądanie stanowi próbę ustawienia nieprawidłowego ustawienia prywatności filmu.

Wypróbuj

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