今回は、YouTubeAPIを初めて利用した際のメモとなります。
Google Cloudの設定から、YouTube動画検索用のサンプルコードを動かしてみるところまでの内容です。
目次
環境
- Java:AmazonCorretto 11.0.3
- Intellij:2021.2.2 Ultimate Edition
- macOS:Big Sur 11.5.2
プロジェクト作成
GCPにログインします。
プロジェクト選択の部分からプロジェクトを作成します。
新しいプロジェクトボタンをクリックします。
新しいプロジェクト作成画面が表示されたら、プロジェクト名を指定して作成します。
プロジェクト設定 API有効化
プロジェクトを作成したら、プロジェクトで利用できるAPIの設定を行います。
メニューのAPIとサービス -> 有効なAPIとサービスをクリックします。
APIとサービスの有効化をクリックします。
YouTubeのAPIを検索してクリックします。
有効にするボタンをクリックして有効化します。
OAuth 同意画面 設定
OAuth 同意画面の設定を行います。
OAuth 同意画面とは、APIを外部に公開する際に表示する認証画面のことなのですが、
外部に公開する必要がない場合も設定は必要です。
メニューよりOAuth 同意画面を開きます。
APIの用途にもよりますが、今回はどこかに公開などは行いませんので、
User Typeは内部を選択して、作成ボタンをクリックします。
続けてアプリ名などを入力して、アプリの登録を行います。
認証情報 APIキー発行
続けて、APIを実行する際の認証設定を行い、APIキーを発行します。
メニューの認証情報をクリックして、認証情報画面を開き、認証情報を作成をクリックします。
APIキーをクリックします。
APIキーが作成されて表示されますので、内容を控えます。
※こちらのキーを漏洩すると、APIを勝手に実行されてしまいますので、
注意して管理する必要があります。
できれば、APIキー制限設定を行い、
意図しないAPI実行を行われないように予防します。
今回はYouTubeAPIだけ利用するので、YouTubeAPIだけに制限してみました。
特定のWebサイトやアプリなどから実行する場合は、アプリケーションの制限なども行います。
Javaプロジェクト作成
YouTube Data API (v3) コード サンプル
今回は、キーワードで動画を検索するサンプルコードを試しに動かしてみました。
https://developers.google.com/youtube/v3/code_samples/java#search_by_keyword
ソース・設定ファイル 用意
Search.java
公開されているサンプルコードを利用します。
今回は、ソースコード内で行われているパッケージ宣言に沿って、
src -> com.google.api.services.samples.youtube.cmdline.youtube_cmdline_search_sampleに配置しました。
※Mavenの設定を行い、ライブラリをダウンロードするまでエラーが発生します。
/*
* 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_search_sample;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
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.ResourceId;
import com.google.api.services.youtube.model.SearchListResponse;
import com.google.api.services.youtube.model.SearchResult;
import com.google.api.services.youtube.model.Thumbnail;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* Prints a list of videos based on a search term.
*
* @author Jeremy Walker
*/
public class Search {
/** Global instance properties filename. */
private static String PROPERTIES_FILENAME = "youtube.properties";
/** 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 the max number of videos we want returned (50 = upper limit per page). */
private static final long NUMBER_OF_VIDEOS_RETURNED = 25;
/** Global instance of Youtube object to make all API requests. */
private static YouTube youtube;
/**
* Initializes YouTube object to search for videos on YouTube (Youtube.Search.List). The program
* then prints the names and thumbnails of each of the videos (only first 50 videos).
*
* @param args command line args.
*/
public static void main(String[] args) {
// Read the developer key from youtube.properties
Properties properties = new Properties();
try {
InputStream in = Search.class.getResourceAsStream("/" + PROPERTIES_FILENAME);
properties.load(in);
} catch (IOException e) {
System.err.println("There was an error reading " + PROPERTIES_FILENAME + ": " + e.getCause()
+ " : " + e.getMessage());
System.exit(1);
}
try {
/*
* The YouTube object is used to make all API requests. The last argument is required, but
* because we don't need anything initialized when the HttpRequest is initialized, we override
* the interface and provide a no-op function.
*/
youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {}
}).setApplicationName("youtube-cmdline-search-sample").build();
// Get query term from user.
String queryTerm = getInputQuery();
YouTube.Search.List search = youtube.search().list("id,snippet");
/*
* It is important to set your API key from the Google Developer Console for
* non-authenticated requests (found under the Credentials tab at this link:
* console.developers.google.com/). This is good practice and increased your quota.
*/
String apiKey = properties.getProperty("youtube.apikey");
search.setKey(apiKey);
search.setQ(queryTerm);
/*
* We are only searching for videos (not playlists or channels). If we were searching for
* more, we would add them as a string like this: "video,playlist,channel".
*/
search.setType("video");
/*
* This method reduces the info returned to only the fields we need and makes calls more
* efficient.
*/
search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)");
search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);
SearchListResponse searchResponse = search.execute();
List<SearchResult> searchResultList = searchResponse.getItems();
if (searchResultList != null) {
prettyPrint(searchResultList.iterator(), queryTerm);
}
} catch (GoogleJsonResponseException e) {
System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
+ e.getDetails().getMessage());
} catch (IOException e) {
System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
}
/*
* Returns a query term (String) from user via the terminal.
*/
private static String getInputQuery() throws IOException {
String inputQuery = "";
System.out.print("Please enter a search term: ");
BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
inputQuery = bReader.readLine();
if (inputQuery.length() < 1) {
// If nothing is entered, defaults to "YouTube Developers Live."
inputQuery = "YouTube Developers Live";
}
return inputQuery;
}
/*
* Prints out all SearchResults in the Iterator. Each printed line includes title, id, and
* thumbnail.
*
* @param iteratorSearchResults Iterator of SearchResults to print
*
* @param query Search query (String)
*/
private static void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query) {
System.out.println("\n=============================================================");
System.out.println(
" First " + NUMBER_OF_VIDEOS_RETURNED + " videos for search on \"" + query + "\".");
System.out.println("=============================================================\n");
if (!iteratorSearchResults.hasNext()) {
System.out.println(" There aren't any results for your query.");
}
while (iteratorSearchResults.hasNext()) {
SearchResult singleVideo = iteratorSearchResults.next();
ResourceId rId = singleVideo.getId();
// Double checks the kind is video.
if (rId.getKind().equals("youtube#video")) {
Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().get("default");
System.out.println(" Video Id" + rId.getVideoId());
System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
System.out.println(" Thumbnail: " + thumbnail.getUrl());
System.out.println("\n-------------------------------------------------------------\n");
}
}
}
}
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-search-sample</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>youtube-cmdline-search-sample</name>
<url>http://maven.apache.org</url>
<properties>
<project.youtube.version>v3-rev8-1.12.0-beta</project.youtube.version>
<project.http.version>1.12.0-beta</project.http.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>
</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_search_sample.Search</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>
さらに、サンプルコードの内容に合わせたpropertiesファイルを用意します。
Search.javaの46ステップあたりでプロパティファイル名を指定しているので、同一のファイルを用意します。
99行目あたりでプロパティファイルの内容を読み込んでいます。
youtube.properties
内容はAPIキーをサンプルコードから呼び出せるように記述します。
APIキーを記述するので、誤って公開しないように注意します。
ファイルの位置は、そのままのソース内容でも読み込まれるように、srcフォルダ内に配置しました。
youtube.apikey=APIキー
Maven 設定
サンプルにpom.xmlが含まれていたので、今回はMavenでビルド設定を行います。
gradleで行いたい方は、pom.xmlを破棄し、以下を参考に設定して下さい。
プロジェクトのところで右クリックメニューを開き、
Add Framework Support…をクリックします。
Add Framework Support…を開いたら、Mavenにチェックを入れてOKボタンをクリックします。
必要なライブラリがダウンロードされて、正常にビルドを行えるようになります。
実行確認
ここまで準備できたら、実行して挙動を確認します。
Search.main()を実行します。
正常に起動すれば、キーワードの入力を促されるので、
動画タイトルなどに該当しそうなキーワードを入力してエンターキーを押します。
実行結果が表示されます。
GCPの画面でも実行された形跡を確認できます。
API 料金・使用制限について
※2022/1/9時点の内容です。変更が入るかもしれませんので、適宜公式の情報を参照ください。
YouTubeAPIは、1日あたりの実行可能量をクォータという単位で取り扱っているようです。
以下に記載されている通り、1日あたり10,000クォータ使用できるようです。
10,000クォータの範囲内であれば無料で使用できるようです。
YouTube Data API – Quota and Compliance Audits
今回例に挙げたSearchですと、1回当たり100ほど消費するようです。
内容ごとに消費するクォータの量は異なり、APIの内容ごとの消費クォータ数は以下に記載されています。
YouTube Data API (v3) – Quota Calculator
IAMと管理の割り当てより、現状の使用率を確認できます。
今回の内容は以上となります。
APIキーの保管や、実行上限には注意が必要ですが、
無料でAPIを扱えるのはありがたいです。