たとえばこんな感じのフィードがあったとします。
<?xml version="1.0" encoding="utf-8"?>
<feed>
<entry>
<key>blog1</key>
<title>blog1-title</title>
<content>blog1-content</content>
</entry>
<entry>
<key>blog2</key>
<title>blog2-title</title>
<content>blog2-content</content>
</entry>
<entry>
<key>blog3</key>
<title>blog3-title</title>
<content>blog3-content</content>
</entry>
<entry>
<key>blog4</key>
<title>blog4-title</title>
<content>blog4-content</content>
</entry>
<entry>
<key>blog5</key>
<title>blog5-title</title>
<content>blog5-content</content>
</entry>
</feed>
単純に parse するとハッシュに格納されるので
entry の並び順はめちゃくちゃになります。
dump結果
$VAR1 = {
'entry' => {
'blog2' => {
'content' => 'blog2-content',
'title' => 'blog2-title'
},
'blog5' => {
'content' => 'blog5-content',
'title' => 'blog5-title'
},
'blog4' => {
'content' => 'blog4-content',
'title' => 'blog4-title'
},
'blog1' => {
'content' => 'blog1-content',
'title' => 'blog1-title'
},
'blog3' => {
'content' => 'blog3-content',
'title' => 'blog3-title'
}
}
};
ランキングの RSS とかだと entry の順番が変わるだけで致命的です。
今回がまさにその状態。
blog1〜5の順番で entry に入っていてほしかったのです。
できないかと思って調べてたらいけました。
how to preserve XML::Simple element order
どうやら Tie::IxHash を使えばいけそうとのこと。
Tie::IxHash については ハッシュのキーを挿入(追加)した順番通りに取り出す がとても
まとまっておりわかりやすいです。
#!/usr/bin/perl
use strict;
use warnings;
use Tie::IxHash;
use XML::Simple;
use Data::Dumper;
*XML::Simple::new_hashref = 'new_hashref';
sub new_hashref {
my $self = shift;
tie my %hash, 'Tie::IxHash';
%hash = @_;
return \%hash;
}
my $parser = XML::Simple->new();
my $xml = $parser->XMLin('sample.xml');
warn Dumper $xml;
1;
__END__
結果
$VAR1 = {
'entry' => {
'blog1' => {
'content' => 'blog1-content',
'title' => 'blog1-title'
},
'blog2' => {
'content' => 'blog2-content',
'title' => 'blog2-title'
},
'blog3' => {
'content' => 'blog3-content',
'title' => 'blog3-title'
},
'blog4' => {
'content' => 'blog4-content',
'title' => 'blog4-title'
},
'blog5' => {
'content' => 'blog5-content',
'title' => 'blog5-title'
}
}
};
このように new_hashref を Tie::IxHash で tie してやった
ハッシュリファレンスを返すように override してやれば大丈夫です。
XML::LibXML でも同じようなことはできるらしいです。
よく忘れるのでメモ。
シンボルテーブルの一覧を取得するには以下の方法で取得できます。
ポイントはモジュール名の後に :: をつけること。
これよく忘れます。
%モジュール::;
で、これだと変数なのか関数なのかが判断できません。
そこで便利なのが Devel::Symdump です。
@array = Devel::Symdump->functions(@packs);
これだけで関数一覧が取得できます。
関数だけでなく hash や scalar が取得できたり
diff とれたり HTML で出力できたり地味に便利です。
Test::Continuous に興味がわいたので
さわってみようとしたらMac::Growl が必要とのこと。
いれようとしたら Foundation.pm 等がないためちゃんと test に通らなかった。
どうやら ports でいれたのには Foundation の ラッパーモジュール がないらしい。
variants で調べて +darwin を足していれなおしたけどなかった。
というわけでいいのかわからないけど、デフォルトに入ってるのにシンボリックリンクを貼って
その場をしのいだ。
以下、説明。
mac 独自に bundle されたモジュール類(Foundation.pmとか)は
/System/Library/Perl/Extras/5.8.8/darwin-thread-multi-2level 以下にあります。
Foundation.pm が PerlObjCBridge.pm と CoreFoundation.pm にも依存していたので忘れなく貼ること。
自分の環境だと以下のパスに貼った。
sudo ln -s /System/Library/Perl/Extras/5.8.8/darwin-thread-multi-2level/Foundation.pm /opt/local/lib/perl5/5.10.0/darwin-2level/Foundation.pm
sudo ln -s /System/Library/Perl/Extras/5.8.8/darwin-thread-multi-2level/CoreFoundation.pm /opt/local/lib/perl5/5.10.0/darwin-2level/CoreFoundation.pm
sudo ln -s /System/Library/Perl/Extras/5.8.8/darwin-thread-multi-2level/PerlObjCBridge.pm /opt/local/lib/perl5/5.10.0/darwin-2level/PerlObjCBridge.pm
perl のバージョンが 5.10 だけど 5.8.8 からのシンボリックリンクでも現状、一応動いてる。
ただ、Mac::Growl が utf8 で文字を渡しても文字化けする始末。
というわけで Net::Growl や GNTP::Growl も試してみたが
残園なことにNet::Growl は何もおこらない。
GNTP::Grwol は IO::Socket::INET でコネクションできない感じ。
IO::Socket::INET: connect: Connection refused at /opt/local/lib/perl5/site_perl/5.10.0/GNTP/Growl.pm line 44, line 1.
うむぅ〜困った。
追記 2009/08/29 20:17:22
snow leopard にしたら Mac::Growl が使えなくなった。
どうやら Carbon 系が 32bit でしか使えないみたい。
64bit で起動させると使えない。
ソース
Feed(RSS, Atom) 共にモジュールがいっぱいあって何を使えばいいのかいまいちわからない。
というわけで調べるついでにベンチマークをとった。
とったといっても RSSのパース速度の比較 と
Atomのパース速度の比較 を参考にさせてもらい(ほぼ流用です。。。)
少しだけ比較するモジュールをたして計測してみた。
さっそく結果
[RSS]
Rate XML::Feed XML::RSS XML::Simple Data::Feed XML::RSS::LibXML XML::FeedPP XML::LibXML regexp
XML::Feed 1.68/s -- -1% -96% -96% -96% -97% -100% -100%
XML::RSS 1.70/s 1% -- -96% -96% -96% -96% -100% -100%
XML::Simple 37.9/s 2153% 2128% -- -18% -20% -22% -89% -100%
Data::Feed 46.1/s 2642% 2611% 22% -- -3% -5% -87% -99%
XML::RSS::LibXML 47.3/s 2714% 2683% 25% 3% -- -2% -87% -99%
XML::FeedPP 48.3/s 2771% 2739% 27% 5% 2% -- -86% -99%
XML::LibXML 356/s 21105% 20868% 841% 673% 653% 639% -- -96%
regexp 7941/s 472363% 467069% 20871% 17132% 16687% 16356% 2128% --
[Atom]
Rate XML::FeedPP Data::Feed XML::Feed XML::Atom XML::LibXML
XML::FeedPP 108/s -- -68% -69% -73% -81%
Data::Feed 336/s 210% -- -4% -15% -41%
XML::Feed 352/s 225% 5% -- -12% -38%
XML::Atom 398/s 267% 18% 13% -- -30%
XML::LibXML 570/s 426% 69% 62% 43% --
正規表現は半端なくはやかったです。
さすがって感じ。ただ作るパターンは注意しないといけない。
で、びっくりしたのが XML::RSS がものすごくおそい。。
他にも XML::RSSLite や XML::RSS::Parser も試したが CDATA セクションが入ったりすると
パースエラーを起こしてパースできなくなったりしたんで、今回の対象からははずしました。
やっぱり速いのは XML::LibXML が Atom, RSS ともに圧倒的にはやかったです。
ただ個人的に XPath を書くのはあまりすきではないのがネック。
Atom だと XML::Atom という宮川さんが書かれたモジュールが速い。
ただ名前空間に Atom ってある通り RSS を読み込ませると試した限りパースできなかった。
Atom に最適化してあるからはやいのかな。
XML::RSS::LibXML も RSS に特化してる感じ。
Data::Feed XML::FeedPP XML::Feed の3つが RSS, Atom 共にパースできる。
中でも Data::Feed は id:lestrrat さんが作られてるとのこと。
そして 4/19 にも更新されててメンテもされてる。XML::FeedPP も XML::Feed もメンテはされてる。
ただ XML::Feed は RSS のパースがあまりに遅いので、Data::Feed か XML::FeedPP がいい気がする。
両方ともインターフェースは似てて同じ感覚で使える。あとは好みの問題なんだろーなと。
XML::FeedPP の pod の方が分かりやすいから、最初はそっちで触るのがよいかも。
XML::FeedPP か Data::Feed を使ってれば変なとこではささらない気がする。
あといらない情報が少ない Atom の方がパースも全体的に速かった。
つっこみなどあればよろしくです。
準備
mac ports を使用して ffmpeg をインストールします。
mac ports の詳細はここをみてください。
音声だけ抜き出して mp3 にする
ffmpeg -y -i hoge.flv -acodec copy hoge.mp3
iphone用の動画(mp4)に変換
ffmpeg -y -i hoge.flv -vcodec libx264 -s 320x240 -b 1024k -acodec libfaac -ac 2 -ar 24000 -ab 96k -f mp4 hoge.mp4
画質を奇麗にしたければ -b(ビットレート) をあげてやればいい。
これをエイリアスにしたい
いちいち覚えれないからエイリアスにして簡単にできたらいいなと。
わざわざこれぐらいでコマンドファイルもつくりたくないし。
#perl -le '($f)=split(/\./, $ARGV[0]);`ffmpeg -y -i $f.flv -acodec copy $f.mp3`' hoge.flv
ワンライナーだとこんな感じででける。
ただこれを alias にすると動かなくなる。
#alias flv2mp3='perl -le "($f)=split(/\./, $ARGV[0]);`ffmpeg -y -i $f.flv -acodec copy $f.mp3`"'
#flv2mp3 hoge.flv
どーすればいいんだろうか。。。。
分かる人ヘルプ