YouTube APIを使って視聴数ランキングを表示する(PHP)

特定チャンネルの動画を視聴数順で取得し、ランキング表示する実装方法を解説します。今回は「直近3ヶ月以内に投稿された動画」に絞ったランキング取得を例にします。

事前準備

  1. Google Cloud Console でプロジェクトを作成
  2. YouTube Data API v3 を有効化
  3. 認証情報から APIキー を発行
  4. 対象チャンネルの チャンネルID を確認(チャンネルページのURL末尾など)

⚠️ APIキーは必ず環境変数や設定ファイルで管理し、ソースコードに直書きしないようにしましょう。

基本実装

<?php

// =============================
// 設定
// =============================
$DEVELOPER_KEY = getenv('YOUTUBE_API_KEY'); // 環境変数から取得を推奨
$CHANNEL_ID    = 'UCxxxxxxxxxxxxxxxxxxxxxxx'; // 対象チャンネルID
$MAX_RESULTS   = 5;                           // 取得件数(最大50)
$MONTHS_AGO    = 3;                           // 何ヶ月前まで遡るか

// 期間の起点日時をISO 8601形式で生成
$PERIOD = date('Y-m-d', strtotime("-{$MONTHS_AGO} month")) . 'T00:00:00Z';

// =============================
// APIリクエスト
// =============================
$params = [
    'type'          => 'video',
    'part'          => 'snippet',
    'maxResults'    => $MAX_RESULTS,
    'regionCode'    => 'JP',
    'channelId'     => $CHANNEL_ID,
    'order'         => 'viewCount', // 視聴数順(他: date / rating / relevance)
    'publishedAfter'=> $PERIOD,
    'key'           => $DEVELOPER_KEY,
];

$url    = 'https://www.googleapis.com/youtube/v3/search?' . http_build_query($params);
$result = file_get_contents($url);

if ($result === false) {
    die('APIリクエストに失敗しました。');
}

$result = json_decode($result, true);

if (isset($result['error'])) {
    die('APIエラー: ' . $result['error']['message']);
}

// =============================
// データ整形
// =============================
$rankingList = [];
foreach ($result['items'] as $item) {
    $rankingList[] = [
        'videoId'           => $item['id']['videoId'],
        'title'             => $item['snippet']['title'],
        'description'       => $item['snippet']['description'],
        'thumbnail_medium'  => $item['snippet']['thumbnails']['medium']['url'],
        'publishedAt'       => $item['snippet']['publishedAt'],
        'channelTitle'      => $item['snippet']['channelTitle'],
    ];
}
PHP

http_build_query() を使うと、配列から安全にURLクエリ文字列を生成できます(特殊文字の自動エスケープつき)。

HTML出力

// =============================
// 出力
// =============================
?>
<ol class="ranking-list">
<?php foreach ($rankingList as $rank => $video): ?>
    <li class="ranking-item">
        <span class="rank-number"><?= $rank + 1 ?></span>
        <a href="https://www.youtube.com/watch?v=<?= htmlspecialchars($video['videoId']) ?>" target="_blank">
            <img src="<?= htmlspecialchars($video['thumbnail_medium']) ?>"
                 alt="<?= htmlspecialchars($video['title']) ?>">
            <div class="video-info">
                <h3><?= htmlspecialchars($video['title']) ?></h3>
                <p class="published"><?= date('Y年m月d日', strtotime($video['publishedAt'])) ?></p>
                <p class="description"><?= htmlspecialchars(mb_substr($video['description'], 0, 80)) ?>...</p>
            </div>
        </a>
    </li>
<?php endforeach; ?>
</ol>
PHP

htmlspecialchars() で出力時のXSS対策を忘れずに。

視聴数も取得したい場合(videos.list の併用)

search.list のレスポンスには実際の視聴数が含まれません。視聴数を表示したい場合は、取得したビデオIDを使って videos.list を追加で呼び出す必要があります。

// videoIdをカンマ区切りで結合
$videoIds = implode(',', array_column($rankingList, 'videoId'));

$statsParams = [
    'part' => 'statistics',
    'id'   => $videoIds,
    'key'  => $DEVELOPER_KEY,
];

$statsUrl    = 'https://www.googleapis.com/youtube/v3/videos?' . http_build_query($statsParams);
$statsResult = json_decode(file_get_contents($statsUrl), true);

// rankingListに視聴数をマージ
$statsMap = [];
foreach ($statsResult['items'] as $item) {
    $statsMap[$item['id']] = $item['statistics']['viewCount'];
}

foreach ($rankingList as &$video) {
    $video['viewCount'] = $statsMap[$video['videoId']] ?? 0;
}
unset($video);
PHP

これで $video['viewCount'] に視聴数が入ります。

応用:キャッシュで API クォータを節約する

YouTube Data API v3 には**1日あたりのクォータ制限(デフォルト10,000ユニット)**があります。毎回APIを叩くのではなく、結果をファイルやDBにキャッシュしておくのがベストプラクティスです。

$cacheFile    = __DIR__ . '/cache/youtube_ranking.json';
$cacheExpiry  = 3600; // 1時間キャッシュ

if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheExpiry)) {
    // キャッシュから読み込み
    $rankingList = json_decode(file_get_contents($cacheFile), true);
} else {
    // APIから取得(上記コード)
    // ...

    // キャッシュに保存
    file_put_contents($cacheFile, json_encode($rankingList));
}
PHP

よくあるエラーと対処法

エラー内容原因対処
keyInvalidAPIキーが誤っているCloud ConsoleでAPIキーを確認
quotaExceeded1日のクォータ超過キャッシュ導入、または翌日まで待つ
forbiddenAPIが有効化されていないYouTube Data API v3 を有効化
結果が0件チャンネルIDの誤り・対象期間に動画なしチャンネルIDを再確認

まとめ

  • order=viewCount + publishedAfter で期間絞り込みランキングが取得できる
  • 実際の視聴数表示は videos.list との2段階取得が必要
  • APIキーは環境変数管理 & 結果はキャッシュでクォータを節約
  • 出力時は必ず htmlspecialchars() でXSS対策を行う

read next