今回は、
Youtube API - フィード
データの種類
Youtube APIでは、projection
の部分にどのようなデータを返してほしいかを指定します。
http://gdata.youtube.com/feeds/projection/videos
現在のところ、projection
は2種類用意されています。
projection | 説明 |
---|---|
api | ytスキーマやmediaスキーマ等の全ての拡張要素を含んだデータを返します。全てのプロパティはテキストです。通常はこちらを使います。 |
base | いくつかの拡張要素が除かれたデータを返します。summaryプロパティやcontentプロパティにはHTMLが含まれています。フィードリーダなどに読み込ませるときなどに使います。 |
たとえば、
http://gdata.youtube.com/feeds/base/videos
フィードの種類
データを取得するフィードは数種類あります。
通常はVideoフィードを使えば十分ですが、
全てのフィードは読み取り専用であり、
Videoフィード
Videoフィードには、
ビデオフィード
ビデオを検索するには、
http://gdata.youtube.com/feeds/projection/videos
パラメータを付与して検索条件を指定することができます。使用できるパラメータについては後述します。
たとえば、
http://gdata.youtube.com/feeds/api/videos?vq=cat&max-results=10
関連動画フィード
関連動画フィードは、videoid
にビデオIDを指定して取得します。最大100件まで取得することができます。
関連動画フィードは、
http://gdata.youtube.com/feeds/projection/videos/videoid/related
Standardフィード
Standardフィードは、feedid
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/standardfeeds/feedid
feedid
は8種類用意されています。
feedid | 説明 |
---|---|
top_ |
評価の高い動画 |
top_ |
お気に入り登録の多い動画 |
most_ |
再生回数が多い動画 |
most_ |
最も議論された動画 |
most_ |
リンクの多い動画 |
most_ |
動画レスポンスの多い動画 |
recently_ |
最近のおすすめ動画 |
watch_ |
携帯電話のための動画 |
お気に入りフィード
ユーザのお気に入りに登録されているビデオを取得します。お気に入りフィードは、username
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/users/username/favorites
再生リストフィード
再生リストのビデオを取得します。再生リストフィードは、playlistID
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/playlists/playlistID
ユーザ再生リストフィードを使うと、
コメントフィード
ビデオのコメントを取得します。コメントフィードは、videoID
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/videos/videoID/comments
ユーザプロファイルフィード
ユーザのプロファイルを取得できます。ユーザプロファイルフィードは、username
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/users/username
ユーザ再生リストフィード
ユーザが登録している再生リストを取得できます。ユーザがプライバシーをusername
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/users/username/playlists
ユーザコンタクトリストフィード
ユーザのユーザコンタクトリストに登録されているユーザを取得できます。
ユーザコンタクトリストは、username
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/users/username/contacts
コンタクトリストはカテゴライズすることができますが、category
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/users/username/contacts/-/category
ユーザ登録チャンネルフィード
ユーザの登録チャンネルを取得できます。
ユーザ登録チャンネルフィードは、videoID
を指定してリクエストします。
http://gdata.youtube.com/feeds/projection/users/username/subscriptions
登録チャンネルには、feed.
プロパティを参照します。
Youtube API - パラメータ
Google Dataパラメータ
Youtube APIは、
パラメータ | 説明 |
---|---|
max-results | 最大取得件数を数値で指定します。 |
start-index | 何件目から取得するのかを、 |
/category |
カテゴリを指定します。 カテゴリを指定するには、 例) http:// |
author | 投稿者を指定します。 |
alt |
レスポンスデータを指定します。atom(Atom feed),rss(RSS 2. |
Youtube APIパラメータ
Youtube APIは、
パラメータ | 説明 |
---|---|
vq |
検索のキーワードを指定します。 複数のキーワードをAND条件で指定するには、 例:keyword1 keyword2 複数のキーワードをOR条件で指定するには、 例:keyword1 OR keyword2 検索結果から除きたいキーワードを指定するには、 例:keyword1 -keyword2 |
format | ビデオフォーマットを指定します。1 |
racy | 制限つきビデオを検索結果に含めるかどうかを指定します。制限つきビデオを検索結果に含めるにはincludeを指定します。 |
orderby |
検索結果の順序を指定します。
relevance |
time |
Standardフィードの対象期間を指定します。
today |
Youtube API - レスポンスデータ
今回は最も使用頻度の高い、
Videoフィードのレスポンスデータ(JSON)
構造 | 説明 |
---|---|
ヘッダ部 | データのヘッダ情報を格納します。 |
フィード部 | データのフィード情報を格納します。 |
ヘッダ部
プロパティ | 説明 |
---|---|
version | バージョンです。現在は1. |
encoding | 文字エンコーディングです。JSONの場合はUTF-8です。 |
フィード部
構造 | 説明 |
---|---|
スキーマ部 | フィードで使用されているスキーマを宣言しています。 |
フィードヘッダ部 | フィードのヘッダ情報を格納します。 |
エントリリスト部 | フィードの各エントリデータを格納する配列です。 |
スキーマ部
プロパティ | 説明 |
---|---|
xmlns | フィードの名前空間を宣言します |
xmlns$openSearch | OpenSearchスキーマの宣言です。 |
xmlns$gml | GML |
xmlns$georss | GeoRSSスキーマの宣言です。 |
xmlns$media | YahooのMedia RSSスキーマの宣言です。 |
xmlns$yt | Youtubeスキーマの宣言です。 |
xmlns$gd | Google Dataスキーマの宣言です。 |
フィードデータがこれらのスキーマを使用している場合は、
スキーマ名(xmlns$を除いたもの)$名前
たとえば、
openSearch$名前
フィードヘッダ部
プロパティ | 説明 |
---|---|
id.$t | idが格納されています。リクエストしたフィードのURLです |
logo.$t | YoutubeのロゴのURLです。 |
openSearch$totalResults.$t | 検索結果の件数です。 |
openSearch$startIndex.$t | 検索結果の開始です。 |
エントリリスト部
プロパティ | 説明 |
---|---|
entry[n] | エントリデータを格納する配列です。 |
ここに、
エントリ部
構造 | 説明 |
---|---|
エントリヘッダ部 | エントリデータのヘッダ情報です。 |
メディアグループ部 | ビデオの詳細情報です。 |
エントリヘッダ部
プロパティ | 説明 |
---|---|
id.$t | idが格納されています。このビデオ情報のフィードのURLです。 |
published.$t | 投稿日時です。RFC 3339フォーマットです。 |
title.$t | ビデオのタイトルです。 |
content.$t | ビデオの説明です。 |
author. |
投稿者の名前です。 |
yt$statistics. |
再生回数です。 |
メディアグループ部
プロパティ | 説明 |
---|---|
media$title.$t | ビデオのタイトルです。 |
media$description.$t | ビデオの説明です。 |
media$keywords.$t | ビデオにつけられたカテゴリもしくはタグです。カンマ区切りで格納されています。 |
yt$duration. |
ビデオの秒数です。 |
media$content[n].url |
ビデオへのURLです。 media$content[n].yt$formatが1の場合はモバイル再生用のRTSPストリーミングURLです。 media$content[n].yt$formatが5の場合はSWFへのURLです。 |
media$player[n].url | プレーヤーページへのURLです |
media$thumbnail[n].url | サムネイル画像へのURLです。 |
全体の構造
"feed": {
"entry":[
media$group{
-
※
「~部」 というのは筆者がつけた名称です。
- 参考
サンプルの機能拡張(1)
第2回で実装したサンプルの機能を拡張し、
実装のイメージをつかみやすくするため、

機能概要
検索結果サムネイル表示機能
- 検索を実行すると、
サムネイル画像と再生回数を9件 (3×3) 表示する。 - サムネイル画像をクリックすると、
ビデオの再生ページに遷移する。 - 「関連度」
「追加日」 「再生回数」 「評価」 をクリックすると検索結果を並べ替えることができる。 - 「前へ」
「次へ」 をクリックするとページ送りを行う。 - 検索結果件数、
表示しているサムネイルのインデックス番号を表示する。
検索履歴機能
- 検索を実行すると、
検索履歴に履歴が残る。 - 検索キーワードが検索履歴に存在する場合は、
その履歴を最上位に移動する。 - 検索履歴には、
検索結果の第1番目のサムネイル画像、 検索キーワード、 削除リンク 「[x]」 を表示する。 - 検索履歴をクリックすると、
その検索キーワードで再度検索する。 - 削除リンク
「[x]」 をクリックすると、 その検索履歴を消去する。 - 「クリア」
をクリックすると、 全ての検索履歴を消去する。
画面要素
タイトル
いままでタイトルもつけていなかったので、
検索キーワードを入力するためのテキストボックスと、 id=frmSearchとしてform要素を定義します。検索を実行する 検索履歴を表示する領域です id=historyとしてdiv要素を定義します。
「検索履歴」 検索結果を表示する領域です id=viewとしてdiv要素を定義します。
「ビデオ」 以上で、 jQueryでページ読み込み時の初期化処理を実装するには、 今回は、 検索を実行した時のイベントを定義します このsubmitイベントハンドラの書き方は第2回で出てきましたね。
入力されたキーワードを取得し引数として、 プロパティ オブジェクトリテラルの書式はこれまで見たことないですか? もし、 プロパティが増えたら記述が大変そうですね。オブジェクトリテラルの書式を使うとすっきりと記述できるので是非覚えてください。 また、 並び替えのリンク 4つのリンクのイベントが1つのイベントハンドラで簡潔に定義できてますね。
これがjQueryの面白いところです。
それでは1つずつ解説しましょう。 説明のため、 まず、 このセレクタは、 このjQueryオブジェクトに対して、 クリック時には、 orderbyプロパティの値の記述に出てきた また、 よって、 イレギュラーな使い方ですが、 また、 「前へ」 まず、 ここで出てくるsearchCondオブジェクトは、 このように適当にグローバルスコープにオブジェクトを作ったり、 そして、 「次へ」 まず、 そして、 VIEW_ また、 検索履歴にある 検索履歴を保持するリスト ページが読み込まれたときに、 新規検索時の処理を定義します 検索キーワードを表すkeywordプロパティに、 そして、 履歴検索時の処理を定義します まず、 そして、 targetは拡張されるオブジェクトを指定します。
その後ろには、 ここでは、 引数の検索条件オブジェクトを元に、 基本的な構造は第2回のものと変わりません。よって、 サムネイルのDOMの構成は次のようになります。 対応するjQueryの実装部分を再掲します ソースコードを見ただけで、 まず、 サムネイルのdiv要素にimg要素を追加します 動画のタイトルを追加します 動画の再生回数を追加します 以上で、 サムネイルをクリックした時のイベントハンドラを定義します 最後に、 新規検索時に、 検索結果の1番目のサムネイル画像を表すjQueryオブジェクトに対して 右下にある検索結果件数表示を実装します このメソッドは、 検索履歴機能を実装します。検索履歴機能を再掲します。 検索履歴に履歴を追加する処理を実装します すでに検索履歴に存在する検索キーワードの場合は、 コールバック関数には2つの引数が与えられます。1番目 イテレーション対象の配列に、 この検索キーワードは次のように取得しています。 まず、 その子要素を選択するために、 この履歴にある検索キーワードと、 この サムネイル画像、 まず、 サムネイルの画像を追加します。この要素は引数imgとして渡されるのでそのまま追加します。 検索キーワードを追加します。class属性がkeyのspan要素を追加します。検索キーワードは引数keywordとして渡されます。 削除リンクを生成します。削除リンクは、 削除リンクをクリックしたときのイベントハンドラを定義します。
クリックすると、 イベントハンドラのコールバック関数内では、 また、 これで、 次に、 検索キーワードを表すkeywordプロパティに、 最後に、 そのli要素を履歴の先頭に移動し、 まず、 最後に履歴の画像を、 以上で全ての実装が終了しました。サンプルを実行して動作を確認してみてください。 今回はYoutube APIを少し詳しく解説しました。
YouTube Data APIを使ったアプリケーションの開発をする際に参考にしてください。 サンプルの機能を拡張して、<h1>Youtube 検索</h1>
検索フォーム
<!-- 検索フォーム -->
<form id="frmSearch">
<input type="text" id="keyword" size="35">
<input type="submit" value="検索">
</form>
検索履歴
<!-- 検索履歴 -->
<div id="history">
<!-- ヘッダ -->
<div class="header">
<div class="submenu"><a id="clear">クリア</a></div>
<div class="caption">検索履歴</div>
</div>
<!-- 履歴リスト -->
<ul></ul>
</div>
検索結果
<!-- ビデオ -->
<div id="view">
<!-- ヘッダ -->
<div class="header">
<div id="sort" class="submenu">
並び替え:
<a id="relevance">関連度</a>|
<a id="updated">追加日</a>|
<a id="viewCount">再生回数</a>|
<a id="rating">評価</a>
</div>
<div class="caption">ビデオ</div>
</div>
<!-- サムネイル -->
<div id="videos"></div>
<!-- フッタ -->
<div id="footer">
<div id="result"></div>
<div id="navi">
<a id="back">前へ</a>
<a id="next">次へ</a>
</div>
</div>
</div>
サンプルの機能拡張
初期化処理
// 初期化
$(function(){
// --- イベントハンドラ ---
// --- 初期処理 ---
});
イベントハンドラ
検索
// --- イベントハンドラ ---
// 検索
$("#frmSearch").submit(function(){
searchNew({"keyword": $("#keyword").val()});
$("#keyword").select();
return false;
});
searchNew({"keyword": $("#keyword").val()});
keyword
に入力されたキーワードを値としてオブジェクトリテラルを生成しています。var obj = new Object();
obj.keyword = $("#keyword").val();
searchNew(obj);
select()
メソッドを呼び出して、$("#keyword").select();
並び替え
// 並び替え
$("#sort > a").click(function(){
searchHistory({"orderby": this.id, "page":1});
});
<div id="sort" class="submenu">
並び替え:
<a id="relevance">関連度</a>|
<a id="updated">追加日</a>|
<a id="viewCount">再生回数</a>|
<a id="rating">評価</a>
</div>
$("#sort > a")
click(fn)
メソッドを呼び出すと、
$("#sort > a").click(function(){
// クリック時のイベント
});
searchHistory({"orderby": this.id, "page":1});
this
とは何でしょうか?this
はその対象のDOM要素の参照を表します。
たとえば、<a id="relevance">関連度</a>
がクリックされればそのリンクのDOM要素への参照になります。$(this)
とすれば、前へ
// 前へ
$("#back").click(function(){
if (searchCond.page return;
searchHistory({"page": searchCond.page-1});
});
if (searchCond.page return;
var searchCond = {}; // 検索条件
searchHistory({"page": searchCond.page-1});
次へ
// 次へ
$("#next").click(function(){
if (searchCond.page*VIEW_COUNT+1 > searchCond.total) return;
searchHistory({"page": searchCond.page+1});
});
if (searchCond.page*VIEW_COUNT+1 > searchCond.total) return;
searchHistory({"page": searchCond.page+1});
var VIEW_COUNT = 9; // 画面に表示する件数
クリア
// クリア
$("#clear").click(function(){
$("#history > ul").empty();
$("#videos").empty();
$("#result").empty();
});
$("#history > ul")
、$("#videos")
、$("#result")
のそれぞれの要素に対してempty()
メソッドを呼び出し、初期処理
// 検索テキストボックスをフォーカス
$("#keyword").focus();
サンプルの機能拡張
新規検索
// --- 新規検索 ---
function searchNew(cond) {
search({
"keyword": cond.keyword,
"page": 1,
"orderby": "relevance",
"fromHistory": false
});
}
履歴検索
// --- 履歴検索 ---
function searchHistory(cond) {
if ($("#history li").size() == 0) return;
search($.extend({}, searchCond, cond, {"fromHistory": true}));
}
<div id="history">
<!-- 履歴リスト -->
<ul></ul>
</div>
$("#history li")
とすることで、size()
メソッドは、if ($("#history li").size() == 0) return;
search($.extend({}, searchCond, cond, {"fromHistory": true}));
$.extend()
メソッドは、$.extend(target, object1, [objectN])
検索
// --- 検索 ---
function search(cond) {
// (1) 検索条件の検査
if (cond == null) return;
if (cond.keyword == null || cond.keyword.length == 0) {
alert("検索キーワードを入力してください。");
return;
}
// (2) 検索取得開始インデックス
var index = (cond.page-1)*VIEW_COUNT+1;
// (3) 検索条件の保存
$.extend(searchCond, cond);
// (4) サムネイル表示を初期化
$("#videos").text("Loading...");
// (5) ajax通信定義
$.ajax({
dataType: "jsonp",
data: {
"vq": cond.keyword,
"orderby": cond.orderby,
"start-index": index,
"max-results": VIEW_COUNT,
"alt":"json-in-script"
},
cache: true,
url: "http://gdata.youtube.com/feeds/api/videos",
success: function (data) {
// (6) サムネイル表示をクリア
$("#videos").empty();
// (7) 検索結果件数を取得・表示
searchCond.total = parseInt(data.feed.openSearch$totalResults.$t,10);
showTotal(index, searchCond.total);
// 検索結果が0件
if (searchCond.total == 0) {
alert("検索キーワードにマッチするビデオはありませんでした。");
return;
}
// (8) エントリを参照してサムネイルを生成
$.each(data.feed.entry, function(i,item){
var group = item.media$group;
$("<div/>").addClass("thumbnail")
.append($("<img/>").attr("src", group.media$thumbnail[0].url)).append("<br/>")
.append(item.title.$t).append("<br/>")
.append($("<span/>").addClass("info").text("再生回数:" + ((item.yt$statistics == null) ? "0" : item.yt$statistics.viewCount)))
.click(function(){window.open(group.media$player[0].url, null)})
.appendTo("#videos");
});
// (9) 検索履歴に追加
if (!cond.fromHistory) {
addHistory($("#videos img:first").clone(), cond.keyword);
}
}
});
}
サムネイルを生成
$("<div/>").addClass("thumbnail") // (1)
.append($("<img/>").attr("src", group.media$thumbnail[0].url)).append("<br/>") // (2)
.append(item.title.$t).append("<br/>") // (3)
.append($("<span/>").addClass("info").text("再生回数:" + ((item.yt$statistics == null) ? "0" : item.yt$statistics.viewCount))) // (4)
.click(function(){window.open(group.media$player[0].url, null)}) // (5)
.appendTo("#videos"); // (6)
addClass(class)
メソッドをクラス名を引数にして呼び出します。append(content)
メソッドを追加する要素を引数にして呼び出します。
ここでは、$("<img/>").attr("src", group.media$thumbnail[0].url)
attr(key, value)
メソッドは、group.
を指定しています。yt$statistics.
を参照し、window.open(group.media$player[0].url, null)
appendTo(target)
メソッドは、検索履歴に追加
// (9) 検索履歴に追加
if (!cond.fromHistory) {
addHistory($("#videos img:first").clone(), cond.keyword);
}
clone()
メソッドを呼び出しています。
こうしないと、サンプルの機能拡張
検索結果件数表示
// --- 検索結果件数表示 ---
function showTotal(index, total) {
$("#result").text(
((total == 0) ? 0 : index)
+ " - "
+ (index+VIEW_COUNT > total ? total : index+VIEW_COUNT-1)
+ " / "
+ total
+ "件"
);
}
text(value)
メソッドは、value
の文字列を設定します。検索履歴
検索履歴機能
検索履歴追加
// --- 検索履歴追加 ---
function addHistory(img, keyword) {
// (1) 履歴に検索キーワードが存在するか
var exists = $.grep($("#history li"), function(item, index){
return ($(item).children(".key").text() == keyword);
});
if (exists.length == 0) { // (2) 存在しない
$("<li/>")
.append(img).append("<br/>")
.append($("<span/>").addClass("key").append(keyword))
.append(
$("<a/>").addClass("del").append("[x]")
.click(function(){
$(this).parent().remove();
if (searchCond.keyword == keyword) {
$("#videos").empty();
$("#result").empty();
}
})
)
.click(function(){searchHistory({"keyword":keyword, "page":1, "orderby":"relevance"});})
.prependTo("#history > ul");
} else { // (3) 存在する
$(exists)
.prependTo($(exists).parent())
.children("img").attr("src", img.attr("src"));
}
}
検索履歴の検索
// (1) 履歴に検索キーワードが存在するか
var exists = $.grep($("#history li"), function(item, index){
return ($(item).children(".key").text() == keyword);
});
$.grep(arr, fn)
は、arr
に指定された配列をイテレーションし、fn
がtrueを返した要素で構成される配列を返します。
コールバック関数でarr
をフィルタリングするようなユーティリティメソッドです。$(item)
children(expr)
メソッドを呼び出しています。
children(expr)
は引数のセレクタにマッチする子要素を返すメソッドです。$(item).children(".key")
text()
メソッドを呼び出して、$(item).children(".key").text()
return ($(item).children(".key").text() == keyword);
$.grep(arr, fn)
の実行結果を保持する変数exists
には、if (exists.length == 0) { // (2) 存在しない
} else { // (3) 存在する
}
履歴に存在しない場合
$("<li/>")
.append(img).append("<br/>")
.append($("<span/>").addClass("key").append(keyword))
$("<a/>").addClass("del").append("[x]")
$(this).parent().remove();
this
で参照できるのでしたね。このDOM要素のjQueryオブジェクトを生成します。
親要素を返すメソッドparent()
を呼び出し、remove()
メソッドを呼び出して、if (searchCond.keyword == keyword) {
$("#videos").empty();
$("#result").empty();
}
.click(function(){searchHistory({"keyword":keyword, "page":1, "orderby":"relevance"});})
.prependTo("#history > ul");
履歴に存在する場合
$(exists)
.prependTo($(exists).parent())
.children("img").attr("src", img.attr("src"));
prependTo(target)
メソッドを呼び出して、$(exists).parent()
として親要素を取得します。.prependTo($(exists).parent())
.children("img").attr("src", img.attr("src"))
まとめ