PHP: Youtube Data API v3にて動画情報をJSONで取得して表示する

以前、Youtube Data API v2の時にfeedを取得して動画を表示するというスクリプトを書いたんですが、v2のサービスが終了しv3に完全移行してしまったため、動作しない状態でした。

これらと同様の機能をギターを弾き語れ!簡易ギターコード進行移調プログラムにて持たせていたんですが、動画の取得ができなくなっていたため他の方法を色々考えていました。

Youtube Data API v3のサンプルを見ると、だいたいOAuthなどで認証後色々できるようになっているわけですが、例えばアップロードやその他諸々のデータをYoutubeのサーバーやらに何かしらするというのであればサンプルのようにするべきなんでしょうけれども、別にそういう機能が必要なわけではありません。

feedさえ取得できればよいわけです。以前はAPIを叩くだけで利用できたため特に登録やらはなくてもイケたんですけれども、今回はどうやら登録が必要そうです。APIを利用するまでの登録やその他は他のサイトに任せておいて、ここではそのやり方を説明したいと思います。

※ この記事は動画IDから動画情報を取得して出力するというものです(2015/7/8にスクリプト一部修正しました)。キーワードで検索する場合は以下のブログカードを参照

PHP: Youtube Data API v3にて動画情報をJSONで取得して表示する part2 キーワードで検索する
前回、PHPにて自分がデータ化しておいた動画IDの配列で、Youtubeの動画をチェックして出力し、すでに削除されているであろう動画IDを見...

前おき

APIを利用するにあたって、どういうことをしたいかと言いますと、その動画が生存しているかどうか、つまりは削除されていないかどうかを調べたいわけです。これが目的なのでOAuthは利用しません。

APIを叩く→JSONでデータ情報が返ってくる→PHPで整形して表示」こういうのを目的としています。
これの前提として、まずどのようにして動画情報をデータ化しておくかなのですがいくつか取得方法がありまして、今回は自分が動画IDを収集しておき、それをデータ化しておいて、その動画IDからAPIを通じてデータがあるかどうかを調べてみたいと思います。
他の方法として、キーワードで検索してその結果を表示したり、キーワードからYoutubeが推奨する動画を検索したりもできます。またAPIから返ってくるJSONの中身も自分が必要なものだけ取得するようなことも可能になっています。

詳しくは YouTube Data API | Google Developers から本家マニュアル等をご覧ください。

また、15件ぐらいだったと思いますが、YouTube Data APIを利用せずともfeedを得ることは可能です。ただし全てのデータから検索しているのでは無いようで、調べたいデータが返ってくるかどうかはわかりませんが、

https://www.youtube.com/feeds/videos.xml?channel_id=[CHANNELID]
https://www.youtube.com/feeds/videos.xml?user=[USERNAME]

このようなアドレスで各ID(大文字部分)を入れれば、JSONでデータを取得することは可能です。USER NAMEかCHANNEL IDなので、動画IDを調べるためにはこれらでまずJSONを取得して、その中からIDを探すということをしなくてはいけないのです。ただし、全ての動画を検索していると言うわけでは無さそうなので有効に利用できるかどうかは使い方次第です。

誰か(あるいは自分)のチャンネルのfeedを得るという意味ではこちらでもイケるんじゃなかろうかと思います。登録なども必要なく、v2の時のように利用できるので、ライトな使い方をされる場合はこちらで良いのかも。

動画IDからJSONを取得してデータを出力する

動画IDとは、https://www.youtube.com/watch?v=xxxxxxxxxxx の太字の部分です。これを自分の必要とする動画から集めます。
集めた動画IDは配列化して、一挙にAPIに送ります。

調べたい動画データを配列化する

このような感じです。APIに送る際には,(カンマ)で区切ってurlencodeをすれば良いので、

このような感じで必要な形式に変換できます。また動画IDを配列化しておくことで、いちいちIDをチェックしなくても一挙に複数のIDを送れるのでとても便利です。

APIを叩くためのアドレスを作る

2015/7/8 追記
削除されたであろう動画の取得に不備があったので、再度調べてみた所、解決方法があったので内容を書き変えました。
不要な部分はスクリプト部分でコメントアウトしています

今までは、http://img.youtube.com/vi/VIDEO_ID/1.jpgなどとしてサムネイルを取得していたわけですが、v3のAPIにサムネイルのアドレスも取得するように設定すると返してくれるので今回はそれを利用します。

このような感じでAPIを叩くためのアドレスを作ります。fieldspartの部分は、リンクを参考して下さい。

APIの情報を取得する

file_get_contents()が利用できるサーバーを利用されている方はそれで取得しても構いません。
利用できない場合は、以下を参考にしてcURLを利用して取得します。

fopen,file_get_content等がそのままでは利用できないサーバーでWordpressのjQueryをCDNにする方法
※ fopen,file_get_contentが利用できるサーバーでも下記で動作します。←これ重要 ※ 内容的にはwordpressのj...

このように関数化しておくと便利です。

取得する方法はとても簡単で、

このようにして変数$jsonに取得したデータを入れておけばよいわけです。変数名からもわかるようにjsonで取得します。

取得したデータをデコードして配列化する

jsonのままだとアレなので、配列化しておきます。

