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 | stringpart매개변수는 이 작업에서 두 가지 용도로 사용됩니다. 쓰기 작업에서 설정할 속성과 API 응답에 포함되는 속성을 식별합니다.동영상 삽입 또는 업데이트 시 설정할 수 있는 속성이 모든 부분에 포함되어 있는 것은 아닙니다. 예를 들어 statistics객체는 YouTube에서 동영상에 대해 계산하는 통계를 캡슐화하며 설정하거나 수정할 수 있는 값을 포함하지 않습니다. 매개변수 값이 변경 가능한 값을 포함하지 않는part를 지정하는 경우에도 해당part는 API 응답에 포함됩니다.다음 목록에는 매개변수 값에 포함할 수 있는 part이름이 포함되어 있습니다.
 | |
| 선택적 매개변수 | ||
| notifySubscribers | booleannotifySubscribers매개변수는 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 요청 및 응답을 확인합니다.