YouTubeチャンネルの最新動画リストをWebサイトに表示する

YouTubeチャンネルの最新動画をWebサイトに表示したい時がある。
昔は簡単に出来た気がするが、制限が出来たりして手軽にはできなくなった。
目次
方法1.YouTubeのRSS Feedを使用してphpで表示
この方法は事前準備が必要ない。
以下のURLからチャンネルの最新動画リストが取得できるのでそれを利用して表示する。
https://www.youtube.com/feeds/videos.xml?channel_id=チャンネルID
しかし、YouTubeのRSS Feedの廃止や仕様変更があると使えなくなるかもしれない。また、アクセスが多くなければ大丈夫だと思うが、サイトに表示する目的でこのRSS Feedを使用してよいのか謎。
phpでGoogle JapanのYoutubeチャンネルのRSS Feedから最新動画4件を表示するサンプル。
<?php
$xml = simplexml_load_file('https://www.youtube.com/feeds/videos.xml?channel_id=UCTnRxVUPssiL7H29ON07t_Q');
$count = 0;
foreach($xml as $item){
if($item->id) {
$title = $item->title;
$id = $item->children('yt', true)->videoId[0];
$html = '<a href="https://www.youtube.com/watch?v='.$id.'" target="_blank"><img src="https://i1.ytimg.com/vi/'.$id.'/hqdefault.jpg"><br>'.$title.'<br>';
echo $html;
$count++;
}
if($count >= 4) {
break;
}
}
?>
方法2-1.YouTube Data API v3を使用してJavaScriptで表示
この方法は事前にGoogleアカウントでGoogle Cloud Platformに登録し、APIキーを発行する必要がある。面倒だし制限もあるが、たぶんこの方法でやるのが正攻法かもしれない。
ここで記載する方法は2020年3月に確認した方法なので、地味に変わっていくかもしれない。
Google Cloud Platformのページへアクセス
https://console.cloud.google.com/
初めて使うときはGoogle Cloud Platformの規約の確認が出る。確認して同意する。なんかいろいろ項目があって難しそうなサイトだが基本的に使うのは”APIとサービス”の箇所。
プロジェクトを作成する
分かりやすい名前でプロジェクトを作成。少し待つとプロジェクトが作成される。

ライブラリからYouTube Data API v3を選択し有効にする
メニューの”APIとサービス”→”ライブラリ”から、YouTube Data API v3を有効にする。

認証情報でAPIキーを作成する
メニューの”APIとサービス”→”認証情報”からAPIキーの認証情報を作成する。

表示されたAPIキーをメモっておき、”キーを制限”からとりあえず最低限の設定をする。

