2012年1月アーカイブ

2012年1月31日

IPC::Cmd では空文字のパラメータを与えられ、るようになった

先の記事を書いた後に、拙い英語でバグ報告を送っておいたのだけれど、早速それを取り入れてくれたようで、 IPC::Cmd 0.76 からは、コマンドに空文字のパラメータを与えられるようになったみたいだ。( 0.74 で取り入れてくれたようだけれど、じぶんが書いた内容が不十分だった模様。。)

ただし、それには、新しいグローバル変数 $IPC::Cmd::ALLOW_NULL_ARGS に真をセットしておかなければならない。

use IPC::Cmd qw/run/;
$IPC::Cmd::ALLOW_NULL_ARGS = 1;
run( command => ["command" ,"--option", "", "arg1", "arg2" ]);

それはともかく Changes に名が入ることなんて初めてだったから、ちょっと嬉しい反面、中途半端なパッチと拙い英語文が残る事となって気まずさ半分。

2012年1月28日

IPC::Cmd では空文字のパラメータを与えられない

IPC::Cmd (0.72) である command を実行させようとして使ってみたら、どうもおかしい。オプションの位置がずれるかどうかしてしまっている。

調べてみると、コマンドラインを構成する文字列のリストの各要素、それが空文字だと捨てられてしまうようだ。

たとえば次のような、空文字を受け取るコマンドがあるとする:

$ command --opt "" arg1 arg2

これを IPC::Cmd で実行させようとする:

IPC::Cmd::run( command => ["command", "--opt", "", "arg1", "arg2"] );

すると、次のようなコマンドラインが生成されてしまう。

command --opt arg1 arg2

短絡的なパッチは次のような感じになったけれど、この変更がほかのところに影響するかどうか、そこまで見ていないので注意。気味が悪ければ IPC::Open3 などを使った方が、よいだろう。

--- Cmd.pm.orig	2012-01-28 18:06:59.000000000 +0900
+++ Cmd.pm	2012-01-28 18:07:12.000000000 +0900
@@ -1072,7 +1072,7 @@
     $cmd = _quote_args_vms( $cmd ) if IS_VMS;
 
     ### strip any empty elements from $cmd if present
-    $cmd = [ grep { defined && length } @$cmd ] if ref $cmd;
+    $cmd = [ grep { defined } @$cmd ] if ref $cmd;
 
     my $pp_cmd = (ref $cmd ? "@$cmd" : $cmd);
     print loc("Running [%1]...\n", $pp_cmd ) if $verbose;

追記:IPC::Cmd では空文字のパラメータを与えられ、るようになった http://blog.hwat.jp/life/201201/31-233200/

2012年1月27日

video タグからの要求に応える

Mojolicious でサーバ morbo を起動している。

video タグに指定した src の URL が public に置かれた静的コンテンツのときは、なんの問題もなくビデオ( mp4 )が再生された。

ただしビデオソースを public な場所に置く事に不都合な事情があったため、 video タグから要求された URL には、アクションに結びつけ、アクションはビデオのソースをバッファして、レスポンスに直接書き出すようにしたかった。

Safari (の video タグのヘルパー?は AppleCoreMedia というエージェントだった)からのリクエストは Range つきのリクエストで、これには Content-Range でもって、要求されたとおりのバイト範囲を部分的に返さないといけない事がわかった。(サーバは Range を無視できるにもかかわらず。)ビデオのソースを全部読み込んで、一気に返す、といった乱暴な手続きでは駄目だった。

# FIXME - support whole patterns of "Range" parameter
sub video {
    my $c       = shift;
    my $file    = shift;
    my $type    = shift;
    my $size    = -s $file;

    my ($buffer, $start, $end);
    my  $request_range = $c->req->headers->range;
    if( $request_range and $request_range =~ /bytes=(\d+)-(\d+)/ ){
        ($start, $end) = ($1, $2);
        $c->res->headers->status('206 Partial Content');
        $c->res->headers->content_range(
            sprintf('bytes %d-%d/%d', $start, $end, $size));
    }else{
        ($start, $end); = (0, $size -1);
        $c->res->headers->status('200 OK');
        $c->res->headers->content_length($size);
    }

    # read range
    my $handle = IO::File->new;
    $handle->open($file, "r");
    $handle->seek($start, 0);
    $handle->read($buffer, $end - $start + 1, 0);
    $handle->close;

    # send contents
    $c->render( data => $buffer, format => $type );
}

レスポンスを自前で組み立てないといけない? このへんは WAF のほうで面倒見てくれてもいいと思うのだけれども。

ただし、このやりかたも Firefox に対しては駄目だった(ちなみに Google Chrome はOKだった。)

2012年1月22日

video タグからのリクエスト

safari.png

Safari (バージョン 5.2.1) の video タグの src に指定した mp4 または flv の URL への HTTP リクエストは Range ヘッダ付きだった。それはいいのだけれども、問題となる現象が見られた。

