YouTubeAPIで動画に評価を追加
ClientLogin認証を使ってYoutubeの動画に評価を追加するサンプル。YoutubeAPIで動画をアップロードするPerlのコードはググると簡単に見つけられたが,評価を追加するコードは(少なくとも日本語では)見つからなかったので,これから似たような事をする人のために載せておく。
手順
引っかかったところ
POSTでXMLを送信する際に,事前に取得した認証トークンをAuthorizationヘッダに指定する。この書式はAuthSub認証を使う場合は
Authorization: AuthSub token=hogehoge
となるが,ClientLoginを使う場合は
Authorization: GoogleLogin auth=hogehoge
となることに注意する。
また,URLLoaderを使ってXMLを送信すると何故か途中でストリームエラーが発生してうまくいかないので,as3httpclientで公開されているSocketURLLoaderを利用した。他にも,URLLoaderにはGETでリクエストを送ると何故かヘッダが付加されないなどの不具合があるようなので,込み入ったリクエストを送る場合はSocketURLLoaderを利用したほうがよさげ。
コード
評価を追加するためのクラス
package { import flash.events.*; import flash.net.*; import code.google.as3httpclient.*; public class RatingTask { private var videoId:String; private var ratingRate:int; private var userId:String; private var userPassword:String; private var authToken:String; public var isSuccess:Boolean; public var onExecuted:Function; private const CLIENT_ID:String = "YourClientID"; private const DEVELOPER_KEY:String = "YourDeveloperKey"; private const CLIENT_LOGIN_URI:String = "https://www.google.com/youtube/accounts/ClientLogin"; private const RATING_URI_PREFIX:String = "http://gdata.youtube.com/feeds/api/videos/"; private const RATING_URI_SUFFIX:String = "/ratings"; // ユーザー情報を与えて初期化 public function RatingTask(videoId:String, ratingRate:int, userId:String, userPassword:String) { this.videoId = videoId; this.ratingRate = ratingRate; this.userId = userId; this.userPassword = userPassword; this.isSuccess = false; } // ログイン public function load():void { // ログインリクエストを作成 var loginRequest:URLRequest = new URLRequest(CLIENT_LOGIN_URI); loginRequest.method = URLRequestMethod.POST; loginRequest.contentType = "application/x-www-form-urlencoded"; var variables:URLVariables = new URLVariables(); variables.Email = userId; variables.Passwd = userPassword; variables.service = "youtube"; variables.source = "ratingtask"; loginRequest.data = variables; // ログイン実行 var loginLoader:URLLoader = new URLLoader(); loginLoader.addEventListener(Event.COMPLETE, onAuth); loginLoader.addEventListener(IOErrorEvent.IO_ERROR, onError); loginLoader.load(loginRequest); } // 評価 public function onAuth(event:Event):void { // 認証トークンを取得する var loginLoader:URLLoader = URLLoader(event.target); var matches:Array = loginLoader.data.match(/Auth=([^\s]*)/); if (matches == null || matches.length < 2) { onError(new Event("認証トークンの取得に失敗しました")); return; } authToken = matches[1]; // 評価リクエストを作成 var ratingRequest:URLRequest = new URLRequest(RATING_URI_PREFIX + videoId + RATING_URI_SUFFIX); ratingRequest.method = URLRequestMethod.POST; ratingRequest.contentType = "application/atom+xml"; ratingRequest.data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<entry xmlns=\"http://www.w3.org/2005/Atom\"\n" + " xmlns:gd=\"http://schemas.google.com/g/2005\">\n" + " <gd:rating value=\"" + ratingRate + "\" min=\"1\" max=\"5\"/>\n" + "</entry>\n"; ratingRequest.requestHeaders = [ new URLRequestHeader("Content-Length", ratingRequest.data.length), new URLRequestHeader("Authorization", "GoogleLogin auth=" + authToken), new URLRequestHeader("X-GData-Client", CLIENT_ID), new URLRequestHeader("X-GData-Key", "key=" + DEVELOPER_KEY) ]; // 評価実行 var ratingLoader:SocketURLLoader = new SocketURLLoader(); ratingLoader.addEventListener(Event.COMPLETE, onRating); ratingLoader.addEventListener(IOErrorEvent.IO_ERROR, onError); ratingLoader.load(ratingRequest); } // 評価後 public function onRating(event:Event):void { var loader:SocketURLLoader = SocketURLLoader(event.target); var matches:Array = loader.data.match(/<\?xml.[^\?>]*\?>/); if (matches == null) { onError(new Event("評価の追加に失敗しました")); return; } isSuccess = true; if (onExecuted != null) { onExecuted(); } } // エラー処理 public function onError(event:Event):void { isSuccess = false; if (onExecuted != null) { onExecuted(); } } } }
使い方
var videoId:String = "hogehoge"; var ratingRate:int = 5; var userName:String = "YourName"; var userPassword:String = "YourPassword"; ratingTask = new RatingTask(videoId, ratingRate, userName, userPassword); ratingTask.onExecuted = function():void{ if (ratingTask.isSuccess) { trace("評価の追加に成功したっぽい"); } else { trace("評価の追加に失敗したっぽい"); } }; ratingTask.load();