YouTube に動画をアップロードし、オプションで動画のメタデータを設定します。 例を見る。
このメソッドはメディア アップロードをサポートしています。アップロードするファイルには、以下の制約が適用されます。
- 最大ファイルサイズ: 64 GB
- 利用可能なメディアの MIME タイプ:
video/*
、application/octet-stream
リクエスト
HTTP リクエスト
POST https://www.googleapis.com/youtube/v3/videos
承認
このリクエストは、最低でも以下のスコープの 1 つによって承認される必要があります(認証と承認の詳細については、こちらをご覧ください)。
スコープ |
---|
https://www.googleapis.com/auth/youtube.upload |
https://www.googleapis.com/auth/youtube |
https://www.googleapis.com/auth/youtubepartner |
パラメータ
下記の表は、このクエリでサポートされているパラメータの一覧です。このリストのパラメータはすべてクエリ パラメータです。
パラメータ | ||
---|---|---|
必須パラメータ | ||
part |
string この操作では、 part パラメータは 2 つの目的で使用されます。書き込み操作で設定されるプロパティの特定と API レスポンスに含まれるプロパティの特定です。パラメータ値に指定できる part 名は、snippet 、 contentDetails 、 fileDetails 、 player 、 processingDetails 、 recordingDetails 、 statistics 、 status 、 suggestions 、 topicDetails などです。ただし、これらの part すべてが、動画のメタデータを設定または更新するときに設定できるプロパティを持っているわけではありません。たとえば、statistics オブジェクトは、ある動画について YouTube が計算した統計情報をカプセル化しますが、ユーザーが設定または修正できる値は持っていません。パラメータ値で、変更可能な値を格納していない part を指定している場合でも、この part は API レスポンスに含まれます。 |
|
省略可能なパラメータ | ||
autoLevels |
boolean autoLevels パラメータは、YouTube で動画の照明と色調の自動補正を行うかどうかを示します。 |
|
onBehalfOfContentOwner |
string このパラメータは、適切に承認されたリクエストでのみ使用できます。注: このパラメータは、YouTube コンテンツ パートナー専用です。 onBehalfOfContentOwner パラメータは、リクエストの承認用認証情報が、パラメータ値で指定されたコンテンツ所有者の代理人である YouTube CMS ユーザーのものであることを示します。このパラメータは、複数の YouTube チャンネルを所有、管理している YouTube コンテンツ パートナーを対象にしています。このパラメータを使用すると、コンテンツ所有者は一度認証されれば、すべての動画やチャンネル データにアクセスできるようになります。チャンネルごとに認証情報を指定する必要はありません。ユーザー認証に使用する CMS アカウントは、指定された YouTube コンテンツ所有者にリンクされていなければなりません。 |
|
onBehalfOfContentOwnerChannel |
string このパラメータは、適切に承認されたリクエストでのみ使用できます。注: このパラメータは、YouTube コンテンツ パートナー専用です。 onBehalfOfContentOwnerChannel パラメータには、動画の追加先となる YouTube チャンネルの ID を指定します。このパラメータは、リクエストで onBehalfOfContentOwner パラメータに対する値が指定されている場合には必須で、このパラメータの組み合わせでのみ使用できます。また、このリクエストは、onBehalfOfContentOwner パラメータに指定されたコンテンツ所有者にリンクされている CMS アカウントを使用して承認する必要があります。最後に、onBehalfOfContentOwnerChannel パラメータ値で指定されたチャンネルを、onBehalfOfContentOwner パラメータで指定されたコンテンツ所有者にリンクする必要があります。このパラメータは、複数の YouTube チャンネルを所有、管理している YouTube コンテンツ パートナーを対象にしています。このパラメータを使用すると、コンテンツ所有者は一度認証されれば、パラメータ値で指定されたチャンネルの代わりにアクションを実行できるようになります。チャンネルごとに認証情報を指定する必要はありません。 |
|
stabilize |
boolean stabilize パラメータでは、カメラのブレをなくすために、YouTube で動画を修正するかどうかを指定します。 |
リクエストの本文
リクエストの本文には動画のリソースを指定します。 このリソースでは、次の点に注意してください。
-
以下のプロパティに値を設定できます。
snippet.title
snippet.description
snippet.tags[]
snippet.categoryId
status.privacyStatus
status.embeddable
status.license
status.publicStatsViewable
レスポンス
成功すると、このメソッドはレスポンスの本文で動画のリソースを返します。
例
注: 以下のコード サンプルは、サポートされているプログラミング言語すべてについて表したものではありません。サポートされている言語の一覧については、クライアント ライブラリのドキュメントを参照してください。
Java
この例では、Java クライアント ライブラリを使用しています。
-
UploadVideo.java
/* * Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.api.services.samples.youtube.cmdline.youtube_cmdline_uploadvideo_sample; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; import com.google.api.client.extensions.java6.auth.oauth2.FileCredentialStore; import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.googleapis.media.MediaHttpUploader; import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.InputStreamContent; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.youtube.YouTube; import com.google.api.services.youtube.model.Video; import com.google.api.services.youtube.model.VideoSnippet; import com.google.api.services.youtube.model.VideoStatus; import com.google.common.collect.Lists; /** * Demo of uploading a video to a user's account using the YouTube Data API (V3) with OAuth2 for * authorization. * * TODO: PLEASE NOTE, YOU MUST ADD YOUR VIDEO FILES TO THE PROJECT FOLDER TO UPLOAD THEM WITH THIS * APPLICATION! * * @author Jeremy Walker */ public class UploadVideo { /** Global instance of the HTTP transport. */ private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); /** Global instance of the JSON factory. */ private static final JsonFactory JSON_FACTORY = new JacksonFactory(); /** Global instance of Youtube object to make all API requests. */ private static YouTube youtube; /* Global instance of the format used for the video being uploaded (MIME type). */ private static String VIDEO_FILE_FORMAT = "video/*"; /** * Authorizes the installed application to access user's protected data. * * @param scopes list of scopes needed to run youtube upload. */ private static Credential authorize(List<String> scopes) throws Exception { // Load client secrets. GoogleClientSecrets clientSecrets = GoogleClientSecrets.load( JSON_FACTORY, UploadVideo.class.getResourceAsStream("/client_secrets.json")); // Checks that the defaults have been replaced (Default = "Enter X here"). if (clientSecrets.getDetails().getClientId().startsWith("Enter") || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) { System.out.println( "Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential" + "into youtube-cmdline-uploadvideo-sample/src/main/resources/client_secrets.json"); System.exit(1); } // Set up file credential store. FileCredentialStore credentialStore = new FileCredentialStore( new File(System.getProperty("user.home"), ".credentials/youtube-api-uploadvideo.json"), JSON_FACTORY); // Set up authorization code flow. GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialStore(credentialStore) .build(); // Build the local server and bind it to port 9000 LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build(); // Authorize. return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user"); } /** * Uploads user selected video in the project folder to the user's YouTube account using OAuth2 * for authentication. * * @param args command line args (not used). */ public static void main(String[] args) { // Scope required to upload to YouTube. List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.upload"); try { // Authorization. Credential credential = authorize(scopes); // YouTube object used to make all API requests. youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName( "youtube-cmdline-uploadvideo-sample").build(); // We get the user selected local video file to upload. File videoFile = getVideoFromUser(); System.out.println("You chose " + videoFile + " to upload."); // Add extra information to the video before uploading. Video videoObjectDefiningMetadata = new Video(); /* * Set the video to public, so it is available to everyone (what most people want). This is * actually the default, but I wanted you to see what it looked like in case you need to set * it to "unlisted" or "private" via API. */ VideoStatus status = new VideoStatus(); status.setPrivacyStatus("public"); videoObjectDefiningMetadata.setStatus(status); // We set a majority of the metadata with the VideoSnippet object. VideoSnippet snippet = new VideoSnippet(); /* * The Calendar instance is used to create a unique name and description for test purposes, so * you can see multiple files being uploaded. You will want to remove this from your project * and use your own standard names. */ Calendar cal = Calendar.getInstance(); snippet.setTitle("Test Upload via Java on " + cal.getTime()); snippet.setDescription( "Video uploaded via YouTube Data API V3 using the Java library " + "on " + cal.getTime()); // Set your keywords. List<String> tags = new ArrayList<String>(); tags.add("test"); tags.add("example"); tags.add("java"); tags.add("YouTube Data API V3"); tags.add("erase me"); snippet.setTags(tags); // Set completed snippet to the video object. videoObjectDefiningMetadata.setSnippet(snippet); InputStreamContent mediaContent = new InputStreamContent( VIDEO_FILE_FORMAT, new BufferedInputStream(new FileInputStream(videoFile))); mediaContent.setLength(videoFile.length()); /* * The upload command includes: 1. Information we want returned after file is successfully * uploaded. 2. Metadata we want associated with the uploaded video. 3. Video file itself. */ YouTube.Videos.Insert videoInsert = youtube.videos() .insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent); // Set the upload type and add event listener. MediaHttpUploader uploader = videoInsert.getMediaHttpUploader(); /* * Sets whether direct media upload is enabled or disabled. True = whole media content is * uploaded in a single request. False (default) = resumable media upload protocol to upload * in data chunks. */ uploader.setDirectUploadEnabled(false); MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() { public void progressChanged(MediaHttpUploader uploader) throws IOException { switch (uploader.getUploadState()) { case INITIATION_STARTED: System.out.println("Initiation Started"); break; case INITIATION_COMPLETE: System.out.println("Initiation Completed"); break; case MEDIA_IN_PROGRESS: System.out.println("Upload in progress"); System.out.println("Upload percentage: " + uploader.getProgress()); break; case MEDIA_COMPLETE: System.out.println("Upload Completed!"); break; case NOT_STARTED: System.out.println("Upload Not Started!"); break; } } }; uploader.setProgressListener(progressListener); // Execute upload. Video returnedVideo = videoInsert.execute(); // Print out returned results. System.out.println("\n================== Returned Video ==================\n"); System.out.println(" - Id: " + returnedVideo.getId()); System.out.println(" - Title: " + returnedVideo.getSnippet().getTitle()); System.out.println(" - Tags: " + returnedVideo.getSnippet().getTags()); System.out.println(" - Privacy Status: " + returnedVideo.getStatus().getPrivacyStatus()); System.out.println(" - Video Count: " + returnedVideo.getStatistics().getViewCount()); } catch (GoogleJsonResponseException e) { System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage()); e.printStackTrace(); } catch (IOException e) { System.err.println("IOException: " + e.getMessage()); e.printStackTrace(); } catch (Throwable t) { System.err.println("Throwable: " + t.getMessage()); t.printStackTrace(); } } /** * Gets the user selected local video file to upload. */ private static File getVideoFromUser() throws IOException { File[] listOfVideoFiles = getLocalVideoFiles(); return getUserChoice(listOfVideoFiles); } /** * Gets an array of videos in the current directory. */ private static File[] getLocalVideoFiles() throws IOException { File currentDirectory = new File("."); System.out.println("Video files from " + currentDirectory.getAbsolutePath() + ":"); // Filters out video files. This list of video extensions is not comprehensive. FilenameFilter videoFilter = new FilenameFilter() { public boolean accept(File dir, String name) { String lowercaseName = name.toLowerCase(); if (lowercaseName.endsWith(".webm") || lowercaseName.endsWith(".flv") || lowercaseName.endsWith(".f4v") || lowercaseName.endsWith(".mov") || lowercaseName.endsWith(".mp4")) { return true; } else { return false; } } }; return currentDirectory.listFiles(videoFilter); } /** * Outputs video file options to the user, records user selection, and returns the video (File * object). * * @param videoFiles Array of video File objects */ private static File getUserChoice(File videoFiles[]) throws IOException { if (videoFiles.length < 1) { throw new IllegalArgumentException("No video files in this directory."); } for (int i = 0; i < videoFiles.length; i++) { System.out.println(" " + i + " = " + videoFiles[i].getName()); } BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in)); String inputChoice; do { System.out.print("Choose the number of the video file you want to upload: "); inputChoice = bReader.readLine(); } while (!isValidIntegerSelection(inputChoice, videoFiles.length)); return videoFiles[Integer.parseInt(inputChoice)]; } /** * Checks if string contains a valid, positive integer that is less than max. Please note, I am * not testing the upper limit of an integer (2,147,483,647). I just go up to 999,999,999. * * @param input String to test. * @param max Integer must be less then this Maximum number. */ public static boolean isValidIntegerSelection(String input, int max) { if (input.length() > 9) return false; boolean validNumber = false; // Only accepts positive numbers of up to 9 numbers. Pattern intsOnly = Pattern.compile("^\\d{1,9}$"); Matcher makeMatch = intsOnly.matcher(input); if (makeMatch.find()) { int number = Integer.parseInt(makeMatch.group()); if ((number >= 0) && (number < max)) { validNumber = true; } } return validNumber; } }
-
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.google.api.services.samples.youtube.cmdline</groupId> <artifactId>youtube-cmdline-uploadvideo-sample</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>youtube-cmdline-uploadvideo-sample</name> <url>http://maven.apache.org</url> <properties> <project.youtube.version>v3-rev24-1.13.2-beta</project.youtube.version> <project.http.version>1.13.1-beta</project.http.version> <project.oauth.version>1.13.1-beta</project.oauth.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <repositories> <repository> <id>google-api-services</id> <url>http://google-api-client-libraries.appspot.com/mavenrepo</url> </repository> </repositories> <dependencies> <!-- YouTube Data V3 support --> <dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-youtube</artifactId> <version>${project.youtube.version}</version> </dependency> <dependency> <groupId>com.google.http-client</groupId> <artifactId>google-http-client-jackson2</artifactId> <version>${project.http.version}</version> </dependency> <dependency> <groupId>com.google.oauth-client</groupId> <artifactId>google-oauth-client-jetty</artifactId> <version>${project.oauth.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <mainClass>com.google.api.services.samples.youtube.cmdline.youtube_cmdline_uploadvideo_sample.UploadVideo</mainClass> </configuration> </plugin> <!-- Forces Maven to use Java 1.6 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> <compilerArgument></compilerArgument> </configuration> </plugin> </plugins> </build> </project>
-
client_secrets.json
{ "installed": { "client_id": "Enter Client ID", "client_secret": "Enter Client Secret" } }
.NET
この例では、.NET クライアント ライブラリを使用しています。
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Threading; /* * External dependencies, OAuth 2.0 support, and core client libraries are at: * https://developers.google.com/api-client-library/dotnet/apis/ * Also see the Samples.zip file for the Google.Apis.Samples.Helper classes at: * https://github.com/youtube/api-samples/tree/master/dotnet */ using DotNetOpenAuth.OAuth2; using Google.Apis.Authentication; using Google.Apis.Authentication.OAuth2; using Google.Apis.Authentication.OAuth2.DotNetOpenAuth; using Google.Apis.Samples.Helper; using Google.Apis.Services; using Google.Apis.Util; using Google.Apis.Youtube.v3; using Google.Apis.Youtube.v3.Data; namespace dotnet { class upload_video { static void Main(string[] args) { CommandLine.EnableExceptionHandling(); CommandLine.DisplayGoogleSampleHeader("YouTube Data API: Upload Video"); var credentials = PromptingClientCredentials.EnsureFullClientCredentials(); var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description) { ClientIdentifier = credentials.ClientId, ClientSecret = credentials.ClientSecret }; var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization); var youtube = new YoutubeService(new BaseClientService.Initializer() { Authenticator = auth }); var video = new Video(); video.Snippet = new VideoSnippet(); video.Snippet.Title = CommandLine.RequestUserInput<string>("Video title"); video.Snippet.Description = CommandLine.RequestUserInput<string>("Video description"); video.Snippet.Tags = new string[] { "tag1", "tag2" }; // See https://developers.google.com/youtube/v3/docs/videoCategories/list video.Snippet.CategoryId = "22"; video.Status = new VideoStatus(); video.Status.PrivacyStatus = CommandLine.RequestUserInput<string>("Video privacy (public, private, or unlisted)"); var filePath = CommandLine.RequestUserInput<string>("Path to local video file"); var fileStream = new FileStream(filePath, FileMode.Open); var videosInsertRequest = youtube.Videos.Insert(video, "snippet,status", fileStream, "video/*"); videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged; videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived; var uploadThread = new Thread(() => videosInsertRequest.Upload()); uploadThread.Start(); uploadThread.Join(); CommandLine.PressAnyKeyToExit(); } static void videosInsertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress obj) { CommandLine.WriteLine(String.Format("{0} bytes sent.", obj.BytesSent)); } static void videosInsertRequest_ResponseReceived(Video obj) { CommandLine.WriteLine(String.Format("Video id {0} was successfully uploaded.", obj.Id)); } private static IAuthorizationState GetAuthorization(NativeApplicationClient client) { var storage = MethodBase.GetCurrentMethod().DeclaringType.ToString(); var key = "storage_key"; IAuthorizationState state = AuthorizationMgr.GetCachedRefreshToken(storage, key); if (state != null) { client.RefreshToken(state); } else { state = AuthorizationMgr.RequestNativeAuthorization(client, YoutubeService.Scopes.YoutubeUpload.GetStringValue()); AuthorizationMgr.SetCachedRefreshToken(storage, key, state); } return state; } } }
PHP
この例では、PHP クライアント ライブラリを使用しています。
<?php /** * Library Requirements * * 1. Install composer (https://getcomposer.org) * 2. On the command line, change to this directory (api-samples/php) * 3. Require the google/apiclient library * $ composer require google/apiclient:~2.0 */ if (!file_exists(__DIR__ . '/vendor/autoload.php')) { throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"'); } require_once __DIR__ . '/vendor/autoload.php'; session_start(); /* * You can acquire an OAuth 2.0 client ID and client secret from the * Google API Console <https://console.cloud.google.com/> * For more information about using OAuth 2.0 to access Google APIs, please see: * <https://developers.google.com/youtube/v3/guides/authentication> * Please ensure that you have enabled the YouTube Data API for your project. */ $OAUTH2_CLIENT_ID = 'REPLACE_ME'; $OAUTH2_CLIENT_SECRET = 'REPLACE_ME'; $client = new Google_Client(); $client->setClientId($OAUTH2_CLIENT_ID); $client->setClientSecret($OAUTH2_CLIENT_SECRET); $client->setScopes('https://www.googleapis.com/auth/youtube'); $redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'], FILTER_SANITIZE_URL); $client->setRedirectUri($redirect); // Define an object that will be used to make all API requests. $youtube = new Google_Service_YouTube($client); // Check if an auth token exists for the required scopes $tokenSessionKey = 'token-' . $client->prepareScopes(); if (isset($_GET['code'])) { if (strval($_SESSION['state']) !== strval($_GET['state'])) { die('The session state did not match.'); } $client->authenticate($_GET['code']); $_SESSION[$tokenSessionKey] = $client->getAccessToken(); header('Location: ' . $redirect); } if (isset($_SESSION[$tokenSessionKey])) { $client->setAccessToken($_SESSION[$tokenSessionKey]); } // Check to ensure that the access token was successfully acquired. if ($client->getAccessToken()) { $htmlBody = ''; try{ // REPLACE this value with the path to the file you are uploading. $videoPath = "/path/to/file.mp4"; // Create a snippet with title, description, tags and category ID // Create an asset resource and set its snippet metadata and type. // This example sets the video's title, description, keyword tags, and // video category. $snippet = new Google_Service_YouTube_VideoSnippet(); $snippet->setTitle("Test title"); $snippet->setDescription("Test description"); $snippet->setTags(array("tag1", "tag2")); // Numeric video category. See // https://developers.google.com/youtube/v3/docs/videoCategories/list $snippet->setCategoryId("22"); // Set the video's status to "public". Valid statuses are "public", // "private" and "unlisted". $status = new Google_Service_YouTube_VideoStatus(); $status->privacyStatus = "public"; // Associate the snippet and status objects with a new video resource. $video = new Google_Service_YouTube_Video(); $video->setSnippet($snippet); $video->setStatus($status); // Specify the size of each chunk of data, in bytes. Set a higher value for // reliable connection as fewer chunks lead to faster uploads. Set a lower // value for better recovery on less reliable connections. $chunkSizeBytes = 1 * 1024 * 1024; // Setting the defer flag to true tells the client to return a request which can be called // with ->execute(); instead of making the API call immediately. $client->setDefer(true); // Create a request for the API's videos.insert method to create and upload the video. $insertRequest = $youtube->videos->insert("status,snippet", $video); // Create a MediaFileUpload object for resumable uploads. $media = new Google_Http_MediaFileUpload( $client, $insertRequest, 'video/*', null, true, $chunkSizeBytes ); $media->setFileSize(filesize($videoPath)); // Read the media file and upload it chunk by chunk. $status = false; $handle = fopen($videoPath, "rb"); while (!$status && !feof($handle)) { $chunk = fread($handle, $chunkSizeBytes); $status = $media->nextChunk($chunk); } fclose($handle); // If you want to make other calls after the file upload, set setDefer back to false $client->setDefer(false); $htmlBody .= "<h3>Video Uploaded</h3><ul>"; $htmlBody .= sprintf('<li>%s (%s)</li>', $status['snippet']['title'], $status['id']); $htmlBody .= '</ul>'; } catch (Google_Service_Exception $e) { $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>', htmlspecialchars($e->getMessage())); } catch (Google_Exception $e) { $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>', htmlspecialchars($e->getMessage())); } $_SESSION[$tokenSessionKey] = $client->getAccessToken(); } elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') { $htmlBody = <<<END <h3>Client Credentials Required</h3> <p> You need to set <code>\$OAUTH2_CLIENT_ID</code> and <code>\$OAUTH2_CLIENT_ID</code> before proceeding. <p> END; } else { // If the user hasn't authorized the app, initiate the OAuth flow $state = mt_rand(); $client->setState($state); $_SESSION['state'] = $state; $authUrl = $client->createAuthUrl(); $htmlBody = <<<END <h3>Authorization Required</h3> <p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p> END; } ?> <!doctype html> <html> <head> <title>Video Uploaded</title> </head> <body> <?=$htmlBody?> </body> </html>
Python
この例では、Python クライアント ライブラリを使用しています。
#!/usr/bin/python import httplib import httplib2 import os import random import sys import time from apiclient.discovery import build from apiclient.errors import HttpError from apiclient.http import MediaFileUpload from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # Explicitly tell the underlying HTTP transport library not to retry, since # we are handling retry logic ourselves. httplib2.RETRIES = 1 # Maximum number of times to retry before giving up. MAX_RETRIES = 10 # Always retry when these exceptions are raised. RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected, httplib.IncompleteRead, httplib.ImproperConnectionState, httplib.CannotSendRequest, httplib.CannotSendHeader, httplib.ResponseNotReady, httplib.BadStatusLine) # Always retry when an apiclient.errors.HttpError with one of these status # codes is raised. RETRIABLE_STATUS_CODES = [500, 502, 503, 504] # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google API Console at # https://console.cloud.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # https://developers.google.com/youtube/v3/guides/authentication # For more information about the client_secrets.json file format, see: # https://developers.google.com/api-client-library/python/guide/aaa_client_secrets CLIENT_SECRETS_FILE = "client_secrets.json" # 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. YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" # This variable defines a message to display if the CLIENT_SECRETS_FILE is # missing. MISSING_CLIENT_SECRETS_MESSAGE = """ WARNING: Please configure OAuth 2.0 To make this sample run you will need to populate the client_secrets.json file found at: %s with information from the API Console https://console.cloud.google.com/ For more information about the client_secrets.json file format, please visit: https://developers.google.com/api-client-library/python/guide/aaa_client_secrets """ % os.path.abspath(os.path.join(os.path.dirname(__file__), CLIENT_SECRETS_FILE)) VALID_PRIVACY_STATUSES = ("public", "private", "unlisted") def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_UPLOAD_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: credentials = run_flow(flow, storage, args) return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=credentials.authorize(httplib2.Http())) def initialize_upload(youtube, options): tags = None if options.keywords: tags = options.keywords.split(",") body=dict( snippet=dict( title=options.title, description=options.description, tags=tags, categoryId=options.category ), status=dict( privacyStatus=options.privacyStatus ) ) # Call the API's videos.insert method to create and upload the video. insert_request = youtube.videos().insert( part=",".join(body.keys()), body=body, # The chunksize parameter specifies the size of each chunk of data, in # bytes, that will be uploaded at a time. Set a higher value for # reliable connections as fewer chunks lead to faster uploads. Set a lower # value for better recovery on less reliable connections. # # Setting "chunksize" equal to -1 in the code below means that the entire # file will be uploaded in a single HTTP request. (If the upload fails, # it will still be retried where it left off.) This is usually a best # practice, but if you're using Python older than 2.6 or if you're # running on App Engine, you should set the chunksize to something like # 1024 * 1024 (1 megabyte). media_body=MediaFileUpload(options.file, chunksize=-1, resumable=True) ) resumable_upload(insert_request) # This method implements an exponential backoff strategy to resume a # failed upload. def resumable_upload(insert_request): response = None error = None retry = 0 while response is None: try: print "Uploading file..." status, response = insert_request.next_chunk() if response is not None: if 'id' in response: print "Video id '%s' was successfully uploaded." % response['id'] else: exit("The upload failed with an unexpected response: %s" % response) except HttpError, e: if e.resp.status in RETRIABLE_STATUS_CODES: error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: raise except RETRIABLE_EXCEPTIONS, e: error = "A retriable error occurred: %s" % e if error is not None: print error retry += 1 if retry > MAX_RETRIES: exit("No longer attempting to retry.") max_sleep = 2 ** retry sleep_seconds = random.random() * max_sleep print "Sleeping %f seconds and then retrying..." % sleep_seconds time.sleep(sleep_seconds) if __name__ == '__main__': argparser.add_argument("--file", required=True, help="Video file to upload") argparser.add_argument("--title", help="Video title", default="Test Title") argparser.add_argument("--description", help="Video description", default="Test Description") argparser.add_argument("--category", default="22", help="Numeric video category. " + "See https://developers.google.com/youtube/v3/docs/videoCategories/list") argparser.add_argument("--keywords", help="Video keywords, comma separated", default="") argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES, default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.") args = argparser.parse_args() if not os.path.exists(args.file): exit("Please specify a valid file using the --file= parameter.") youtube = get_authenticated_service(args) try: initialize_upload(youtube, args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
Ruby
この例では、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 |
invalidCategoryId |
snippet.categoryId プロパティで指定されたカテゴリ ID が無効です。videoCategories.list メソッドを使用して、サポートされているカテゴリを取得してください。 |
badRequest |
invalidDescription |
リクエスト メタデータで指定された動画の説明は無効です。 |
badRequest |
invalidFilename |
Slug ヘッダーで指定された動画ファイル名は無効です。 |
badRequest |
invalidRecordingDetails |
リクエスト メタデータの recordingDetails オブジェクトで指定された録画の詳細は無効です。 |
badRequest |
invalidTags |
リクエスト メタデータで指定された動画のキーワードは無効です。 |
badRequest |
invalidTitle |
リクエスト メタデータで指定された動画のタイトルは無効です。 |
badRequest |
invalidVideoGameRating |
リクエスト メタデータで指定されたビデオ ゲームの評価は無効です。 |
badRequest |
invalidVideoMetadata |
リクエスト メタデータが無効です。 |
badRequest |
mediaBodyRequired |
リクエストに動画コンテンツが含まれていません。 |
forbidden |
forbiddenLicenseSetting |
リクエストは、動画に無効なライセンスを設定しようとしています。 |
forbidden |
forbiddenPrivacySetting |
リクエストは、動画に無効なプライバシー設定を指定しようとしています。 |