わーくあうと!

日々の作業でためになったことをアウトプットすることで自分の成長につながればなと。

ニコ動のURLからブログ記事のアイキャッチを自動的に作成する方法

wordpressで、youtubeニコニコ動画からアイキャッチを自動生成する方法を探してたら↓の記事を見つけた。

YouTubeの動画からブログ記事のアイキャッチ画像を自動的に作成する方法

この記事を参考に『auto-post-thumbnail.php』の

// Get all images from post's body
 preg_match_all('/<\s*img [^\>]*src\s*=\s*[\""\']?([^\""\'>]*)/i', $post[0]->post_content, $matches);

の下に

if (empty($matches[0])) {
 preg_match('%(?:youtube\.com/(?:user/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $post[0]->post_content, $match);
 if (!empty($match[1])) {
 $matches=array(); $matches[0]=$matches[1]=array('http://i3.ytimg.com/vi/'.$match[1].'/hqdefault.jpg');
 }
}

を追記する事でYouTubeの動画が貼られた記事で自動でアイキャッチを作成することができた。

その勢いで正規表現部分とサムネ画像URL部分をいじればニコ動にも対応できるかなーと思い、

if (empty($matches[0])) {
 preg_match('/http:\/\/(?:www\.nicovideo\.jp\/watch|nico\.ms)\/[a-z][a-z](\d+)/', $post[0]->post_content, $match);
 if (!empty($match[1])) {
 $matches=array(); $matches[0]=$matches[1]=array('http://tn-skr.smilevideo.jp/smile?i='.$match[1]);
 }
}

といったコードを先程のYouTubeのコードの下に追記したが、うまく行かなかった。

色々とデバッグした結果、どうやら『function apt_generate_post_thumb』内でmimeタイプのチェックをしているが、これがファイルの拡張子でチェックしているため拡張子が偽装されているものについてはここで弾かれているようだった(ニコ動のサムネはファイル名に拡張子が無い)

ということで、ファイルデータから直接mimeタイプを取れるよう修正した(プラグインを直接編集するのは気が引けるが...)

編集内容は

// No file type! No point to proceed further
 if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) ) {
 return null;
}

という記述の

if (!$type || !$ext) {
 $finfo = finfo_open(FILEINFO_MIME_TYPE);
 $type = finfo_buffer($finfo, $file_data);
 $ext = "aaa";//なんでもいいから値入れる.
 finfo_close($finfo);
}

を書く。

これでニコ動のアイキャッチ生成にも対応できた。

LESSのbox-shadow、transitionなどで複数パラメータを使用する

すいませんすいません。最近アプリ開発をサボってちょっとしたWebサイト作ってます・・・。

で、久しぶりにcssいじってたらLESSなんて便利なものがあったので使ってたのですが、『box-shadow』や『transition』で複数の値カンマ区切りでいい感じに指定する方法が見つからなくて悩んだので解決策をメモっておきます。

解決までの経緯を書くのが面倒なので、最終的なコードを晒すと

/* box-shadow. */
.box-shadow(...) {
 @props: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
 -webkit-box-shadow: @props;
 -moz-box-shadow: @props;
 -ms-box-shadow: @props;
 -o-box-shadow: @props;
 box-shadow: @props;
}
.box-shadow(@style) {
 -webkit-box-shadow: @style;
 -moz-box-shadow: @style;
 -ms-box-shadow: @style;
 -o-box-shadow: @style;
 box-shadow: @style;
}

こんな感じでmixin定義。で、