<video src="..../video.mp4">

その要求に、サーバが Range を受け付けて "206 Partial Content" ではなく Range を無視して "200 OK" とともにコンテンツ全体を返すと(サーバは、 Range を無視する事ができる)、 Safari はそれを処理してくれないで、ふたたび Range 付きのリクエストを要求。といった現象が見られた。

結局 "200 OK" を返しているうちは、 video タグからは3回リクエストが来て、挙げ句にそのコンテンツは観ることができない。 ──何かの仕様を見落としているんだろうか。

2012年1月15日

急ぎの時の Proxy サーバ

急遽プロキシサーバが欲しくなって、探そうと思ったら最初に CPAN で検索してしまった。簡単手軽、お急ぎのときはこうだ:

$ perl -MHTTP::Proxy -e 'HTTP::Proxy->new(@ARGV)->start'

リモートホスト上で起動させるなら、 LISTEN するめに引数に host で受け付けるアドレスを指定して、 PORT はデフォルトが 8080 なので、変更するならそれも追加する。 new に @ARGV を置いたのはそういう理由。

$ perl -MHTTP::Proxy -e 'HTTP::Proxy->new(@ARGV)->start' host 0.0.0.0 port 3333

それから、コンテンツをフィルタするときは、レスポンスが全部揃ってから処理するために HTTP::Proxy::BodyFilter::complete を使うのが良いとの事。そうでないと、コンテンツデータを部分的に受信しながらその都度フィルタにかけようとしてしまう、ようだ。

2012年1月14日

Playlist: Vocaloids 2011 Five Stars ★

2011 年内にニコニコ動画に公開されて、じぶんがピックアップしてきた楽曲の中で、最高レート★★★★★にした曲の、今日の時点のリスト。

  1. ASTER - Lemm - 初音ミク
  2. ESQUIRE - emon - 鏡音リン
  3. 原罪地点 - 箸休/hashiyasume - 初音ミク
  4. Living in the Life - いちにぃ - 初音ミク
  5. コンシール - カーリー - 初音ミク
  6. そんな気がするんだ - れるりり - 初音ミク
  7. again'n again - U-ske - 初音ミク
  8. 君がそばにいるように - じょん - 初音ミク
  9. プラネタルーム - SWANTONE - 初音ミク
  10. Marbling city (Tong poo) - 恋竹林 - 初音ミク
  11. 不整合なWaltz - 庭野井戸 - miki
  12. さまよえる電波の羊 - akamimi - ほのか鳴
  13. 海想 - 36g - 初音ミク
  14. 498 - ぼーかりおどP - 初音ミク
  15. Pipipi ★ Hello - sa3sa3 - 初音ミク
  16. 私の大好きな夏 - ジェバンニP - 初音ミク
  17. 途切れない幻想へ - ヤオギ - 初音ミク
  18. 茜色 - れるりり - 鏡音リン
  19. 夏影 -Summer Wind Remix- - Clean Tears - 初音ミク
  20. いつか愛を - まじま - 初音ミク
  21. 86,400 - 西島ソーンダイク - 初音ミク
  22. A寝台の少女 - 36g - 初音ミク, 雪歌ユフ
  23. Tiny PaRadisE - kagomeP - 結月ゆかり
  24. empty strings - yahiro - 巡音ルカ

total 1:55:48 / 160.4 MB

496曲中、24曲あった。

これを平たく 2011 年トップリスト、と簡単に言えないのは事情がある。★を操作するのは、その曲を始めて聴いたときがほとんどで、第一印象のインパクトに大きく依存する、と思うから。──このリストの中にある曲もない曲も、繰り返し聴いているうちに、★の数が変わってくるものもあるだろうから。──また、聴くタイミングや、そのときのじぶんの情緒の在処によってまた★の数は変わってくるのであるから。

順番は、公開順にしたかったけれど、手持ちのデータベースに情報が満たされていないのでかなわず。順不同でもいいかと思ったけれど、やっぱりちょっと操作して、流れを作ってみた。といっても、なかなか難しいね、季節も曲調ジャンルも一貫してないから。

ときに、プレイリストを作る時はいつも「起承転結、転結起」って考える。最後に「起」を持って来ると、繰り返しまた聴きたくなるように。

2012年1月 2日

Playlist: Vocaloids 2011 Enter Winter

去る12月公開の作品群から組み立てたこのプレイリストの再生順序は、動画の公開順のまま。

なんとなくそれでも良かったから。決してめんどくさがったわけじゃなくて。プレイリスト作るのって楽しいのだから。

