Videos: insert

YouTube に動画をアップロードし、オプションで動画のメタデータを設定します。

このメソッドはメディア アップロードをサポートしています。 アップロードするファイルには、以下の制約が適用されます。

  • 最大ファイルサイズ: 256 GB
  • 使用できるメディア MIME タイプ: video/*、application/octet-stream

割り当ての影響: 1 日あたり 100 回の呼び出し。このメソッドの呼び出しには、割り当てコストが動画アップロード割り当てバケットで 1 ユニット発生します。

一般的なユースケース

リクエスト

HTTP リクエスト

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

承認

このリクエストは、少なくとも次のうち 1 つのスコープでの承認が必要です(認証と承認の詳細をご確認ください)。

スコープ
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

パラメータ

次の表に、このクエリでサポートされているパラメータを示します。このリストのパラメータはすべてクエリ パラメータです。

パラメータ
必須パラメータ
part string
part パラメータには、このオペレーションで 2 つの目的があります。書き込みオペレーションで設定するプロパティと、API レスポンスに含めるプロパティを識別します。

すべてのパートに、動画の挿入または更新時に設定できるプロパティが含まれているわけではありません。たとえば、statistics オブジェクトは、YouTube が動画に対して計算する統計情報をカプセル化し、設定または変更できる値は含まれていません。パラメータ値で、変更可能な値を含まない part を指定した場合でも、その part は API レスポンスに含まれます。

次のリストには、パラメータ値に含めることができる part 名が含まれています。
  • brandPartner
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • paidProductPlacementDetails
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
オプション パラメータ
notifySubscribers boolean
notifySubscribers パラメータは、新しい動画に関する通知を動画のチャンネルに登録しているユーザーに送信するかどうかを示します。パラメータ値が True の場合、チャンネル登録者に新しくアップロードされた動画が通知されます。ただし、多くの動画をアップロードするチャンネル所有者は、新しい動画ごとにチャンネル登録者に通知が送信されないように、値を False に設定することをおすすめします。デフォルト値は True です。
onBehalfOfContentOwner string
このパラメータは、適切に承認されたリクエストでのみ使用できます。注: このパラメータは、YouTube コンテンツ パートナー専用です。

onBehalfOfContentOwner パラメータは、リクエストの認証情報が、パラメータ値で指定されたコンテンツ所有者の代理として行動する YouTube CMS ユーザーを識別することを示します。このパラメータは、複数の YouTube チャンネルを所有、管理している YouTube コンテンツ パートナーを対象にしています。このパラメータを使用すると、コンテンツ所有者は一度認証されれば、すべての動画やチャンネル データにアクセスできるようになります。チャンネルごとに認証情報を指定する必要はありません。ユーザー認証に使用する CMS アカウントは、指定された YouTube コンテンツ所有者にリンクされていなければなりません。
onBehalfOfContentOwnerChannel string
このパラメータは、適切に承認されたリクエストでのみ使用できます。このパラメータは、適切に承認されたリクエストでのみ使用できます。注: このパラメータは、YouTube コンテンツ パートナー専用です。

onBehalfOfContentOwnerChannel パラメータは、動画が追加されるチャンネルの YouTube チャンネル ID を指定します。このパラメータは、リクエストで onBehalfOfContentOwner パラメータの値を指定する場合に必要であり、そのパラメータと組み合わせてのみ使用できます。また、リクエストは、onBehalfOfContentOwner パラメータで指定されたコンテンツ所有者にリンクされている CMS アカウントを使用して承認する必要があります。最後に、onBehalfOfContentOwnerChannel パラメータ値で指定されたチャンネルは、onBehalfOfContentOwner パラメータで指定されたコンテンツ所有者にリンクされている必要があります。

このパラメータは、複数の YouTube チャンネルを所有、管理している YouTube コンテンツ パートナーを対象にしています。このパラメータを使用すると、コンテンツ所有者は一度認証されれば、パラメータ値で指定されたチャンネルの代わりにアクションを実行できるようになります。チャンネルごとに認証情報を指定する必要はありません。

リクエストの本文

リクエストの本文に動画リソースを指定します。 そのリソースの場合:

  • 以下のプロパティの値を指定することができます。

    • snippet.title
    • snippet.description
    • snippet.tags[]
    • snippet.categoryId
    • snippet.defaultLanguage
    • localizations.(key)
    • localizations.(key).title
    • localizations.(key).description
    • status.embeddable
    • status.license
    • status.privacyStatus: このプロパティの値を指定しない場合、アップロードされた動画のプライバシー設定はデフォルトで public になります。YouTube ヘルプセンターで説明されているように、クリエイター アカウントの設定によっては、アップロードがデフォルトで private になる場合があります。未確認の API プロジェクトからアップロードされた動画は、非公開視聴モードに制限されません。
    • status.publicStatsViewable
    • status.publishAt
    • status.selfDeclaredMadeForKids
    • status.containsSyntheticMedia
    • recordingDetails.recordingDate

レスポンス

成功すると、このメソッドはレスポンスの本文で動画のリソースを返します。

例

注: 次のコードサンプルは、サポートされているすべてのプログラミング言語を表しているわけではありません。サポートされている言語の一覧については、クライアント ライブラリのドキュメントをご覧ください。

Go

このコードサンプルでは、API の videos.insert メソッドを呼び出して、リクエストに関連付けられたチャンネルに動画をアップロードします。

この例では、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

次のコードサンプルでは、API の videos.insert メソッドを呼び出して、リクエストに関連付けられたチャンネルに動画をアップロードします。

この例では、.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

このサンプルでは、API の videos.insert メソッドを呼び出して、リクエストに関連付けられたチャンネルに動画をアップロードします。

この例では、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

エラー

次の表に、このメソッドの呼び出しに応じて API が返す可能性のあるエラー メッセージを示します。詳細については、エラー メッセージのドキュメントを参照してください。

エラーのタイプ エラーの詳細 説明
badRequest (400) defaultLanguageNotSet リクエストは、動画の詳細のデフォルト言語を指定せずに、ローカライズされた動画の詳細を追加しようとしています。
badRequest (400) invalidCategoryId snippet.categoryId プロパティで指定されたカテゴリ ID が無効です。videoCategories.list メソッドを使用して、サポートされているカテゴリを取得します。
badRequest (400) invalidDescription リクエスト メタデータで指定された動画の説明は無効です。
badRequest (400) invalidFilename Slug ヘッダーで指定された動画ファイル名が無効です。
badRequest (400) invalidPublishAt リクエスト メタデータで指定された公開予定時刻が無効です。
badRequest (400) invalidRecordingDetails リクエスト メタデータの recordingDetails オブジェクトで指定された録画の詳細が無効です。
badRequest (400) invalidTags リクエスト メタデータで指定された動画のキーワードは無効です。
badRequest (400) invalidTitle リクエスト メタデータで指定された動画タイトルが無効または空です。
badRequest (400) invalidVideoGameRating リクエスト メタデータで指定されたビデオ ゲームの評価は無効です。
badRequest (400) invalidVideoMetadata リクエスト メタデータが無効です。
badRequest (400) mediaBodyRequired リクエストに動画コンテンツが含まれていません。
badRequest (400) uploadLimitExceeded ユーザーがアップロードできる動画の数を超えています。
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting リクエストは、動画に無効なライセンスを設定しようとしています。
forbidden (403) forbiddenPrivacySetting リクエストは、動画に無効なプライバシー設定を指定しようとしています。

試してみよう:

APIs Explorer を使用してこの API を呼び出し、API リクエストとレスポンスを確認します。