Videos: insert

Semua video yang diupload melalui endpoint videos.insert dari project API yang belum diverifikasi yang dibuat setelah 28 Juli 2020 akan dibatasi untuk mode tonton pribadi. Untuk mencabut pembatasan ini, setiap project API harus dilakukan audit untuk memverifikasi kepatuhan terhadap Persyaratan Layanan. Lihat Histori Revisi API untuk detail selengkapnya.

Mengupload video ke YouTube dan secara opsional menyetel metadata video.

Metode ini mendukung upload media. File yang diupload harus sesuai dengan batasan ini:

  • Ukuran file maksimum: 256 GB
  • Jenis MIME Media yang diterima: video/*, application/octet-stream

Dampak kuota: Panggilan ke metode ini memiliki biaya kuota sebanyak 1.600 unit.

Kasus penggunaan umum

Permintaan

Permintaan HTTP

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

Otorisasi

Permintaan ini memerlukan otorisasi dengan setidaknya salah satu cakupan berikut (baca selengkapnya tentang autentikasi dan otorisasi).

Cakupan
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

Parameter

Tabel berikut mencantumkan parameter yang didukung kueri ini. Semua parameter yang tercantum adalah parameter kueri.

Parameter
Parameter yang diperlukan
part string
Parameter part memiliki dua tujuan dalam operasi ini. Atribut ini mengidentifikasi properti yang akan disetel oleh operasi tulis serta properti yang akan disertakan dalam respons API.

Perhatikan bahwa tidak semua bagian berisi properti yang dapat disetel saat menyisipkan atau memperbarui video. Misalnya, objek statistics mengenkapsulasi statistik yang dihitung oleh YouTube untuk sebuah video dan tidak berisi nilai yang dapat Anda tetapkan atau ubah. Jika nilai parameter menentukan part yang tidak berisi nilai yang dapat berubah, part tersebut akan tetap disertakan dalam respons API.

Daftar berikut berisi nama part yang dapat Anda sertakan dalam nilai parameter:
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
Parameter opsional
notifySubscribers boolean
Parameter notifySubscribers menunjukkan apakah YouTube harus mengirimkan notifikasi tentang video baru kepada pengguna yang subscribe ke channel video tersebut. Nilai parameter True menunjukkan bahwa subscriber akan diberi tahu mengenai video yang baru diupload. Namun, pemilik channel yang mengupload banyak video dapat memilih untuk menyetel nilai ke False agar tidak mengirim notifikasi tentang setiap video baru kepada subscriber channel. Nilai defaultnya adalah True.
onBehalfOfContentOwner string
Parameter ini hanya dapat digunakan dalam permintaan yang diizinkan dengan benar. Catatan: Parameter ini ditujukan khusus untuk partner konten YouTube.

Parameter onBehalfOfContentOwner menunjukkan bahwa kredensial otorisasi permintaan mengidentifikasi pengguna CMS YouTube yang bertindak atas nama pemilik konten yang ditentukan dalam nilai parameter. Parameter ini ditujukan untuk partner konten YouTube yang memiliki dan mengelola banyak channel YouTube yang berbeda. Pemilik konten dapat melakukan autentikasi sekali dan mendapatkan akses ke semua data channel serta video mereka, tanpa harus memberikan kredensial autentikasi untuk setiap channel. Akun CMS yang diautentikasi oleh pengguna harus ditautkan ke pemilik konten YouTube yang ditentukan.
onBehalfOfContentOwnerChannel string
Parameter ini hanya dapat digunakan dalam permintaan yang diizinkan dengan benar. Parameter ini hanya dapat digunakan dalam permintaan yang diotorisasi dengan benar. Catatan: Parameter ini ditujukan khusus untuk partner konten YouTube.

Parameter onBehalfOfContentOwnerChannel menentukan ID channel YouTube dari channel yang ditambahi video. Parameter ini diperlukan saat permintaan menentukan nilai untuk parameter onBehalfOfContentOwner, dan hanya dapat digunakan bersama dengan parameter tersebut. Selain itu, permintaan tersebut harus diizinkan menggunakan akun CMS yang ditautkan ke pemilik konten yang ditentukan oleh parameter onBehalfOfContentOwner. Terakhir, channel yang telah ditentukan oleh parameter value onBehalfOfContentOwnerChannel harus ditautkan ke pemilik konten yang ditentukan oleh parameter onBehalfOfContentOwner.

Parameter ini ditujukan untuk partner konten YouTube yang memiliki dan mengelola banyak channel YouTube yang berbeda. ID ini memungkinkan pemilik konten mengautentikasi satu kali dan melakukan tindakan atas nama channel yang ditentukan dalam nilai parameter, tanpa harus memberikan kredensial autentikasi untuk setiap channel yang terpisah.

Isi permintaan

Berikan resource video dalam isi permintaan. Untuk resource tersebut:

  • Anda dapat menetapkan nilai untuk properti berikut:

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

Respons

Jika berhasil, metode ini akan menampilkan resource video dalam isi respons.

Contoh

Catatan: Contoh kode berikut mungkin tidak mewakili semua bahasa pemrograman yang didukung. Baca dokumentasi library klien untuk mengetahui daftar bahasa yang didukung.

Go

Contoh kode ini memanggil metode videos.insert API untuk mengupload video ke saluran yang terkait dengan permintaan.

Contoh ini menggunakan library klien 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

Contoh kode berikut memanggil metode videos.insert API untuk mengupload video ke saluran yang terkait dengan permintaan.

Contoh ini menggunakan library klien.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

Contoh ini memanggil metode videos.insert API untuk mengupload video ke saluran yang terkait dengan permintaan.

Contoh ini menggunakan library klien 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

Error

Tabel berikut mengidentifikasi pesan error yang dapat ditampilkan API sebagai respons terhadap panggilan ke metode ini. Lihat dokumentasi pesan error untuk detail selengkapnya.

Jenis error Detail error Deskripsi
badRequest (400) defaultLanguageNotSet Permintaan tersebut mencoba menambahkan detail video yang dilokalkan tanpa menentukan bahasa default detail video.
badRequest (400) invalidCategoryId Properti snippet.categoryId mencantumkan ID kategori yang tidak valid. Gunakan metode videoCategories.list untuk mengambil kategori yang didukung.
badRequest (400) invalidDescription Metadata permintaan mencantumkan deskripsi video yang tidak valid.
badRequest (400) invalidFilename Nama file video yang ditentukan pada header Slug tidak valid.
badRequest (400) invalidPublishAt Metadata permintaan menentukan waktu publikasi terjadwal yang tidak valid.
badRequest (400) invalidRecordingDetails Objek recordingDetails dalam metadata permintaan mencantumkan detail perekaman yang tidak valid.
badRequest (400) invalidTags Metadata permintaan menentukan kata kunci video yang tidak valid.
badRequest (400) invalidTitle Metadata permintaan mencantumkan judul video yang tidak valid atau kosong.
badRequest (400) invalidVideoGameRating Metadata permintaan menentukan rating video game yang tidak valid.
badRequest (400) invalidVideoMetadata Metadata permintaan tidak valid.
badRequest (400) mediaBodyRequired Permintaan tidak mencakup konten video.
badRequest (400) uploadLimitExceeded Pengguna telah melampaui jumlah video yang dapat mereka upload.
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting Permintaan tersebut mencoba menyetel lisensi yang tidak valid untuk video.
forbidden (403) forbiddenPrivacySetting Permintaan tersebut mencoba menyetel setelan privasi yang tidak valid untuk video.

Cobalah!

Gunakan APIs Explorer untuk memanggil API ini dan melihat permintaan dan respons API.