videos.insert
엔드포인트를 통해 업로드된 모든 동영상은 비공개 보기 모드로 제한됩니다. 이 제한을 해제하려면 각 API 프로젝트가 감사를 실시하여 서비스 약관을 준수하는지 확인해야 합니다. 자세한 내용은 API 버전 기록을 참고하세요.
YouTube에 동영상을 업로드하고 동영상의 메타데이터를 선택적으로 설정합니다.
이 메서드는 미디어 업로드를 지원합니다. 업로드한 파일은 다음 제한사항을 따라야 합니다.
- 최대 파일 크기: 256GB
- 허용되는 미디어 MIME 유형:
video/*
,application/octet-stream
할당량 영향: 이 메서드를 호출하면 할당량 비용이 1,600단위가 됩니다.
일반적인 사용 사례
요청
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 매개변수는 이 작업에서 두 가지 용도로 사용됩니다. 쓰기 작업에서 설정할 속성과 API 응답에 포함되는 속성을 식별합니다.동영상 삽입 또는 업데이트 시 설정할 수 있는 속성이 모든 부분에 포함되어 있는 것은 아닙니다. 예를 들어 statistics 객체는 YouTube에서 동영상에 대해 계산하는 통계를 캡슐화하며 설정하거나 수정할 수 있는 값을 포함하지 않습니다. 매개변수 값이 변경 가능한 값을 포함하지 않는 part 를 지정하는 경우에도 해당 part 는 API 응답에 포함됩니다.다음 목록에는 매개변수 값에 포함할 수 있는 part 이름이 포함되어 있습니다.
|
|
선택적 매개변수 | ||
notifySubscribers |
boolean notifySubscribers 매개변수는 YouTube가 동영상의 채널을 구독하는 사용자에게 새 동영상에 관한 알림을 전송해야 하는지 여부를 나타냅니다. 매개변수 값이 True 이면 구독자에게 새로 업로드된 동영상에 대한 알림이 전송됨을 나타냅니다. 하지만 동영상을 많이 업로드하는 채널 소유자는 채널 구독자에게 새 동영상마다 알림을 보내지 않도록 값을 False 로 설정하는 것이 좋습니다. 기본값은 True 입니다. |
|
onBehalfOfContentOwner |
string 이 매개변수는 적절하게 승인된 요청에서만 사용할 수 있습니다. 참고: 이 매개변수는 YouTube 콘텐츠 파트너 전용입니다. onBehalfOfContentOwner 매개변수는 요청의 승인 사용자 인증 정보가 매개변수 값에 지정된 콘텐츠 소유자를 대신하는 YouTube CMS 사용자를 식별함을 나타냅니다. 이 매개변수는 여러 YouTube 채널을 소유하고 관리하는 YouTube 콘텐츠 파트너를 위해 마련되었습니다. 콘텐츠 소유자는 한 번 인증하면 개별 채널에 대한 인증 사용자 인증 정보를 제공하지 않고도 모든 동영상 및 채널 데이터에 액세스할 수 있습니다. 사용자가 인증할 CMS 계정은 지정된 YouTube 콘텐츠 소유자에게 연결되어야 합니다. |
|
onBehalfOfContentOwnerChannel |
string 이 매개변수는 적절하게 승인된 요청에서만 사용할 수 있습니다. 이 매개변수는 적절하게 승인된 요청에서만 사용할 수 있습니다. 참고: 이 매개변수는 YouTube 콘텐츠 파트너만 사용할 수 있습니다. onBehalfOfContentOwnerChannel 매개변수는 동영상이 추가되는 채널의 YouTube 채널 ID를 지정합니다. 이 매개변수는 요청에서 onBehalfOfContentOwner 매개변수의 값을 지정하는 경우에 필요하며 해당 매개변수와 함께만 사용할 수 있습니다. 또한 요청은 onBehalfOfContentOwner 매개변수가 지정하는 콘텐츠 소유자와 연결된 CMS 계정을 사용하여 승인되어야 합니다. 마지막으로 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
status.containsSyntheticMedia
recordingDetails.recordingDate
응답
성공하는 경우 이 메소드는 응답 본문에 video 리소스를 반환합니다.
예
참고: 다음 코드 샘플은 지원되는 일부 프로그래밍 언어를 나타내지 않을 수도 있습니다. 지원되는 언어 목록은 클라이언트 라이브러리 문서를 참고하세요.
Go
이 코드 샘플은 API의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
다음 코드 샘플은 API의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
이 샘플은 API의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
오류
다음 표에는 이 메서드 호출에 대한 응답으로 API에서 반환할 수 있는 오류 메시지가 나와 있습니다. 자세한 내용은 오류 메시지 설명서를 참조하세요.
오류 유형 | 오류 세부정보 | 설명 |
---|---|---|
badRequest (400) |
defaultLanguageNotSet |
동영상 세부정보의 기본 언어를 지정하지 않고 현지화된 동영상 세부정보를 추가하려는 요청입니다. |
badRequest (400) |
invalidCategoryId |
snippet.categoryId 속성이 잘못된 카테고리 ID를 지정합니다. 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를 사용하여 이 API를 호출하고 API 요청 및 응답을 확인합니다.