Videos: insert

Tất cả video được tải lên qua điểm cuối videos.insert từ các 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, từng 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ính năng 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
  • Các 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à 1.600 đơ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 yêu cầu uỷ quyền với ít nhất một trong các phạm vi sau (đọc thêm về việc 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

Thông số

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

Thông 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. Phương thức này xác định các thuộc tính mà thao tác ghi sẽ thiết lập cũng như các thuộc tính mà phản hồi API sẽ bao gồm.

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ể được thiết lập 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 một 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 các giá trị có thể thay đổi, thì part đó sẽ vẫn được đưa vào phản hồi của 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
  • paidProductPlacementDetails
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
Thông số tuỳ chọn
notifySubscribers boolean
Thông số notifySubscribers cho biết YouTube có nên 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ố True cho biết người đăng ký sẽ được thông báo về các video mới tải lên. Tuy nhiên, chủ sở hữu kênh tải nhiều video lên có thể nên đặt giá trị này 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ể sử dụng thông số này trong một yêu cầu được uỷ quyền hợp lệ. Lưu ý: Tham số này chỉ dành cho đối tác nội dung của YouTube.

Tham số onBehalfOfContentOwner cho biết thông tin uỷ quyền của yêu cầu 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ố. Tham 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. 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 về video và kênh của họ 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 YouTube được chỉ định.
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 phù hợp. Bạn chỉ có thể sử dụng thông số này trong một yêu cầu được uỷ quyền hợp lệ. Lưu ý: Thông số này chỉ dành riêng cho các đối tác nội dung trên YouTube.

Thông số onBehalfOfContentOwnerChannel chỉ định mã nhận dạng kênh YouTube của kênh mà bạn đang thêm video. Tham số này là bắt buộc khi một yêu cầu chỉ định giá trị cho tham số onBehalfOfContentOwner và chỉ có thể được sử dụng cùng với tham số đó. Ngoài ra, yêu cầu phải được uỷ quyền bằng tài khoản CMS được 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. Thẻ 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 hành động 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 phần nội dung yêu cầu. Đối với tài nguyên đó:

  • Bạn có thể đặt giá trị cho các 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
    • status.containsSyntheticMedia
    • 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 phần nội dung phản hồi.

Ví dụ

Lưu ý: Các đoạn 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ợ. Hãy xem tài liệu về thư viện ứng dụng để biết danh sách 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 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 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 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 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 thông tin chi tiết.

Loại lỗi Thông tin chi tiết về lỗi Mô tả
badRequest (400) defaultLanguageNotSet Yêu cầu này đang cố gắng thêm thông tin chi tiết về video đã bản địa hoá mà không chỉ định ngôn ngữ mặc định của thông tin chi tiết về 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 yêu cầu chỉ định 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 yêu cầu chỉ định thời gian phát hành 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 yêu cầu chỉ định các từ khoá video không hợp lệ.
badRequest (400) invalidTitle Siêu dữ liệu yêu cầu chỉ định tiêu đề video không hợp lệ hoặc trống.
badRequest (400) invalidVideoGameRating Siêu dữ liệu yêu cầu chỉ định 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 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ố lượng video được phép 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 cố gắng đặt chế độ cài đặt quyền riêng tư không hợp lệ cho video.

Hãy dùng thử!

Sử dụng APIs Explorer để gọi API này và xem yêu cầu và phản hồi API.