Videos: insert

إنّ كل الفيديوهات التي تم تحميلها باستخدام نقطة النهاية videos.insert من مشاريع واجهة برمجة تطبيقات لم يتم التحقق منها والتي تم إنشاؤها بعد 28 تموز (يوليو) 2020 ستقتصر على وضع المشاهدة الخاص. لرفع هذا الشرط، يجب أن يخضع كل مشروع من مشاريع واجهة برمجة التطبيقات لتدقيق للتحقق من توافقه مع بنود الخدمة. يُرجى الاطّلاع على سجلّ مراجعات واجهة برمجة التطبيقات للحصول على مزيد من التفاصيل.

يحمِّل فيديو إلى YouTube ويحدّد البيانات الوصفية للفيديو اختياريًا.

تتيح هذه الطريقة تحميل الوسائط. يجب أن تتوافق الملفات المحمَّلة مع القيود التالية:

  • الحد الأقصى لحجم الملف: 256 غيغابايت
  • أنواع MIME للوسائط المقبولة: video/* وapplication/octet-stream

تأثير الحصة: تحتوي أي مكالمة إلى هذه الطريقة على تكلفة حصة تبلغ 1600 وحدة.

حالات الاستخدام الشائعة

الطلب

طلب HTTP

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

التفويض

يتطلب هذا الطلب تفويضًا باستخدام نطاق واحد على الأقل من النطاقات التالية (مزيد من المعلومات عن المصادقة والترخيص).

النطاق
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 لغرضَين في هذه العملية. وهي تحدد الخصائص التي ستضبطها عملية الكتابة والخصائص التي ستتضمّنها استجابة واجهة برمجة التطبيقات.

يُرجى العِلم أنّ بعض الأجزاء لا تحتوي على خصائص يمكن ضبطها عند إدراج فيديو أو تعديله. على سبيل المثال، يحتوي الكائن statistics على إحصاءات تحتسبها منصة YouTube لفيديو معيّن ولا يحتوي على قيم يمكنك ضبطها أو تعديلها. إذا كانت قيمة المعلَمة تحدد part لا يحتوي على قيم قابلة للتغيير، سيتم تضمين part في استجابة واجهة برمجة التطبيقات.

تحتوي القائمة التالية على أسماء part التي يمكنك تضمينها في قيمة المعلَمة:
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
المَعلمات الاختيارية
notifySubscribers boolean
تحدّد المَعلمة notifySubscribers ما إذا كان يجب على YouTube إرسال إشعار حول الفيديو الجديد إلى المستخدمين الذين يشتركون في القناة التي تعرض الفيديو. تشير قيمة المعلَمة True إلى أنّه سيتم إشعار المشتركين بالفيديوهات الجديدة التي يتم تحميلها. مع ذلك، قد يفضّل مالك القناة الذي يحمِّل العديد من الفيديوهات ضبط القيمة على False لتجنُّب إرسال إشعار إلى المشتركين في القناة بشأن كل فيديو جديد. القيمة التلقائية هي True.
onBehalfOfContentOwner string
لا يمكن استخدام هذه المَعلمة إلا في طلب معتمد بشكل صحيح. ملاحظة: هذه المَعلمة مخصّصة حصريًا لشركاء المحتوى في YouTube.

تشير المَعلمة onBehalfOfContentOwner إلى أنّ بيانات اعتماد التفويض الخاصة بالطلب تحدِّد مستخدم نظام "إدارة محتوى YouTube" الذي يتصرّف نيابةً عن مالك المحتوى المحدَّد في قيمة المَعلمة. هذه المعلمة مخصصة لشركاء المحتوى في YouTube الذين يملكون العديد من القنوات المختلفة على YouTube ويديرونها. يسمح هذا البرنامج لمالكي المحتوى بالمصادقة مرة واحدة والوصول إلى جميع بيانات القنوات والفيديوهات الخاصة بهم، بدون الحاجة إلى تقديم بيانات اعتماد مصادقة لكل قناة على حدة. يجب أن يكون حساب نظام إدارة المحتوى الذي يصادقه المستخدم مرتبطًا بمالك المحتوى المحدد على YouTube.
onBehalfOfContentOwnerChannel string
لا يمكن استخدام هذه المَعلمة إلا في طلب معتمد بشكل صحيح. لا يمكن استخدام هذه المَعلمة إلا في طلب معتمد بشكل صحيح. ملاحظة: هذه المَعلمة مخصّصة حصريًا لشركاء المحتوى في YouTube.

تحدّد المَعلمة onBehalfOfContentOwnerChannel معرّف قناة YouTube للقناة التي تتم إضافة فيديو إليها. هذه المعلَمة مطلوبة عندما يحدِّد الطلب قيمةً للمعلَمة onBehalfOfContentOwner، ولا يمكن استخدامها إلا مع تلك المعلَمة. بالإضافة إلى ذلك، يجب أن يكون الطلب مصرّحًا به باستخدام حساب "نظام إدارة المحتوى" (CMS) المرتبط بمالك المحتوى الذي تحدّده المَعلمة onBehalfOfContentOwner. أخيرًا، يجب أن تكون القناة التي تحددها قيمة المعلَمة 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
    • status.publicStatsViewable
    • status.publishAt
    • status.selfDeclaredMadeForKids
    • recordingDetails.locationDescription (متوقّفة نهائيًا)
    • recordingDetails.location.latitude (متوقّفة نهائيًا)
    • recordingDetails.location.longitude (متوقّفة نهائيًا)
    • recordingDetails.recordingDate

الإجابة

في حال نجاح هذا الإجراء، تعرِض هذه الطريقة مورد فيديو في نص الاستجابة.

أمثلة

ملاحظة: قد لا تمثل عيّنات التعليمات البرمجية التالية جميع لغات البرمجة المتوافقة. راجِع مستندات مكتبات العملاء للحصول على قائمة باللغات المتوافقة.

البدء

يستدعي نموذج الرمز هذا طريقة 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.

يستدعي الرمز النموذجي التالي طريقة 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

يستدعي هذا النموذج طريقة 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

الأخطاء

يحدّد الجدول التالي رسائل الخطأ التي يمكن أن تعرضها واجهة برمجة التطبيقات استجابةً لطلب بيانات إلى هذه الطريقة. يُرجى الاطّلاع على وثائق رسالة الخطأ للحصول على مزيد من التفاصيل.

نوع الخطأ تفاصيل الخطأ الوصف
badRequest (400) defaultLanguageNotSet يحاول الطلب إضافة تفاصيل الفيديو المترجَم بدون تحديد اللغة التلقائية لتفاصيل الفيديو.
badRequest (400) invalidCategoryId تحدّد السمة snippet.categoryId معرّف فئة غير صالح. استخدِم طريقة 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 لطلب بيانات من واجهة برمجة التطبيقات هذه والاطّلاع على طلب البيانات من واجهة برمجة التطبيقات والاستجابة لها.