名前をわかりやすいものにし、APIの制限でYouTube Data API v3のみ有効にする。
アプリケーションの制限は後ほど設定する。
チャンネル最新動画のプレイリストIDを取得する
今回は最新動画を表示したいので、Youtubeチャンネルで自動的に作られる最新動画のプレイリストを取得して使用するが、別のプレイリストのIDでもかまわない。最新動画ではなく、Webサイトに表示する用のプレイリストを作るのもよいかもしれない。
前項で取得したAPIキーで以下のどちらかのURLにアクセスしてすると、チャンネル最新動画のプレイリストIDを取得出来る。
https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id=チャンネルID
&key=APIキー
https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=ユーザーID
&key=APIキー
参考として、Google JapanのYoutubeチャンネルのユーザーID(googlejapan)から取得できた内容は以下
{
"kind": "youtube#channelListResponse",
"etag": "\"SJZWTG6xR0eGuCOh2bX6w3s4F94/eUeGc3BQo3dtCHuDuRG7JuSs-50\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#channel",
"etag": "\"SJZWTG6xR0eGuCOh2bX6w3s4F94/qMTU7TUqEmJAH6NVHxTVB_DqPKA\"",
"id": "UCTnRxVUPssiL7H29ON07t_Q",
"contentDetails": {
"relatedPlaylists": {
"uploads": "UUTnRxVUPssiL7H29ON07t_Q",
"watchHistory": "HL",
"watchLater": "WL"
}
}
}
]
}
15行目の”UUTnRxVUPssiL7H29ON07t_Q”がGoogle JapanのYoutubeチャンネルの最新動画のプレイリストID。
プレイリストIDから動画情報を取得する
プレイリストIDとAPIキーを使って以下へアクセスするとプレイリストに登録されている動画情報が取得できる。
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=4
&playlistId=プレイリストID
&key=APIキー
maxResultsで取得件数を指定出来る。未指定の場合は5件取得される。
以下のような内容が取得できた。
{
"kind": "youtube#playlistItemListResponse",
"etag": "\"SJZWTG6xR0eGuCOh2bX6w3s4F94/mHRFJ0FaDfT-73Yt4aajP44syCA\"",
"nextPageToken": "CAQQAA",
"pageInfo": {
"totalResults": 921,
"resultsPerPage": 4
},
"items": [
{
"kind": "youtube#playlistItem",
"etag": "\"SJZWTG6xR0eGuCOh2bX6w3s4F94/EpfKPylDBB7S0iWZELmffT-hO6M\"",
"id": "VVVUblJ4VlVQc3NpTDdIMjlPTjA3dF9RLlY2ZmoybUNIUHJJ",
"snippet": {
"publishedAt": "2020-02-13T03:34:35.000Z",
"channelId": "UCTnRxVUPssiL7H29ON07t_Q",
"title": "使いやすいパソコンが欲しいなら... さぁ、Chromebook",
"description": "Google が目指した使いやすいパソコン。\nさぁ、Chromebook\n詳細はこちら:https://www.google.com/intl/ja_jp/chromebook/",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/V6fj2mCHPrI/default.jpg",
"width": 120,
"height": 90
},
~以下省略~
JavaScriptで表示
前項のAPIを使用し、JavaScriptでプレイリストの動画情報を取得して表示するサンプル。
idがyoutubeのdivタグの中に出力されるようにしている。
<div id="youtube"></div>
<script>
var apikey = 'APIキー';
var playlistid = 'プレイリストID';
var maxresults = '4';
var url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults='+maxresults +'&playlistId='+playlistid+'&key='+apikey;
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
var html = "";
var thumbnail = "";
var videoid = "";
var title = "";
for(var i in json.items){
thumbnail = json.items[i].snippet.thumbnails.high ? json.items[i].snippet.thumbnails.high.url : json.items[i].snippet.thumbnails.default.url;
videoid = json.items[i].snippet.resourceId.videoId;
title = json.items[i].snippet.title;
html += '<a href="https://www.youtube.com/watch?v='+videoid+'"><img src="'+thumbnail+'"><br>'+title+'<br>';
}
document.getElementById('youtube').innerHTML = html;
}
}
</script>
以下のようにサムネイル・タイトル・リンクが表示出来た。

アプリケーションの制限を設定する
JavaScriptからAPIを使用する方法は、APIキーが見えてしまうため制限を設定する。Google Cloud Platformのメニューの”APIとサービス”→”認証情報”から使用しているAPIキーを選択し”アプリケーションの制限”を設定。

HTTPリファラー(ウェブサイト)を選択し、設置するページのURLを指定すると、そのページからしかAPIへアクセス出来なくなる。*のワイルドカードが使えるようなので適切に範囲を指定。
気になる点
JavaScriptでAPIに直接アクセスする方法は、ページが表示されるたびにAPIへアクセスが発生する。どのくらいで制限されるのかよく分からなかったが、アクセスが多くないサイトであれば大丈夫な気がする。
方法2-2.YouTube Data API v3を使用してJavaScriptとphpを併用して表示
JavaScriptでAPIへアクセスする方法でも大丈夫そうな気もするが、突然制限がかかって表示出来なくなっても困るので、phpでローカルにキャッシュデータを保存してそれを表示するようにする。
アプリケーションの制限をなしにする
まずは、Google Cloud PlatformからAPIキーのアプリケーションの制限をなしにする。後ほど必要に応じて設定する。
phpでAPIから取得したデータをローカルに保存する
以下をyoutube.phpとして保存する。
<?php
//Google APIキー
$apikey = 'APIキー';
//Youtube プレイストID
$playlistid = 'プレイストID';
//取得件数
$maxresults = '4';
//API URL
$url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults='.$maxresults .'&playlistId='.$playlistid.'&key='.$apikey;
//ローカルjsonファイル名
$filename = 'youtube.json';
//データ更新
function update($filename,$url){
$json = @file_get_contents($filename);
$handle = fopen($filename, 'w');
if(flock($handle, LOCK_EX)){
if($data = @file_get_contents($url)){
$json = $data;
}
fwrite($handle, $json);
}
fclose($handle);
}
//ローカルjson更新時間チェック
if(file_exists($filename)){
$updatetime = filemtime($filename);
$diff = time() - $updatetime;
if($diff >= 600) {
update($filename,$url);
}
}else{
update($filename,$url);
}
//ローカルjson出力
$json = @file_get_contents($filename);
header('Content-Type: application/json');
echo $json;
?>
youtube.phpにアクセスされるとAPIからデータを取得し、ローカルのyoutube.jsonに保存&中身を出力。アクセス時にyoutube.jsonの最終更新時間から10分以内の場合はローカルのファイルの中身を出力。
正しい書き方か分からないが、たぶん多くて1時間に6回くらいのAPIアクセスになるので制限は気にならないはず。更新頻度が低くて構わないなら1時間に1回とかでもよいかもしれない。
JavaScriptからyoutube.phpを読み込んで表示
<div id="youtube"></div>
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'youtube.php');
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
var html = "";
var thumbnail = "";
var videoid = "";
var title = "";
for(var i in json.items){
thumbnail = json.items[i].snippet.thumbnails.high ? json.items[i].snippet.thumbnails.high.url : json.items[i].snippet.thumbnails.default.url;
videoid = json.items[i].snippet.resourceId.videoId;
title = json.items[i].snippet.title;
html += '<a href="https://www.youtube.com/watch?v='+videoid+'"><img src="'+thumbnail+'"><br>'+title+'<br>';
}
document.getElementById('youtube').innerHTML = html;
}
}
</script>
読み込み先をYouTube DATA APIからローカルのyoutube.phpに変更しただけで表示部分は同じ。
アプリケーションの制限をIPアドレスにする
APIキーは直接見えないので制限なしでもよい気もするが、一応IPアドレスで制限をかけておく。phpが実行されるサーバーのIPアドレスを追加すればアクセス制限可能だった。

結果
装飾して以下のようなページが完成した。

YouTube DATA APIをちゃんと使おうとすると面倒なので、最新動画の表示であればとりあえずRSSを使ってもよい気がする。