この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:8
ページ更新者:T
更新日時:2026-06-11 07:07:02

タイトル: YouTube Data API (v3)
SEOタイトル: YouTube Data API v3 入門 — 認証・主要エンドポイント・クォータ・サンプルコード

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>事前準備</strong>: Google Cloud Console でプロジェクト作成 → <strong>YouTube Data API v3</strong> 有効化 → 認証情報作成(API キー or OAuth クライアント ID)</li><li><strong>API キー</strong>: 公開データ読み取り専用(動画情報・検索など)。<strong>OAuth 2.0</strong>: 自分のチャンネル操作(アップロード・コメント投稿)に必要</li><li>主要エンドポイント: <code>videos.list</code> / <code>search.list</code> / <code>channels.list</code> / <code>playlistItems.list</code> / <code>commentThreads.list</code></li><li><strong>クォータ制限</strong>: デフォルト 10,000 ユニット/日。<code>search.list</code> = 100、<code>videos.list</code> = 1 と非常に偏る</li><li><strong>part パラメータ</strong>: 取得フィールドを指定(<code>snippet,statistics,contentDetails</code>)。多いほどレスポンスが膨らむ</li><li>JS から呼ぶ場合は <strong>gapi クライアントライブラリ</strong>。サーバ側は <code>google-api-php-client</code> / <code>google-api-python-client</code></li></ul></td></tr></table>
<h2>事前準備: Google Cloud Console</h2>

<ol>
<li><a href="https://console.cloud.google.com/">Google Cloud Console</a> にアクセス</li>
<li>新規プロジェクト作成 (または既存プロジェクト選択)</li>
<li>左メニュー <strong>API とサービス → ライブラリ</strong></li>
<li><strong>YouTube Data API v3</strong> を検索 → 有効化</li>
<li><strong>認証情報</strong> → <strong>+ 認証情報を作成</strong>:
  <ul>
    <li><strong>API キー</strong>: 公開データ読み取り用。すぐ発行</li>
    <li><strong>OAuth クライアント ID</strong>: ユーザー認可が必要な操作用。同意画面の設定が必要</li>
  </ul>
</li>
<li>API キーは <strong>HTTP リファラ制限 / IP 制限</strong>を設定してリーク対策</li>
</ol>

<h2>主要エンドポイント</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>エンドポイント</th><th>用途</th><th>クォータコスト</th></tr></thead>
<tbody>
<tr><td><code>videos.list</code></td><td>動画情報取得(指定 ID)</td><td>1</td></tr>
<tr><td><code>search.list</code></td><td>キーワード検索</td><td><strong>100</strong></td></tr>
<tr><td><code>channels.list</code></td><td>チャンネル情報</td><td>1</td></tr>
<tr><td><code>playlists.list</code></td><td>再生リスト一覧</td><td>1</td></tr>
<tr><td><code>playlistItems.list</code></td><td>再生リスト内動画</td><td>1</td></tr>
<tr><td><code>commentThreads.list</code></td><td>コメント取得</td><td>1</td></tr>
<tr><td><code>videos.insert</code></td><td>動画アップロード</td><td>1,600</td></tr>
<tr><td><code>liveBroadcasts.list</code></td><td>ライブ配信</td><td>1</td></tr>
</tbody>
</table>

<h2>JavaScript (ブラウザ) からの呼び出し</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><script src="https://apis.google.com/js/api.js"></script>
<script>
const API_KEY = &apos;YOUR_API_KEY&apos;;

async function init() {
  await gapi.load(&apos;client&apos;, async () => {
    await gapi.client.init({
      apiKey: API_KEY,
      discoveryDocs: [&apos;https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest&apos;],
    });
    searchVideos(&apos;Laravel&apos;);
  });
}

async function searchVideos(query) {
  const res = await gapi.client.youtube.search.list({
    part: &apos;snippet&apos;,
    q: query,
    type: &apos;video&apos;,
    maxResults: 10,
    order: &apos;relevance&apos;,  // date / rating / viewCount / relevance
  });

  res.result.items.forEach(item => {
    console.log(item.id.videoId, item.snippet.title);
  });
}

init();
</script></code></pre>
<h2>シンプルな HTTP リクエスト</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-bash"># API キーで動画情報取得
curl "https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id=dQw4w9WgXcQ&key=YOUR_API_KEY"

# 検索
curl "https://www.googleapis.com/youtube/v3/search?part=snippet&q=Laravel&type=video&maxResults=5&key=YOUR_API_KEY"

# チャンネル情報
curl "https://www.googleapis.com/youtube/v3/channels?part=snippet,statistics&forHandle=@GoogleDevelopers&key=YOUR_API_KEY"</code></pre>
<h2>PHP からの呼び出し</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php"><?php
// composer require google/apiclient

require __DIR__ . &apos;/vendor/autoload.php&apos;;

