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サイトに表示する用のプレイリストを作るのもよいかもしれない。

チャンネルトップのプロフィールの更に表示の部分からチャンネルIDをコピーする。チャンネルIDの頭のUCをUUに変更したものが、そのチャンネルの最新動画のプレイリストID。

チャンネルID:UCTnRxVUPssiL7H29ON07t_Q
最新動画のプレイリストID:UUTnRxVUPssiL7H29ON07t_Q

プレイリスト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アドレスを追加すればアクセス制限可能だった。

方法3.YouTube IFrame Player APIのプレイリスト埋め込みから動画IDを取り出して表示

この方法も事前準備が必要ない。
YouTubeのIFrame Player APIで埋め込んだプレイリスト動画から各動画の動画IDを取り出して表示する。

ブラウザのJavaScriptのみで完結するので、場合によってはこの方法も便利かもしれない。

チャンネル最新動画のプレイリストIDを取得する

チャンネルトップのプロフィールの更に表示の部分からチャンネルIDをコピーする。チャンネルIDの頭のUCをUUに変更したものが、そのチャンネルの最新動画のプレイリストID。

チャンネルID:UCTnRxVUPssiL7H29ON07t_Q
最新動画のプレイリストID:UUTnRxVUPssiL7H29ON07t_Q

JavaScriptで表示

非表示状態でYoutubeのプレイリストを埋め込み表示し、そこから最新動画のIDを抜き出す。

<!-- 出力先 -->
<div id="youtube"></div>

<!-- プレイリストを非表示で埋め込む場所 -->
<div id="player" style="display: none;"></div>

<script>
//YouTube IFrame Player APIのスクリプトを読み込む
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

//読み込まれたスクリプトから呼ばれる
var onYouTubeIframeAPIReady = function() {
	var player = new YT.Player('player', {
		playerVars: {
			list: 'UUTnRxVUPssiL7H29ON07t_Q' //ここにプレイリストIDを入力
		},
		events: {
			'onReady': function(){
				var videoids = player.getPlaylist();
				var html = "";
				var thumbnail = "";
				var videoid = "";
				for(var i in videoids) {
					if(i >= 4) {
						break;
					}
					videoid = videoids[i];
					thumbnail = 'http://img.youtube.com/vi/'+videoid+'/sddefault.jpg';
					html += '<a href="https://www.youtube.com/watch?v='+videoid+'"><img src="'+thumbnail+'"><br>https://www.youtube.com/watch?v='+videoid+'<br><br>';
					//iframeで動画埋め込む時はこっち
					//html += '<iframe src="https://www.youtube.com/embed/'+videoids[i]+'?rel=0" frameborder="0" allowfullscreen></iframe>';
				}
				document.getElementById('youtube').innerHTML = html;
			}
		}
	});
}
</script>

気になる点

本来の使い方とは違う使い方をしているのは気になる。
この方法では各動画のタイトルが取得出来なかった。

結果

方法2-2のものを装飾して以下のようなページが完成した。

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



関連記事