YouTubeの動画を連続再生させてみる。
- iPhone対応&cuePlaylistを使って簡単に実装した話はこちら
YouTubeで好きなアーティストの曲を連続再生させたいって思ったとき、すでに「君のラジオ」だったりYouTube本家にDiscoとしてあるわけですが、Last.FMユーザーとしては自分のTop50のランキングからランダムにいい感じに曲を選んで欲しいと思ったりしています。
なので、そういうものを作ろうかなと思いながら全然形に出来ていないので、ちょびちょびアウトプットしながら作っていこうかと思います。
今回はここまで
ざっくり必要なもの
- YouTubeの動画を連続再生させる。(←今回ココ)
- Last.FMのアカウントからランキングを取得して、そのアーティストの集合から曲をランダムに抽出する仕組み
- 曲は毎回再生するたびにそこそこ変化する。
- 上位のアーティストの曲は優先度が高い。
- 他の面白そうな技術に流されない心。
こんなものでしょうか?
YouTubeの動画を連続再生させる
プレーヤーの埋め込み
ドキュメント見る
- というわけでまずドキュメントを調べるために、「youtube javascript api」と調べてみると、いきなり下記のページがヒットします。
- ここにまさにプレーヤーの埋込みのサンプルがあるのでそれを参考に埋め込んでみます。
- ドキュメントに書いてある通り、SWFObjectというライブラリが必要になるのですが、今回はgoogleがホスティングしているものを利用することにします。
<head> <meta charset="utf-8"> <title>YouTubeを連続再生してみるサンプル1</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> </head> <body> <script type="text/javascript"> var video_list = ["cfOa1a8hYP8", "tYm1PDwLrQM"]; swfobject.embedSWF("http://www.youtube.com/v/" + video_list[0] + "?enablejsapi=1&autoplay=1&playerapiid=player", "video", "854", "480", "8", null, null, { allowScriptAccess: "always" }, { id: "player" }); </script> <h1>YouTubeを連続再生してみるサンプル1</h1> <div id="video"></div> </body> </html>
- こんな感じになります。
- swfobject作るときの各パラメータについてはドキュメントに書いてあるので省略しますが、自動再生するために「autoplay」を有効にしたりしています。
- ここでは、playerapiidとして「player」、divのidとして「video」、idとしてgetElementByIdでプレイヤーを取得するためのIDとして「player」を指定しています。
- playerapiidの方はおそらく後で説明するイベントなどで引数として渡されてくる値になるのだと思います。
イベントを取得して連続再生
- 上記でとりあえずvideo_idを渡せば再生出来るようになりましたので次は連続再生出来るようにしたいと思います。
- YouTubeプレイヤーではプレイヤーの準備が整ったら「onYouTubePlayerReady」という関数を呼ばれます。そのタイミングで、プレイヤーの状態が変わったら投げる「onStateChange」というイベントに、再生が終了した時だったら次のビデオを読み込んで再生するという処理を登録しています。
function onYouTubePlayerReady(playerId) { document.getElementById(playerId).addEventListener("onStateChange", "onytplayerStateChange"); } function onytplayerStateChange(newState) { if (newState == 0) { document.getElementById("player").loadVideoById(video_list[1]); } }
- newStateが0の場合が再生が終了した場合のイベントになるので、その時にloadVideoByIdでvideo idを指定することで連続再生することが出来ます。
- これでとりあえずvideo idのリストさえ取得できれば連続再生出来そうですね。なので次は動画情報を取得してみます。
- こんな感じになります。
動画情報を取得する
- Playerの埋込みではPlayer APIというのを使いましたが、動画情報の取得ではData APIというのを利用します。
- 動画の取得方法はいくつかあるのですが今回は単純に検索クエリーを投げてその結果を受け取る方法を採用したいと思います。
投げるクエリー
- 今回はJQueryを使って実装しました。
- (抜粋)
function onytplayerStateChange(newState) { if (newState == 0) { ++index; document.getElementById("player").loadVideoById(video_list[index].id); } } var video_list = []; var index = 0; var api_offset = 1; jQuery(function($) { $("#search").click(function() { var query = $("#query").attr("value"); $.getJSON("http://gdata.youtube.com/feeds/api/videos?", { "q": query, "alt": "jsonc", "v" : 2, "max-results":10, "format": 5, "orderby": "viewCount", "start-index": api_offset }, function(rs) { var query = new RegExp($("#query").attr("value"),"i"); api_offset += 10; var rs_list = rs.data.items; rs_list = rs_list.sort(function(a, b) { return b.favoriteCount - a.favoriteCount; }); for (var i = 0, max = rs_list.length; i < max; i++) { if (rs_list[i].title.match(query)) { video_list.push(rs_list[i]); } } swfobject.embedSWF("http://www.youtube.com/v/" + video_list[index].id + "?enablejsapi=1&autoplay=1&playerapiid=player", "video", "854", "480", "8", null, null, { allowScriptAccess: "always" }, { id: "player" }); } ); }); });
- 動画情報を取得してそれを配列に入れて、再生が終了するごとに次のビデオを再生しています。
- こんな感じ
- http://koba04.com/youtube/3.html
- 再度検索するときに、もう1度リロードする必要があるなどまだまだ問題はあります。
API
- 指定しているパラメータは見ての通りですが、qは検索文字列、altはレスポンスデータ型(後述)、vはAPIバージョン、max-resultsは結果の最大数、formatは動画フォーマット(埋め込み可能なものだけ)、orderbyは順番、start-indexはoffsetを指定しています。offsetを指定しているのは後で11-20件目を取ったり出来るようにするためです。
- alt=jsoncについて
- 先ほど紹介したページにはaltに指定している値として「atom」、「rss」、「json」、「json-in-script」が記載されているのですが、ここで得られるjsonは個人的には正直使いにくいなぁと思っていました。
- ですが英語版のページにはjsoncというもっとシンプルな構造が紹介されています。こちらの方がつかいやすいので今回はこちらを使用します。
- http://code.google.com/intl/ja/apis/youtube/2.0/developers_guide_jsonc.html
- 余談ですが、英語のドキュメント見ているといつの間にか日本語のページに飛ばされることがあるので注意。
取得したデータを精査
- 単純にアーティスト名で検索すると全然違う動画も結構引っかかってくるのでかなり残念な感じになります。
- ですので取得したデータを加工することで少しはマシなデータを取得出来るようにします。
- 方法としては、jsoncのデータに入っているfavoriteCountというデータでソートをし、検索文字列がタイトルに含まれているかでフィルタリングをしています。ものによっては全然取得出来なくなりますが無関係な動画はあまり引っかかってこなくなると思います。
var query = new RegExp($("#query").attr("value"),"i"); api_index += 10; var rs_list = rs.data.items; rs_list = rs_list.sort(function(a, b) { return b.favoriteCount - a.favoriteCount; }); for (var i = 0, max = rs_list.length; i < max; i++) { if (rs_list[i].title.match(query)) { video_list.push(rs_list[i]); } }
もう一工夫
- 上記で検索されたアーティストの動画を連続再生させることが出来るようになりましたが正直まだ使いにくいです。ですので現時点では下記のような機能を追加で実装しています。
- 動画リスト、現在再生している動画を表示する機能。
- 残り動画が少なくなってきたらAPI呼んで次の動画を取ってくる機能。
- 次の曲、前の曲に移動出来る機能。
こんな感じになります。あまり確認していないので動かないところもあるかもしれません。(IEは論外)
ソースはGithubで管理しています。html 1つにまとめて書いているのでhtmlだけあれば動かすことが出来ると思います。
まだまだイマイチですので、少しずつ手を加えていきたいなと思います。Githubみたいにpermalinkを作って検索出来るようにするとか。
Enjoy Youtube !
- pushState対応した話
- iPhone対応&cuePlaylistを使って簡単に実装する話