itunes.png
  1. Toys - mato - 初音ミク
  2. 生命回路 - けーだっしゅ - 初音ミク
  3. 39転調 - 西島ソーンダイク - 初音ミク
  4. what a wonderful world - Lovi'n - 初音ミク
  5. 雪の日 - もとほせ - 初音ミク
  6. 未来の風~Tomorrow Wind~ - たこ呆 - GUMI
  7. Vacant Boulevard - yahiro - 巡音ルカ
  8. ミーム22X - ワタヤノボル - GUMI
  9. Taste Of Sweet Love - Ageha - 初音ミク
  10. 祕密の森 - ムジカデリク - 初音ミク
  11. 冷たいこころ - 空海月 - 初音ミク
  12. who are you? - カラスヤサボウ - 鏡音リン
  13. 青よりもっと藍 - レアホースP - 初音ミク
  14. Loop - Clean Tears - 初音ミク
  15. toumin - げろげろ - 初音ミク
  16. 君の好きなように - ca-ru - 初音ミク
  17. 「I」 - 蝶々P - 鏡音リン
  18. ハイイロにとけて - lowbell - 巡音ルカ
  19. スノウランド - カーリー - 初音ミク
  20. テトロドトキサイザ2号 - ギガ - GUMI
  21. Killer Morning - KIYU - 初音ミク
  22. Tiny PaRadisE - kagomeP - 結月ゆかり
  23. 恋する気持ち止まんない - 空海月 - 初音ミク
  24. 小夜時雨 - あなぶら - 雪歌ユフ
  25. 寒空トゥララ - 吟 - 初音ミク, GUMI
  26. コイウタ - Clean Tears - 初音ミク

total 2:06:24 / 213.2 MB

AtomicParsley で貼れる JPEG ファイル

AtomicParsley でアートワークに JPEG ファイルを貼付けようと思ったら、エラーになった。

image file is not jpg/png and cannot be embedded.

JPEG ファイルが壊れているのかと思って、プレビューを使って別名で保存したものは、エラーにならなかった。

調べてみると、ひとくちに JPEG と言っても、「 JPEG は画像のデータ圧縮の規格でありフォーマットそのものではありません」とのこと。ではフォーマットは、というと JFIF というのが至極一般的との事。エラーになったのは、 JFIF ではない JPEG ファイルだったからなんだろう(確認する前に捨ててしまった... )。

いずれにせよ、今作っているツールでは、 AtomicParsley 実行して初めてエラーで知るのでは都合が悪い。 AtomicParsley を実行する前にそれを判断したいので、 AtomicParsley がどんなふうに画像フォーマットを調べそしてエラーに導いたのか、そこの判定処理を、今作っているツールの事前処理のところに埋め込みたいと思う。

従って、ソースをあたってみる事にした。

AtomicParsley のソース( AtomicParsley.cpp )を見てみると、 PNG 形式と、 JPEG の次の二つの形式をチェックしている、らしきところが見つかった:

173 int APar_TestArtworkBinaryData(const char* artworkPath) {
174         int artwork_dataType = 0;
175         FILE *artfile = APar_OpenFile(artworkPath, "rb");
176         if (artfile != NULL) {          
177                 fread(twenty_byte_buffer, 1, 8, artfile);
178                 if ( strncmp(twenty_byte_buffer, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) == 0 ) {
179                         artwork_dataType = AtomFlags_Data_PNGBinary;
180                 } else if ( strncmp(twenty_byte_buffer, "\xFF\xD8\xFF\xE0", 4) == 0 || memcmp(twenty_byte_buffer, "\xFF\xD8\xFF\xE1", 4) == 0 ) {
181                         artwork_dataType = AtomFlags_Data_JPEGBinary;
182                 } else {
183                         fprintf(stdout, "AtomicParsley error: %s\n\t image file is not jpg/png and cannot be embedded.\n", artworkPath);
184                         exit(1);
185                 }
186                 fclose(artfile);
187                 
188         } else {
189                 fprintf(stdout, "AtomicParsley error: %s\n\t image file could not be opened.\n", artworkPath);
190                 exit(1);
191         }
192         return artwork_dataType;
193 }

ファイルの先頭 8 バイトを読み込んで、バイトの並び方をチェック。 PNG 形式と JPEG 形式と。特に難しい事ではないけれど、ここでは、 AtomicParsley が実際にどんなパターンでチェックしているのかを確認できたことが重要だ。そのマニュアルには、アートワークに貼付けられる画像は png または jpeg 、とあったけれども jpeg にはいろいろなフォーマットがあって、そのうちの、この二種類のマジックナンバーが対応しているにすぎない。ということが、これで判った。

さてこうして、 AtomicParsley で埋め込み出来るイメージファイルであるかをチェックだけするルーチンを Perl で書く事が出来た。未対応の形式だったら、 PNG もしくは JFIF にコンバートすればよいだろう。

https://gist.github.com/1549186

余事ながら、この中で3カ所、ヘッダパターンをチェックしている記述があるけれど、ふたつは strncmp でチェックしているのに、あとの一つは memcmp でチェックしているのはなぜだろう? むしろすべてを memcmp でチェックすべきかな?

OpenID対応しています OpenIDについて

このアーカイブについて

このページには、2012年1月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2011年12月です。

次のアーカイブは2012年2月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。