Videos: insert

Tất cả video được tải lên thông 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ỏ 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 thông tin chi tiết.

Tải video lên YouTube và tuỳ chọn thiết lập siêu dữ liệu cho video.

Phương thức này hỗ trợ việc tải nội dung nghe nhìn lên. Các tệp đã tải lên phải tuân thủ những quy định 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

Mức tác động cho hạn mức: Một lệnh gọi đến phương thức này có chi phí định 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 yêu cầu uỷ quyền có ít nhất một trong các phạm vi sau (đọc thêm về xác thực và cấp phép).

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

Các tham số

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

Các tham số
Các thông số bắt buộc
part string
Tham số part phục vụ hai mục đích trong hoạt động này. Thẻ 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 sẽ đưa vào.

Lưu ý rằng không phải tất cả các phần đều 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 các số liệu thống kê mà YouTube tính toán cho một video và không chứa những 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 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
Tham số không bắt buộc
notifySubscribers boolean
Thông số notifySubscribers cho biết liệu 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ị thông số của True cho biết rằng người đăng ký sẽ nhận được thông báo về các 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ề mỗi video mới cho người đăng ký 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 phù hợp. Lưu ý: Tham số này chỉ dành cho các đối tác nội dung của YouTube.

Tham số onBehalfOfContentOwner cho biết rằng thông tin cấp phép của yêu cầu xác định người dùng CMS của YouTube đang thay mặt chủ sở hữu nội dung được chỉ định trong giá trị tham số. Tham số này dành cho các đối tác nội dung 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à truy cập vào tất cả dữ liệu 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 đã chỉ định.
onBehalfOfContentOwnerChannel 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 phù hợp. Bạn chỉ có thể sử dụng tham số này trong một yêu cầu được ủy quyền phù hợp. Lưu ý: Tham số này chỉ dành cho các đối tác nội dung trên YouTube.

Tham số onBehalfOfContentOwnerChannel chỉ định mã nhận dạng kênh YouTube của kênh mà bạn sẽ thêm video vào. Bạn bắt buộc phải sử dụng tham số này khi yêu cầu chỉ định một giá trị cho tham số onBehalfOfContentOwner và chỉ có thể sử dụng tham số này cùng với tham số đó. Ngoài ra, yêu cầu này phải được cho phép 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 YouTube sở hữu và quản lý nhiều kênh YouTube. Cho phép chủ sở hữu nội dung xác thực một lần và thay mặt kênh được chỉ định trong giá trị tham số mà không phải cung cấp thông tin xác thực cho từng kênh.

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
    • 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 ý: Những mã mẫu sau đây có thể không đại diện cho một số 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 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 các thông báo lỗi mà API có thể trả về khi một 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 cho 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ệ. Hãy 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 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 các từ khóa 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ức phân loại trò chơi điện tử không hợp lệ.
badRequest (400) invalidVideoMetadata Siêu dữ liệu về yêu cầu là không hợp lệ.
badRequest (400) mediaBodyRequired Yêu cầu này không bao gồm nội dung video.
badRequest (400) uploadLimitExceeded Người dùng đã vượt quá số lượng video mà họ có thể tải lên.
forbidden (403) forbidden
forbidden (403) forbiddenLicenseSetting Yêu cầu cố gắng đặt một giấy phép không hợp lệ cho video.
forbidden (403) forbiddenPrivacySetting Yêu cầu cố gắng đặt một cài đặt bảo mật không hợp lệ cho video.

Hãy dùng thử!

Hãy 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.