Videos: insert

Tất cả video được tải lên qua điểm cuối videos.insert thuộc những dự án API chưa được xác minh được tạo sau ngày 28 tháng 7 năm 2020 sẽ bị hạn chế ở chế độ xem riêng tư. Để gỡ bỏ quy định hạn chế này, mỗi dự án API phải trải qua một quy trình kiểm tra để xác minh tình trạng tuân thủ Điều khoản dịch vụ. Vui lòng xem Nhật ký sửa đổi API để biết thêm chi tiết.

Tải video lên YouTube và tuỳ ý đặt siêu dữ liệu của video.

Phương thức này hỗ trợ tải nội dung nghe nhìn lên. Tệp được tải lên phải tuân thủ những ràng buộc sau:

  • Kích thước tệp tối đa: 256 GB
  • Loại MIME nội dung đa phương tiện được chấp nhận: video/*, application/octet-stream

Tác động đến hạn mức: Lệnh gọi đến phương thức này có chi phí hạn mức là 1600 đơn vị.

Các trường hợp sử dụng phổ biến

Yêu cầu

Yêu cầu HTTP

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

Ủy quyền

Yêu cầu này cần được uỷ quyền với ít nhất một trong các phạm vi sau (đọc thêm về quy trình xác thực và uỷ quyền).

Phạm vi
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

Tham số

Bảng sau đây liệt kê các tham số mà truy vấn này hỗ trợ. Tất cả tham số được liệt kê đều là tham số truy vấn.

Tham số
Tham số bắt buộc
part string
Tham số part phục vụ hai mục đích trong thao tác này. Lớp này xác định các thuộc tính mà thao tác ghi sẽ đặt cũng như các thuộc tính mà phản hồi API đưa vào.

Xin lưu ý rằng không phải phần nào cũng chứa các thuộc tính có thể đặt khi chèn hoặc cập nhật video. Ví dụ: đối tượng statistics đóng gói số liệu thống kê mà YouTube tính toán cho video và không chứa các giá trị mà bạn có thể đặt hoặc sửa đổi. Nếu giá trị tham số chỉ định một part không chứa giá trị có thể thay đổi, thì part đó vẫn sẽ được đưa vào phản hồi API.

Danh sách sau đây chứa các tên part mà bạn có thể đưa vào giá trị tham số:
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
Thông số không bắt buộc
notifySubscribers boolean
Tham số notifySubscribers cho biết YouTube có gửi thông báo về video mới cho những người dùng đăng ký kênh của video đó hay không. Giá trị tham số là True cho biết rằng người đăng ký sẽ nhận được thông báo về video mới tải lên. Tuy nhiên, chủ sở hữu kênh đang tải nhiều video lên có thể muốn đặt giá trị thành False để tránh gửi thông báo về từng video mới cho người đăng ký của kênh. Giá trị mặc định là True.
onBehalfOfContentOwner string
Bạn chỉ có thể dùng thông số này trong một yêu cầu được uỷ quyền đúng cách. Lưu ý: Thông số này chỉ dành cho các đối tác nội dung của YouTube.

Thông số onBehalfOfContentOwner cho biết thông tin uỷ quyền của yêu cầu giúp xác định một người dùng YouTube CMS đang hành động thay mặt cho chủ sở hữu nội dung được chỉ định trong giá trị thông số. Thông số này dành cho những đối tác nội dung trên YouTube sở hữu và quản lý nhiều kênh YouTube khác nhau. Tính năng này cho phép chủ sở hữu nội dung xác thực một lần và có quyền truy cập vào tất cả dữ liệu kênh cũng như video của mình mà không cần phải cung cấp thông tin xác thực cho từng kênh. Tài khoản CMS mà người dùng xác thực phải được liên kết với chủ sở hữu nội dung đã chỉ định trên YouTube.
onBehalfOfContentOwnerChannel string
Bạn chỉ có thể dùng thông số này trong một yêu cầu được uỷ quyền đúng cách. Chỉ có thể sử dụng thông số này trong một yêu cầu được uỷ quyền đúng cách. Lưu ý: Đây là tham số dành riêng cho các đối tác nội dung của YouTube.

Tham số onBehalfOfContentOwnerChannel chỉ định mã nhận dạng kênh YouTube của kênh có video được thêm vào. Tham số này là bắt buộc khi yêu cầu chỉ định một giá trị cho tham số onBehalfOfContentOwner và chỉ có thể dùng cùng với tham số đó. Ngoài ra, yêu cầu phải được uỷ quyền bằng một tài khoản CMS liên kết với chủ sở hữu nội dung mà tham số onBehalfOfContentOwner chỉ định. Cuối cùng, kênh mà giá trị tham số onBehalfOfContentOwnerChannel chỉ định phải được liên kết với chủ sở hữu nội dung mà tham số onBehalfOfContentOwner chỉ định.

Tham số này dành cho các đối tác nội dung trên YouTube sở hữu và quản lý nhiều kênh YouTube. Tính năng này cho phép chủ sở hữu nội dung xác thực một lần và thực hiện thao tác thay mặt cho kênh được chỉ định trong giá trị thông số mà không phải cung cấp thông tin xác thực cho từng kênh riêng biệt.

Nội dung yêu cầu

Cung cấp tài nguyên video trong nội dung yêu cầu. Đối với tài nguyên đó:

  • Bạn có thể đặt giá trị cho những thuộc tính sau:

    • 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 (không dùng nữa)
    • recordingDetails.location.latitude (không dùng nữa)
    • recordingDetails.location.longitude (không dùng nữa)
    • recordingDetails.recordingDate

Phản hồi

Nếu thành công, phương thức này sẽ trả về một tài nguyên video trong nội dung phản hồi.

Ví dụ

Lưu ý: Các mã mẫu sau đây có thể không đại diện cho tất cả ngôn ngữ lập trình được hỗ trợ. Xem tài liệu về thư viện ứng dụng để biết danh sách các ngôn ngữ được hỗ trợ.

Go

Mã mẫu này gọi phương thức videos.insert của API để tải video lên kênh được liên kết với yêu cầu.

Ví dụ này sử dụng thư viện ứng dụng 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

Mã mẫu sau đây gọi phương thức videos.insert của API để tải video lên kênh được liên kết với yêu cầu.

Ví dụ này sử dụng thư viện ứng dụng.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

Mẫu này gọi phương thức videos.insert của API để tải video lên kênh được liên kết với yêu cầu.

Ví dụ này sử dụng thư viện ứng dụng 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

Lỗi

Bảng sau đây xác định các thông báo lỗi mà API có thể trả về để phản hồi lệnh gọi đến phương thức này. Vui lòng xem tài liệu về thông báo lỗi để biết thêm chi tiết.

Loại lỗi Chi tiết lỗi Nội dung mô tả
badRequest (400) defaultLanguageNotSet Yêu cầu này đang cố gắng thêm thông tin chi tiết đã bản địa hoá của video mà không chỉ định ngôn ngữ mặc định của thông tin chi tiết của video.
badRequest (400) invalidCategoryId Thuộc tính snippet.categoryId chỉ định một mã danh mục không hợp lệ. Sử dụng phương thức videoCategories.list để truy xuất các danh mục được hỗ trợ.
badRequest (400) invalidDescription Siêu dữ liệu của yêu cầu chỉ định một nội dung mô tả video không hợp lệ.
badRequest (400) invalidFilename Tên tệp video được chỉ định trong tiêu đề Slug không hợp lệ.
badRequest (400) invalidPublishAt Siêu dữ liệu của yêu cầu chỉ định thời gian xuất bản theo lịch không hợp lệ.
badRequest (400) invalidRecordingDetails Đối tượng recordingDetails trong siêu dữ liệu của yêu cầu chỉ định thông tin chi tiết về bản ghi không hợp lệ.
badRequest (400) invalidTags Siêu dữ liệu của yêu cầu chỉ định từ khoá video không hợp lệ.
badRequest (400) invalidTitle Siêu dữ liệu của yêu cầu chỉ định một tiêu đề video không hợp lệ hoặc trống.
badRequest (400) invalidVideoGameRating Siêu dữ liệu của yêu cầu chỉ định một mức phân loại trò chơi điện tử không hợp lệ.
badRequest (400) invalidVideoMetadata Siêu dữ liệu của yêu cầu không hợp lệ.
badRequest (400) mediaBodyRequired Yêu cầu không bao gồm nội dung video.
badRequest (400) uploadLimitExceeded Người dùng đã vượt quá số video họ có thể tải lên.
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting Yêu cầu này cố gắng đặt giấy phép không hợp lệ cho video.
forbidden (403) forbiddenPrivacySetting Yêu cầu này tìm cách thiết lập một chế độ cài đặt quyền riêng tư không hợp lệ cho video.

Hãy dùng thử!

Dùng APIs Explorer để gọi API này cũng như xem yêu cầu và phản hồi của API.