Youtube API V3でユーザーがアップロードした動画リストを取得する方法

あるユーザーがアップロードしたYoutubeの動画リストを、ユーザーIDを使って下記のように簡単に取得できました。

http://gdata.youtube.com/feeds/api/users/ユーザーID/uploads?alt=json

しかし、この方法は2015年4月20日で終了し、今後はv3を使用して取得する必要があります。
ここでは、チャンネルIDからの取得も加え、切替え方法について説明します。

Google Developer ConsoleでAPIを登録しキーを取得

Google Mapsをはじめ、すべてのGoogle系APIは、Google Developer Consoleというツールで集約管理されるように仕様変更されています。
まずは下記にアクセスしましょう。Googleアカウントを作っていない方は要作成です。YoutubeやGMailのアカウントで利用できるはずです。
https://console.developers.google.com/

「プロジェクトを作成」をクリックしてAPIを管理するための大枠を作成します。

次に左側のメニューから「APIと認証」→「API」とクリックし、APIライブラリ内の「Youtube Data API」をクリックします。
「APIを有効にする」というボタンがあるのでこれをクリックします。
これで、先ほど作成したプロジェクトでYoutube Data APIが使用できるようになりました。

同じく左側のメニューから「APIと認証」→「認証情報」とクリックし、下側の「公開APIへのアクセス」欄にある「新しいキーを作成」をクリックして、表示された小窓の「ブラウザキー」をクリックします。
尚、サーバーキーとブラウザキーの違いは、使用制限のかけ方が異なっています。

  • サーバーキー
    IPアドレス単位で制限(サーバーのIPアドレスが送信される環境=PHPなどのサーバーサイドプログラム内、で使用する場合)
  • ブラウザキー
    リファラー単位で制限(IP制限ができない場合。クライアントサイド=Javascriptで使用する場合)

最後に、上で説明したリファラーまたはIPアドレス単位での制限を設定します。これは後からでも変更ができるので、開発中は空でも構いません(書き方は後述)。
尚、制限を行わないと、APIを悪用され、アクセス制限を受けたり、課金される可能性がありますので注意しましょう。

以上でAPIキーが取得できます。英数・ハイフン・アンダーバーの羅列であるこのAPIキーをメモしておき、以下で説明する{APIキー}の個所に挿入してください。

蛇足ですが、OAuthのクライアントIDは、非公開データ・プライバシーデータへのアクセスや、データの追加・削除などを行う際に使用するものであり、公開されたデータにアクセスする今回のケースでは使用しません。

リファラー制限の書き方

テストをしてみましたが、a.jpではa.jp/a.htmlは不可、a.jp/*ではwww.a.jp/a.htmlは不可でした。以上から、あるドメインa.jpの場合は、
a.jp/*
*.a.jp/*
としておくのが無難かと思います。

ここで言うリファラーは、Youtube Data APIにリクエストを行うファイルの絶対パスと読み替えてOKです。外部jsの場合も下記のように同様です。

  • a.jp/a.html内からjsonpでリクエストした場合のリファラー
    a.jp/a.html
  • a.jp/a.html内から呼ばれたa.jp/a.jsからjsonpでリクエストした場合のリファラー
    a.jp/a.html

APIリクエストを実行。channelからアップロードした動画のプレイリストIDを取得→playlistItemsにリクエスト

Youtube Data APIのリファレンスはこちらで、概ね日本語化されています。
まずは、ユーザーIDまたはチャンネルIDから、アップロードした動画のプレイリストIDを取得するために、下記のアドレスにアクセスします。

  • ユーザーIDの場合
    http://youtube.com/user/ユーザーID
    https://www.googleapis.com/youtube/v3/channels
    ?part=contentDetails&forUsername=ユーザーID&key={APIキー}
  • チャンネルIDの場合
    http://youtube.com/channel/チャンネルID
    https://www.googleapis.com/youtube/v3/channels
    ?part=contentDetails&id=チャンネルID&key={APIキー}

すると下記のようなJSONを取得できます。

{
 "kind": "youtube#channelListResponse",
 "etag": "**",
 "pageInfo": {
  "totalResults": 1,
  "resultsPerPage": 5
 },
 "items": [
  {
   "kind": "youtube#channel",
   "etag": "**",
   "id": "**",
   "contentDetails": {
    "relatedPlaylists": {
     "likes": "**",
     "uploads": "アップロードした動画のプレイリストID"
    },
    "googlePlusUserId": "**"
   }
  }
 ]
}

次に、取得した「アップロードした動画のプレイリストID」を使って下記のアドレスから動画のリストを取得します。

https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=プレイリストID&maxResults=件数(~50)&key={APIキー}

すると、次のようなJSONが取得できます。これにはvideoIdのほか、動画のタイトルや説明が含まれます。

kind : youtube#playlistItemListResponse
etag : "**"
pageInfo :
    totalResults : 3
    resultsPerPage : 50
items :
    0 :
        kind : youtube#playlistItem
        etag : "**"
        id : **
        snippet :
            publishedAt : 2015-01-01T00:00:00.000Z
            channelId : **
            title : 動画のタイトル
            description : 動画の説明
            thumbnails :
                default :
                    url : https://i.ytimg.com/vi/**/default.jpg
                    width : 120
                    height : 90
                medium :
                    url : https://i.ytimg.com/vi/**/mqdefault.jpg
                    width : 320
                    height : 180
                high :
                    url : https://i.ytimg.com/vi/**/hqdefault.jpg
                    width : 480
                    height : 360
            channelTitle : チャンネル名
            playlistId : **
            position : 0
            resourceId :
                kind : youtube#video
                videoId : 動画のvideoId
    1 :
    2 :
  ・
  ・
  ・