配列化することで簡単にデータを扱えるようになります。

配列化したjsonのデータから必要な値を取り出す

ここでは、動画IDを配列化してAPIを叩き、それらのIDから返ってきたjsonをひとまず見つかったデータとして変数$foundに入れます。その際、動画IDとそのタイトルそしてサムネイルのアドレスも取得しておき格納しておきます。

最初に配列化した動画IDが見つからなかった場合はどうするかと言いますと、

このようにして、元々のIDの配列と、見つかったidの配列をそれぞれ作り、array_diff()でそれらを比較することによって重複していないIDを見つけることができます。最初に自分が調べたい動画のIDの一覧を作り、jsonから返ってきたデータのidと比較しているので、APIが見つけられなかったと言うことは、つまりは削除されていると考えられるわけです。

2015/7/8 に追記した内容で、JSONの中にステータスがあったので、そこからprocessed以外のステータスのものは問題ありと言うことで除外(削除された)と判断して$notFoundに入れるようにしました。データとしては、$uploadStatus = $gDat[‘status’][‘uploadStatus’];で取得することができます。

その他の理由の場合もあるかも知れませんが、どうせ表示はできない状態でしょうから$notFoundに入っているIdを何かしらで表示しておけば、そのIDだけデータ修正すれば良いのでメンテナンスにも役立つと思います。
元々の配列をPHPで直接書かずにcsvなどでデータ化しておいて、$notFoundがある場合は該当の記述を変更するということで自動化も期待できます。いちいちexcelやテキストエディターを開くのが面倒な人は、Googleのスプレッドシートを利用しても良いのではないでしょうか?

見つかったデータから出力する(Youtubeプレイヤーを作る)

Youtubeのプレイヤーを表示させるには、Youtubeの任意の動画にアクセスして、共有の埋め込みコード部分でiframeの出力形式を見ておいて、知っておく必要があります。

このような感じで書けばプレイヤーが表示できるということですね。サイズは任意に設定できるので、必要な部分は、//www.youtube.com/embed/MOVIE_IDになるかと思います。

その前に必要なデータを配列化しておきます。

IDやらタイトルは$foundで作った配列にあるのでサムネイルだけなんとかすればここまでする必要ないんですけれども、変数名を統一するためにまとめてやっておきます。まぁ$foundでしておいても良いんですけどね(笑)

さて、これで一応、出力する準備はできたんですが直接プレイヤーを埋め込むと読み込みやらにそこそこ時間がかかるので、表示自体はサムネイルで一覧表示しておき、プレイヤーは別途jQueryなどを利用してどこかしらのdiv内に挿入するほうが良いのではないだろうかと思います。

なので、出力する方法とすれば、$ydat[‘href’](※ 下記ではjQueryの都合上$ydat[‘id’]を利用しています)の部分がiframeの読み込みソースになるので、$ydatをforeachなどで回して、

このようなデータを配列で作っておきます。そうすれば、

などとして、リストとして出力できるわけです。ただし、aタグにはiframeで必要な動画のidが入っており、そのままではリンクとしては機能しないので、先ほど書いたようにjQueryでプレイヤーを読み込みます。※ $ydat[‘href’]もありますので必要な記述を任意選んで下さい。jQuery等も便宜改変の事。

このような記述を<script></script>に書いておけば、aのclassがythrefのリンクの場合、#ytlのブロックに、iframeを書き出すことができます。
サイズや、必要なオプションは別途設定していく必要がありますが、このようにしてAPIからJSONで取得したデータをPHPで整形してプレイヤーで読み込みということができるわけです。

また、$notFoundのAPIから見つからなかった(削除されたであろう)データも、データのメンテナンスにちょっとぐらい役立つのではないでしょうか?

以上、今回は、既に収集してある動画IDからそのIDの生存確認と、Youtube Data API v3からjsonでデータを取得してPHPで整形し、jQueryで動画プレイヤーを表示するという内容で書いてみました。
次回は、キーワードで検索すると言うのを書いてみたいと思います。


ちなみに、APIには利用上限があり、

無料の割り当て 50,000,000 ユニット数/日
ユーザーごとの制限 3,000 リクエスト/秒/ユーザー

となってます。また、毎日の割り当ては太平洋時間(PT)の午前 0 時にリセットされます。

ユニットとはなんぞやと言うことですが、以下のように記載されています。

クォータを超過しない範囲でアプリケーションが 1 日あたりに送信できる読み取り、書き込み、またはアップロードの各リクエスト数を見積もることができます。たとえば、1 日あたりのクォータが 5,000,000 ユニットの場合、アプリケーションが送信できるリクエスト数の制限はおおよそ次のようになります。

  • それぞれリソースのパーツを 2 つ取得する 1,000,000 件の読み取り操作。
  • それぞれリソースのパーツを 2 つ取得する 50,000 件の書き込み操作と 450,000 件の追加読み取り操作。
  • それぞれリソースのパーツを 3 つ取得する 2,000 件の動画アップロード操作、7,000 件の書き込み操作、および 200,000 件の読み取り操作。

大規模なサイトでは上限を超過して、APIが利用できなくなるか料金が発生するかみたいな感じになるかと思います。ここらは調べてないのでわかりませんが、まぁそんなところでしょう。