0

YouTubeのAPI

検索


youtube_searchっていうgemが便利だった
gem install youtube_search


検索すると配列が何十件か返ってきて、その中にhashで検索結果が入ってる
タイトルやvideo_idが取れる。
#!/usr/bin/env ruby
require 'rubygems'
require 'youtube_search'

video = YoutubeSearch.search('隕石').first
puts video["video_id"]


プレイヤー


JSでプレイヤーを作れるAPIがあったので、ためしてみた。
なんかAPIがかっこわるい。あとURLから動画を再生する関数が動いてない気がする。video_idから再生はできる。

http://shokai.github.com/youtube-js-api-study

0

ブラウザ用EventEmitterを作った

もうあるので車輪の再発明だけど、作った
https://github.com/shokai/event_emitter.js


元々sinatra-cometioの中で使っていたのを切り出して、テストとか書いた。

Ruby版といっしょに使うと楽しい。

event emitterとは


Node.jsに含まれているライブラリ。をWebブラウザだけで動くように実装しなおした。


こんな感じでapplyすると
var User = function(){
new EventEmitter().apply(this);
this.name = '';
};

イベント登録して
var user = new User();
user.name = 'shokai';
user.on('go', function(data.place){
alert(user.name+' -> '+data.place);
});

呼び出せるようになる
user.emit('go', {place: 'mountain'}); // "shokai -> mountain"

あと、onのかわりにonceで登録すると1回だけ呼び出せるイベントになったりとかある。
JavaScriptの全てオブジェクトに簡単にイベント機能が追加できる。
くわしくはREADMEを見て。


test


ブラウザで使うjsだけどterminalでテストしたかったので、nodeunitを使った。


このようにnode実行した時はnode moduleとして読み込めるように、event_emitter.jsの末尾でmodule.exportsに登録しておいた。
var EventEmitter = function(){
/** 略 **/
};

if(typeof module !== 'undefined' && typeof module.exports !== 'undefined'){
module.exports = EventEmitter;
}

あとはnodeunitでテストを書いた。


JavaScriptの圧縮


uglify-jsで圧縮した

0

JSでHTMLにScriptタグを挿入する

var load_script = function(url, onload){
var script = document.createElement("script");
script.src = url;
if(typeof onload === "function"){
script.onload = onload;
script.onreadystatechange = function(){
if(readyState=="loaded" || readyState=="complete"){
onload();
}
};
}
document.body.appendChild(script);
};

load_script("//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js",function(){
alert("script load success!!");
});

0

PhoneGap/CordovaのWebViewの拡張方法(調査)

Android版PhoneGap(Cordova)で新しいwebブラウザのプロトタイプ的なものを作る方法を調べた。
既存のwebサイトを表示して、その上に自作のUIを表示したりしてページを操作できるようなのを作る。
例えばbubble cursorを常時使用し続けるAndroid用webブラウザ等が作れる。

っぽい方法をわりと真面目に調べた。まだ試していない。


手順

PhoneGapプラグインを作ると、Java側でonNativeReadyイベントを受け取れる。
そのタイミングでスクリプトタグをHTMLの末尾に挿入すれば、既存のwebサイト上にcordova.jsを読み込ませたり、自分のスクリプトを実行したりできる。
(試していないが多分できると思う)


既存サイトにスクリプトタグを挿入する


スクリプト挿入するbookmarkletを作る。

