CakePHP Advent Calendar 2010を読んでいて、そんなこともできるんだっていう記事が多いので、あとで、投稿された記事をまとめてファイルにしようかと思いました。
続きを読む
「CakePHP」カテゴリーアーカイブ
CakePHP + jQuery webcam plugin
プロフィールの画像を直接取得できればいいかなぁって思い、このプラグインを使ってみました。
最初は、jQueryだけでwebカメラの操作ができるんだって思っていました。
でも実際は、flashとjQueryを組み合わせて使います。
概要
- ウェブカメラからの画像を画面にキャプチャする(html5 canvas)
- ウェブカメラからの画像を取得しサーバー上に保存する
※デスクトップキャプチャソフト等も使えます。
完成イメージ
参考サイト
配布元
Ajalog.7z:jQueryでWebカメラを制御する
環境
- XAMPP
- CakePHP1.3.5
- jQuery1.4.3
- jQuery webcam plugin
準備
- 配布元からファイルをDL&展開
- 展開してできたファイルを適当な場所に設置(e.g. app/webroot/js/jquery.webcam.js app/webroot/swf/jscam.swf and jscam_canvas_only.swf)
- ウェブカメラを接続 or デスクトップキャプチャ等のソフトをインストール
webcam plugin
swfファイル
次の2つがあります。使いたい状況に応じて設定します。
- jscam.swf
- jscam_canvas_only.swf
1.はすべての機能が使えます。
2.はcanvasに描画する機能のみです。サーバー側にsaveしたい場合は1.を使います。
function
- capture(delay):delay秒後にcaptureします
- save(file): キャプチャ画像を保存 mode:”save”時にfile名を設定するとサーバー側に保存
- getCameraList():有効なカメラリストの取得
- setCamera(index):getCameraList()のindexでカメラを切り替える
mode
- callback
- save
- stream
の3種類があります。
callbackは各コールバック関数を呼びます。
saveはcallbackと変わりませんが、save(file)を実行するときにデータを指定したファイルパスへ送信します。
streamは配布元を参照して下さい。
他のパラメータは、配布元を参照してください。
キャプチャした画像をcanvasに描画する処理は上記の参考サイトに書いてあるので、ここではサーバー側の処理を行います。
mode:“save”
onSave():画像の保存完了後に呼び出される。
保存画像を表示させるには、
このコールバックの中でページを書き換え処理を入れるか、
リダイレクトを行えばいいと思います。
jQuery関係のファイルは適当な場所で読み込む。
<strong>Webカメラから画像を設定</strong> <div id="jquery_camera"></div> <div id="camerastatus" style="margin-left: 10px;"> <strong>カメラリスト</strong> <ul id="cams"></ul> <div id="status"></div> <button id="btn">キャプチャ</button> </div> <?php $this->Html->scriptStart(array('inline' => false)); ?> $(function(){ var width = 320; var height = 240; $("#jquery_camera").webcam({ width: width, // webcamの横サイズ height: height,// webcamの縦サイズ mode: "save", //swffile: "/swf/jscam_canvas_only.swf", swffile: "/swf/jscam.swf", // captrue(delay)が実行されたとき、残り時間を引数にもち、 // 1秒ごとに呼び出される // e.g. delay = 5のときは remainが5,4,...,1と変化して呼び出される。 onTick: function(remain) { if(0 == remain){ $("#status").text("Cheese!"); }else{ $("#status").text(remain + "seconds remaining..."); } }, // mode:saveの場合 // サーバー側での保存が完了し、サーバーからのレスポンスがくると呼ばれる onSave : function () { //キャプチャした画像をwebcam.saveメソッドで保存すると呼び出される。 $("#status").text("done!!"); var url = "リダイレクト先"; window.location = url; }, // Capture時に呼び出される onCapture: function() { webcam.save('/users/upload/<?= $this->data['User']['id'] ?>'); }, // debug用 debug: function(type, string) { $("#status").html(type + ": " + string); }, // 読み込み完了時 onLoad: function() { var cams = webcam.getCameraList(); for(var i in cams) { $("#cams").append("<li>" + cams[i] + "</li>"); } $("#btn").click(function(){ webcam.capture(); }); } }); }) <?php $this->Html->scriptEnd(); ?>
CakePHP
app/controllers/webcams_controller.php
・・・ function upload($id = null){ $this->laout = ''; $updir = ini_get('upload_tmp_dir'); $str = file_get_contents("php://input"); $filepath = $updir . DS . 'user.jpg'; file_put_contents($filepath, pack("H*", $str)); // これ以降にDBへの登録処理をおこなう // e.g.下の処理はMediaPluginを使った時の処理の例 $this->data['Picture']['title'] = ''; $this->data['Picture']['description'] = ''; $this->data['Picture']['model'] = 'User'; $this->data['Picture']['foreign_key'] = $id; $this->data['Picture']['file'] = $filepath; if($this->Picture->save($this->data)){ @unlink($filepath); exit(); }else{ //失敗時の処理 } ・・・
CakePHP + ZendFramework (Gdata)でYouTubeアプリ作成
ZendFramework (Gdata)を使ってYouTubeのデータを操作
ZendFrameworkのGdataを使用して、YouTubeのデータ処理を行ってみました。
概要
YouTubeのAPIには
動画のデータ操作を行うData APIと
プレイヤーの操作を行うPlayer APIがあります。
この2つのAPIを利用して以下を行います。
- YouTubeのApiを使って、ほしいデータを検索(Data API)
- HP上に動画プレイヤーを設置する(Player API)
- 検索した動画を設置した動画プレイヤーで再生する
他にも動画のアップロード等ができますが、そちらは、参考資料を参考にしてください。
クライアントライブラリはPHPとjavascriptだけではなく、Javaなどのほかの言語でも提供されています。
完成イメージ
環境
- CakePHP1.3.5
- jQuery1.4.3
- ZendGdata-1.11.0
参考資料
Zend Gdataの設定
- 上記のリンクからGdataの圧縮ファイルをDL&展開しておく
- 展開したなかのlibraryディレクトリの中のZendディレクトリをvendorsまたはapp/vendorsに設置する。i.e.vendors/Zend or app/vendors/Zend
- ここからZendFrameworkLoader Componentを作成する。i.e. app/contorollers/components/zend.phpを作成
app/contorollers/components/zend.php
<?php class ZendComponent extends Object { /** * Controller Startup Initialisation * Add APP/vendor to include path * * @throws Exception */ public function startup() { $include = get_include_path(); // Zendディレクトリをapp/vendorsに設置した場合 // $include.= PATH_SEPARATOR . APP . 'vendors' . DS; // Zendディレクトリをvendorsに設置した場合 $include.= PATH_SEPARATOR . VENDORS; $successful = set_include_path($include); ........... } ?>
Controllerの作成
app/controllers/youtube_controller.php
<?php class YoutubeController extends AppController{ public $name = 'Youtube'; public $uses = ''; public $layout = 'default'; public $components = array('Zend'); public function index(){ // YouTubeクラスのロード $this->Zend->loadClass('Zend_Gdata_YouTube'); $yt = new Zend_Gdata_YouTube(); // Queryの作成 $query = $yt->newVideoQuery(); $query->videoQuery = '世界卓球 -パチンコ -AKB'; $query->startIndex = 1; // 開始番号 $query->maxResults = 10; // 検索取得数 $query->orderBy = 'viewCount'; // 閲覧数順 // Feedの取得 $videoFeed = $yt->getVideoFeed($query); // $videoFeed = $yt->getUserFavorites('username'); // ユーザのお気に入りの動画を取得 // 取得したFeedをView変数に設定する $this->set('videoFeed', $videoFeed); } } ?>
ZendFrameworkは使ったことがなかったので、知らなかったのですが、
クラス名はディレクトリの階層をアンダーバー”_”で区切ってつけられています。
たとえば。。
Zend_Gdata_YouTubeクラスは
Zend/Gdata/YouTube.phpにあります。
この命名規約のため階層が深くなれば、newするときのメソッド名が長くなります。
短くするために、上のコードのように
$query = $yt->newVideoQuery();
でnewできるようになっています。
VideoQueryは実際は、
Zend/Gdata/YouTube/VideoQuery.php
にあります。
さらに、$query->startIndexとメンバ変数のように設定している箇所があります。
しかし、クラス、継承しているクラスを見てみると、そのようなメンバ変数はありません。
ここの実際のメソッドはsetStartIndex()です。
setter&getterはメンバ変数のように扱える仕組みになっているようです。
Viewの作成
app/views/layouts/default.ctp
..... <head> <?php echo $this->Html->charset(); ?> <title> <?php __('CakePHP: the rapid development php framework:'); ?> <?php echo $title_for_layout; ?> </title> <?php echo $this->Html->meta('icon'); // ============================================== // CSS // ============================================== echo $this->Html->css('cake.generic'); // ============================================== // javascript // ============================================== echo $this->Html->script('swfobject'); echo $this->Html->script('jquery-1.4.3.min'); echo $scripts_for_layout; ?> </head> .......
app/views/youtube/index.ctp
<!-- TEST作成のため、CSSは直接書いている--> <h1>test</h1> <div id="yt" style="width: 800px;margin: auto;"> <div style="float: left;"> <div id="ytapiplayer"> You need Flash player 8+ and JavaScript enabled to view this video. </div> </div> <div style="margin-left: 5px; float: left;width:260px; height:375px; overflow: scroll;"> <?php foreach ($videoFeed as $videoEntry) { // サムネイルの取得 $videoThumbnails = $videoEntry->getVideoThumbnails(); // サムネイルは4つ取得できる(ここでは1つだけ表示した) foreach ($videoThumbnails as $thumbnail) { echo $this->Html->image($thumbnail['url'], array('height' => 90, 'width' => 120, 'id' => $videoEntry->getVideoId(), 'class' => 'youtube', 'title' => $videoEntry->getVideoTitle(), 'alt' => $videoEntry->getVideoTitle())); break; } } ?> </div> </div> <script type="text/javascript"> var ytplayer = null; // playerの準備が完了後に呼び出されるコールバック // playerを制御するには必ず実装が必要 function onYouTubePlayerReady(playerid){ // プレイヤーを取得(swfobjectで指定したidを指定する) ytplayer = document.getElementById("myytplayer"); // ytplayer.cueVideoById(); } var params = { allowScriptAccess: "always" }; var atts = { id: "myytplayer" }; swfobject.embedSWF("http://www.youtube.com/v/u1zgFlCw8Aw?enablejsapi=1&playerapiid=ytplayer", "ytapiplayer", "500", "375", "8", null, null, params, atts); $(function(){ $("img.youtube").click(function(){ ytplayer.loadVideoById($(this).attr("id")); }); $("img.youtube").hover(function(){ $(this).css("cursor", "pointer") .fadeTo("fast", 0.5); },function(){ $(this).fadeTo("fast", 1); }) }); </script>
imgタグのid属性に動画のidを設定しています。
サムネイルがクリックされたときに、その動画が再生されます。