サンプルコード

上で説明した内容を、利用シーンに合わせてコードにしてみます。Javascript+jQuery(クライアントサイド)で利用する場合は例えば次のようになります。

//step1:uploadsのplaylistIdの取得を試みる
$.ajax( {
    "timeout": 5000,
    "url": "https://www.googleapis.com/youtube/v3/channels",
    "type": "GET",
    "dataType": "jsonp",
    "data": {
        "part": "contentDetails",
        "key": {APIキー},
        "forUsername": ユーザーID,
        または
        "id": チャンネルID,
    },
    "success": function(res) {
        if(!res || !res.items || !res.items[0] || !res.items[0].contentDetails || !res.items[0].contentDetails.relatedPlaylists || !res.items[0].contentDetails.relatedPlaylists.uploads) {
            //error処理
            alert("error!");
            return "";
        }

        var playlistId = res.items[0].contentDetails.relatedPlaylists.uploads;

        //step2:uploadsのplaylistIdが動画リストを取得する
        $.ajax( {
            "timeout": 5000,
            "url": "https://www.googleapis.com/youtube/v3/playlistItems",
            "type": "GET",
            "dataType": "jsonp",
            "data": {
                "part": "snippet",
                "key": {APIキー},
                "playlistId": playlistId,
                "maxResults": 件数(~50)
            },
            "success": function(res) {
                if(!res || !res.items || !res.items[0] || !res.items[0].snippet || !res.items[0].snippet.resourceId || !res.items[0].snippet.resourceId.videoId) {
                    //error処理
                    alert("error!");
                    return "";
                }

                var videoIds = [];
                for(var i = 0; i < res.items.length; i++) {
                    var id = res.items[i].snippet.resourceId.videoId;
                    if($.inArray(id, videoIds) != -1) {
                        continue;
                    }
                    videoIds.push(id);
                }

                //videoIdsの取得成功
                alert(videoIds.join("\n") );
            },
            "error": function(res, status) {
                //error処理
                alert("error!");
                return "";
            }
        } );
    },
    "error": function(res, status) {
        //error処理
        alert("error!");
        return "";
    }
} );

$.ajaxでjsonpを2回リクエストしていますが、この箇所は関数化してスッキリさせたり、jQueryのバージョンによって$.ajax().success()としたりと改善可能です。
PHPの場合は例えば次のようになります。

<?php
define("YT_API_KEY", "{APIキー}");
define("RPP", {表示件数(~50)});

//step1:uploadsのplaylistIdの取得を試みる
$url = "https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=ユーザーID&key=".YT_API_KEY;
または
$url = "https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id=チャンネルID&key=".YT_API_KEY;
$channel = json_decode(file_get_contents($url), true);
if(!$channel["items"][0]["contentDetails"]["relatedPlaylists"]["uploads"]) {
    //error処理
    exit();
}
$playlistId = $channel["items"][0]["contentDetails"]["relatedPlaylists"]["uploads"];

//step2:uploadsのplaylistIdが動画リストを取得する
$url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=".$playlistId."&key=".YT_API_KEY."&maxResults=".RPP;
$playlist = json_decode(file_get_contents($url), true);
if(!is_array($playlist["items"]) ) {
    //error処理
    exit();
}
$videoIds = array();
foreach($playlist["items"] as $val) {
    $id = $val["snippet"]["resourceId"]["videoId"];
    if($id) {
        $videoIds[] = $id;
    }
}
//videoIdsの取得成功
print_r($videoIds);
?>

まめわざでの使い方

右にあるのはGoogle Japanの公式チャンネルです。
このように、まめわざには、上記の方法でユーザーのアップロードした動画リストをリアルタイムに取得して表示する機能があり、さながらテレビのような感覚で動画を楽しめ、動作も軽快です。
ユーザー・チャンネル・プレイリストに限らず、気に入った動画を複数登録してリスト表示することもできます。

動画をスクリプトタグ形式で多数設置した場合、ページの表示速度に甚大な影響が出ます。特にスマートフォンなどからの閲覧時はやっかりです。
まめわざは、動画をまずサムネイルで表示し、クリック後にスクリプトを動作させるワンクッションがあるため、多数の動画があっても重くなりません。

動画ブロックを追加して、Youtubeのアドレスを貼り付けるだけで簡単にYoutube動画が設置出来ます。
動画に訴求効果が期待できる企業は、動画の配信についてもご検討ください。

2015/6/9