.box-shadow(0 0 10px 0 rgba(0,0,0,0.2), inset 0 0 10px 0 rgba(255,0,0,0.2);

こんな感じで呼び出す。 複数指定しない場合は

.box-shadow(0 0 10px 0 rgba(0,0,0,0.2);

こんな感じ。

で、「RGBAの値を入力するのが面倒だ!16進数指定したい!hex!」って場合は

.box-shadow(0 0 10px 0 fade(#000, 20%);

という書き方もできる。

このmixinについてざっくり説明すると、引数が複数の場合は上の .box-shadow を呼んで、引数が一つの場合は下の .box-shadow を呼ぶようになっている。

また、『transition』でも同じように

/* transition. */
.transition(...) {
 @props: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
 -webkit-transition: @props;
 -moz-transition: @props;
 -ms-transition: @props;
 -o-transition: @props;
 transition: @props;
}
.transition(@style) {
 -webkit-transition: @style;
 -moz-transition: @style;
 -ms-transition: @style;
 -o-transition: @style;
 transition: @style;
}

と定義しておけば複数パラメータに対応できる。

MindNodeからfreeMindへのデータ移行方法

かなり限定的な話だけど、さっきマインドマップツールを移行する時に移行方法を発見したのでメモっておく。

  1. freeMindのノードを全選択してコピー
  2. 適当なテキストエディタに貼り付け
  3. 「    」←スペース4つを「」←タブ文字に置換(タブ文字を書けないのでそこはいい感じにやって下さい...)
  4. 置換後の文字列をコピってMindNodeに貼りつけ

以上。

最近のハイライト(4月19日版)

最近のAir for iOSでのアプリ制作で困ったこと、考えたこと、どうやって解決したか、などをつらつらとメモっておく。(主にプログラム周り)

 

イベントを活用しようと思った

今までサーバーサイドのプログラムばかり書いていたせいかイベント駆動の概念が無かったが、これからは使ってみようと思った。

例えば『メニュー』クリックで『シーン』を切り替える処理を書く場合、

イベント使わない → メニュークラス から シーンクラス の シーンを切り替える() メソッドを呼ぶ。

イベント使う → メニュークラス から シーン切り替えのイベントを送出。シーンクラスでイベントを受け取り、シーンを切り替える。

こんな感じに書ける。

何が嬉しいかというと、メニュークラスとシーンクラスの依存を断ち切る事ができる。うん。嬉しい。使っていこう。

 

データの永続化どうしよう

これは書いているうちに長くなったので別エントリにまとめた。

Air for iOSでのデータ保存について - わーくあうと!

 

リファレンス見やすくて嬉しい

あと ActionScript 3.0 のリファレンスガイドがとても見やすい。それぞれのクラスの継承関係から使用例、メソッドの詳細まで細かく書いてるので、リンクを辿って読んでいくと新しい発見もあって楽しい。

例えば上のほうで書いた、「イベントを使おう」と思ったきっかけも、

俺:「SharedObjectが継承しているEventDispatcherってなんだろう」

(リファレンス読む)

俺:「へーこんな事できるのかー面白そう。使ってみよう」

って経緯だった。リファレンス読もう。

 

その他AS3についてもろもろ

AS3ってこんな書き方できないのーとTwitterでつぶやいてみた

 

もちろん誰からもリプライは無かった。

以上、最近のハイライトでした。

Air for iOSでのデータ保存について

ゲームを作ってるとゲーム内の値(所持金、経験値など)をローカルに保存する必要が出てくる。

方法は色々あるが、『SharedObject』や『File』、『SQLite』なんかを使う方法があるらしい。

これは特に迷う事無くSharedObjectを使おうと決めた。理由はオブジェクトをそのまま保存できて自前でシリアライズする手間もなく、一番ラクそうだったから。

カスタムクラスの保存ができない・・・

そんなこんなで使ってみたがカスタムクラスの保存ができない。というかObject型で保存される。少し調べてみたら、『registerClassAlias』関数でカスタムクラスをあらかじめ登録することでカスタムクラスのインスタンスを保存できるようになるようだった。

registerClassAlias("HogeModel", HogeModel);
SharedObject.getLocal(Defines.APP_SO_NAME_SPACE);

↑こんな感じでSharedObject.getLocalの前にカスタムクラスを登録する。

(これはこれで保存するカスタムクラスをいちいち書かないといけなくて面倒だけど)

勝手に保存される・・・

SharedObjectの動きを確認していると、SharedObject.flush()を読んでいなくても保存されていることに気がついた。どこかに.flush()するコード残ってたかなーと探してみたが見当たらない。

あれー、、と思いながらリファレンスのflushの説明を読んでみると

ローカルに永続化された共有オブジェクトを直ちにローカルファイルに書き込みます。このメソッドを使用しない場合、共有オブジェクトがファイルに書き込まれるのは、共有オブジェクトセッションの終了時となります。つまり、SWF ファイルが閉じられるとき、共有オブジェクトが参照されなくなってガベージコレクションされるとき、SharedObject.clear() または SharedObject.close() が呼び出されたとき、のいずれかの時点です。

と書かれている。仕様でした。

これはこれで便利だが、自分が想定していない所で保存されると追い辛いバグを孕みそうな予感がしたので、自前の保存関数をかまして使うことで、自動で保存されないようにした。

コードで書くと下記のような感じ

public class AppData {

    public function AppData() {
    }

    /*
    * SharedObjectを取得.
    */
    public static function getSharedObject():SharedObject {
        registerClassAlias("HogeModel", HogeModel);
        return SharedObject.getLocal(Defines.APP_SO_NAME_SPACE);
    }

    /*
    * (1)SharedObjectの保存領域部分を返す.
    */
    private static var __tmp:Object;
    public static function getDataObject():Object {
        var so:SharedObject = AppData.getSharedObject();

        if(__tmp == null){
            __tmp = ObjectUtil.clone(so.data);
        }
        return __tmp;
    }

    /*
    * (2)保存.
    */
    public static function saveAll():void {
        var so:SharedObject = AppData.getSharedObject();
        //↓__tmpを入れなおしている.
        so.data = AppData.getDataObject();
        so.flush();
    }
}

(1)で保存領域を複製した物(__tmp)を返し、(2)でso.dataに代入しなおして保存している。

これはまぁぶっちゃけ保存し忘れするかもしれないってのとトレードオフの関係なので、やるべきかどうかは個人の自由かなと思う。

以上。そんな感じ。

情報が多すぎる

最近は、朝起きて朝ご飯を食べつつ

のチェックをしていると、(日によるが)全て見終わる頃にはもう昼過ぎになっている。

その後は昼ご飯を食べてちょっと昼寝して、起きたらまたtwitterなどを巡回して、やっとアプリ開発作業を始める。

見なきゃいいのに目の前に情報があったら気になってそわそわしてしまうので見てしまう。

情報が多すぎる。

Air Debug Lancher(ADL)のプレビューが画面に収まらない件

Air for iOSでのアプリ開発、普段は Air Debug Lancher(ADL) でプレビューしてるんだけど

自分の環境ではディスプレイに収まらなかった。

スクリーンショット 2013-04-13 12.59.21

↑下のほう収まってないんです。

ADLの表示倍率を変更できる設定がないか探したけど見当たらなかった。

iOSシュミレーターなら表示倍率が変えられるし、3GSの解像度で表示もできるからどうにかなるがパブリッシュに時間が掛かり過ぎて使ってられないし。 で、どうしたものかと。

考えた末に思いつきました。

Air for iOS設定を開いて、『起動時の縦横比』を『横長モード』にしてプレビューしたのがこれ↓

スクリーンショット 2013-04-13 13.10.53

うーん、、まあ正しい対応かと言われると微妙だが、仕方ないのでとりあえずはこれでやってみる。  

 

iOS端末で左右に隙間ができる件

開発中のアプリをiOSシュミレータ&iOS端末で確認するとなぜか左右に隙間ができていて、背景のサイズも確認したが問題無さそうなのになんでー?と思ってたらどうやらフルスクリーンモードで書きだして無かったため横縦比はそのままで上のステータスバーの分だけ微妙に縮小されてた模様。

フルスクリーンモードで書きだすようにして解決した。

十分な容量がどうとかでiOS端末にipa送れない件

なんかAir for iOSでパブリッシュしてiPhoneipa送るときに「デバイスエラー デバイスに十分な容量があるか確認してください。」とか言われた。

もちろん容量は余っている。

http://kuniakisuzuki.cocolog-nifty.com/blog/2012/09/flash-cs6air-fo.html

で、適当にググったら↑の記事を発見。どうやら.p12ファイルを使い回してると出る場合があるらしい。

確かにテストアプリを作った時から使い回して使ってるわ。ということでキーチェーンアクセスから.p12形式の証明書を作り直してパブリッシュした。

が、状況変わらず・・・

なんだろうなーと、Flashの再インストールとかしてみようかなーでもそれは面倒だなーと悩んだが、少し寝たら原因分かった。

アプリケーションIDが違ってた。しょうもない。

ということでアプリケーションIDを iOS Dev Center で設定したものに変更してパブリッシュしたら無事端末に送れた。

めでたしめでたし。

 

4月13日追記==========================

全然めでたく無かった。やっぱりおかしい。ちょっと作業してパブリッシュしたらまた同じ症状がでた。

アプリケーションIDも合ってる、.p12ファイルも合ってる、プロビジョニングファイルも合ってる。謎・・・

とりあえず出来上がったipaiTunesから入れてみたら入った。

この問題を追うと時間かかりそう&解決できなさそうなので、しばらくはiTunesから実機に送ることにしよう。