$client = new Google\Client();
$client->setDeveloperKey(&apos;YOUR_API_KEY&apos;);

$youtube = new Google\Service\YouTube($client);

// 検索
$response = $youtube->search->listSearch(&apos;snippet&apos;, [
    &apos;q&apos;          => &apos;Laravel チュートリアル&apos;,
    &apos;type&apos;       => &apos;video&apos;,
    &apos;maxResults&apos; => 10,
    &apos;order&apos;      => &apos;viewCount&apos;,
    &apos;regionCode&apos; => &apos;JP&apos;,
]);

foreach ($response->items as $item) {
    echo $item->id->videoId . &apos; — &apos; . $item->snippet->title . "\n";
}

// 動画詳細
$videos = $youtube->videos->listVideos(&apos;snippet,statistics,contentDetails&apos;, [
    &apos;id&apos; => &apos;dQw4w9WgXcQ&apos;,
]);

foreach ($videos->items as $v) {
    echo $v->snippet->title . "\n";
    echo "views: " . $v->statistics->viewCount . "\n";
    echo "duration: " . $v->contentDetails->duration . "\n";  // ISO 8601 PT4M13S
}</code></pre>
<h2>part パラメータの主な値</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>part 値</th><th>含まれる情報</th></tr></thead>
<tbody>
<tr><td><code>snippet</code></td><td>タイトル、説明、サムネ、公開日、チャンネル名</td></tr>
<tr><td><code>statistics</code></td><td>視聴数、いいね数、コメント数</td></tr>
<tr><td><code>contentDetails</code></td><td>動画長さ (ISO 8601)、画質、字幕有無、年齢制限</td></tr>
<tr><td><code>status</code></td><td>公開状態、組込許可、ライセンス</td></tr>
<tr><td><code>player</code></td><td>埋込用 iframe HTML</td></tr>
<tr><td><code>topicDetails</code></td><td>Wikipedia トピック関連</td></tr>
</tbody>
</table>

<p>カンマ区切りで複数指定: <code>part=snippet,statistics,contentDetails</code>。<strong>必要なものだけにしてクォータ節約</strong>。</p>

<h2>クォータ管理</h2>

<ul>
<li>デフォルト <strong>10,000 ユニット/日</strong>。日本時間 16:00 / 17:00 (PST 0:00) にリセット</li>
<li><code>search.list</code> は <strong>1 リクエスト = 100 ユニット</strong>。100 回叩くと枯渇</li>
<li>不足する場合は <strong>クォータ拡張申請</strong>(フォーム提出 → 数週間レビュー)</li>
<li>節約テク: <code>fields</code> パラメータで返却フィールドを絞る、<strong>結果キャッシュ</strong>、ID 既知なら <code>videos.list</code>(コスト 1)に切替</li>
</ul>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text"># fields パラメータ例 — 必要だけ取り出す
?part=snippet,statistics
&fields=items(id,snippet/title,statistics/viewCount)</code></pre>
<h2>OAuth が必要な操作</h2>

<p>自分のチャンネルへの<strong>動画アップロード</strong>、<strong>プレイリスト編集</strong>、<strong>コメント投稿</strong>は API キーでは不可。OAuth 2.0 認可フローが必要です:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php"><?php
$client = new Google\Client();
$client->setClientId(&apos;CLIENT_ID&apos;);
$client->setClientSecret(&apos;CLIENT_SECRET&apos;);
$client->setRedirectUri(&apos;http://localhost/oauth2callback.php&apos;);
$client->addScope(Google\Service\YouTube::YOUTUBE_UPLOAD);

if (!isset($_GET[&apos;code&apos;])) {
    header(&apos;Location: &apos; . $client->createAuthUrl());
    exit;
}

$token = $client->fetchAccessTokenWithAuthCode($_GET[&apos;code&apos;]);
$client->setAccessToken($token);

// これで OAuth 必須 API も呼べる
$youtube = new Google\Service\YouTube($client);
// $youtube->videos->insert(...)</code></pre>
<h2>FAQ</h2>

<p><strong>Q: API キーが漏洩した</strong><br />
A: Cloud Console から即座に削除し、新規発行。リファラ制限 / IP 制限を必ず設定。フロントエンド埋込は最小限の権限のみ。</p>

<p><strong>Q: search.list でフィルタしたら結果がおかしい</strong><br />
A: <code>order=relevance</code> がデフォルト。再現性が必要なら <code>order=date</code> + 日付フィルタ。<code>publishedAfter</code> / <code>publishedBefore</code> は <strong>RFC 3339</strong> 形式。</p>

<p><strong>Q: クォータが枯渇したらどうなる</strong><br />
A: <code>quotaExceeded</code> エラーで全リクエストが失敗。翌日リセットまで待つか、別プロジェクトの API キーを発行。長期的にはキャッシュ / バックエンド集約が必須。</p>