これを
(function(){
var load_script = function(url){
var script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
};
load_script('//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
})();


圧縮してbookmarklet形式にする
javascript:(function(){var e=function(e){var t=document.createElement("script");t.src=e,document.body.appendChild(t)};e("//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js")})();
nodeのuglify-jsを使った


試しにjQueryが読み込まれていないサイトで実行してみると、jQueryが使えるようになる


webView上でスクリプト実行


MainActivity.java のsuper.loadUrl();でindex.htmlを読み込んでいる。
その後で
super.loadurl("javascript:alert('hello!!!')");
を書くと、ページを読んだ時に実行できる。


前述のbookmarkletをloadUrlすればいい。


しかし、alertと違って前述のscriptタグ挿入bookmarkletは、HTMLがロード完了してDOMが構築し終わってからでないと動かなかった(当たり前だが)
また、MainActivity.javaに書いても最初の1ページ目でしかスクリプトが挿入できないので、ページ遷移する都度scriptタグ挿入してやる必要がある。


とりあえず後輩のうすきくんと一緒に検証してみた。

MainActivityの中で
super.loadUrl("http://www.yahoo.co.jp");
final MainActivity self = this;
new Thread(){
public void run(){
try{
Thread.sleep(10000);
self.loadUrl("javascript:(function(){var e=function(e){var t=document.createElement('script');t.src=e,document.body.appendChild(t)};e('http://shokai.org/alert.js')})();");
}
catch(Exception ex){
Log.e(ex);
}
}
}.start();
(このコード、思い出して書いたので多少間違ってるかも)


なんと動いた。
ページ遷移完了後にloadUrlでbookmarklet実行したいんだけど、イベントが取得できないので10秒待ってからスクリプトタグを挿入した。
まずはPhoneGapのwebview上に後からスクリプトタグ挿入できるかの検証なので、alert.jsの中身はalert(“script insert success!!!”);しか書かないようにした。


あとは、10秒待つのではなくページ遷移毎にスクリプトタグ挿入できれば目標達成できる。


JavaScriptファイルはfile://の場所で指定してもロードしてくれなかったが、HTTPでアクセスできる場所に置いたらロードしてくれた。gistやgithubとかに置いてもいいと思う。


ページ遷移イベント


PhoneGapプラグインを作れば、外部サイトをロードした場合でもページ遷移完了イベントを受け取れる。


WebViewの画面遷移やロード完了イベントは、WebViewClientを設定すればイベントを受けられるのだが、PhoneGap(Cordova)本体が先にWebViewClientを設定してしまっている。
つまり先客がいるわけで、自作のWebViewClientをPhoneGapに食わせる事はできない。


とりあえずCordovaのソースコードを読んでみる
https://github.com/apache/incubator-cordova-android


framework/src/org/apache/cordova/CordovaWebViewClient.java がWebViewClientを継承したクラスで、コイツがPhoneGapのWebViewのイベントを全て受信している。
これを書きなおして自分でcordova.jarをビルドしてもいいのだが、本体を修正すると更新についていけなくなるので避けたい。


さらに辿ってみると、 framework/src/org/apache/cordova/CordovaWebViewClient.java からpostMessage関数で”onNativeReady”というイベントが送られている。
onNativeReadyは framework/assets/js/cordova.android.js の中から呼ばれている。
PhoneGapでよく使われるJS側のdevicereadyイベントの直後に呼び出される。

んで framework/src/org/apache/cordova/api/PluginManager.java から全プラグインにpostMessageの内容が中継されているので、

phonegap pluginを作って、onMessageで”onNativeReady”イベントを受け取れば、ページが読み込み終わった事がJava側でわかるはず。


そのタイミングでloadUrlにbookmarklet形式でスクリプトタグ挿入させればいいのではないか?

という所まで調べたのでうすきくん頑張ってください・・


PhoneGap pluginの作成


このへんが参考になると思われる。

Apache Cordova API Documentation Plugin Development Guide
橋本商会 » PhoneGap NFC Plugin作った

プラグインの解説はJavaのコードをJavaScriptから利用するためのインタフェースを作る部分が大半なのだが、
今回はPluginManagerが中継しているonNativeReadyイベントを受け取ってブックマークレット実行するだけなので、ほとんどの部分を読み飛ばして良いと思うしJSも書く必要ないと思う。

0

Sinatra用のcometプラグインを作った

追記:RocketIOに統合されました → 橋本商会 » Sinatra RocketIOというプラグイン作った、これでWebSocketとCometが使える

******

作った

Sinatra Comet I/O

インストール

gem install sinatra-cometio



通信を意識せずに、サーバー側からクライアントの関数、クライアント側からサーバーの関数を呼び出せる。


サーバーからクライアントへプッシュする例

サーバー側


Ruby
require 'sinatra'
require 'sinatra/cometio'

CometIO.push :chat, :name => "shokai", :message=> "hello work!!"


クライアント側


HTML
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="<%= cometio_js %>"></script>

JS
var io = new CometIO().connect();
io.on("chat", function(data){
console.log(data.name + " : " + data.message); // -> "shokai : hello work!!"
});


クライアント→サーバーの例や、新規クライアント接続イベントやエラーイベント等についてもSinatra Comet I/Oに書きました


サンプルとしてHerokuでチャットを作った。 http://cometio-chat.herokuapp.com

チャットの場合同時に300クライアントぐらいしか接続できないっぽい。スケールさせる方法はよくわからない。
少人数で使うちょっとしたツールにリッチなUIを持たせる時などに便利だと思います。


*チャットサンプルですが1台のマシンから2つchrome開いても、交互に通信するみたいです。片方をsafariにするか、chromeをプライベートブラウズモードにすると動きます
色々やってたら大丈夫になりました