最近CPAN Authorになった僕ですが、PerlといえばCPANモジュールを利用するのがあたりまえ(?)ですよね。
そこで自分なりに習作としてキッチンタイマーをGtk2とGtk2::GladeXMLをつかって作成しようとしたところで問題に引っかかったのでご報告したいと思います。
Gladeをつかってファイルをつくってウィンドウをつくってカウントダウンをするところまでは順調でした、しかしいざBeep音をならすところになって用意したmp3ファイルを再生するためのライブラリとしてはじめに目をつけたのはAudio::Play::MPlayerでした。
一見順調に思えたこのモジュールですが、いざ利用するとなぜかアプリケーションの終了後mplayerを利用した別threadがのこってしまっているのでした。はじめは別threadのしょりでthreadが終了しないのかと思いましたが、どうも違うのではと思いました。
こういう問題のときは問題の原因を把握する事が最優先です。まず私はAudio::Play::MPlayerで単純にファイルを再生して終了するだけのスクリプトをかいてみました。するとなんとこのスクリプトが終了しないのです。これでまずは問題がなにかしらこのライブラリに有るのだろうという事は見当がつきます。
そうなると次は実装を確認する事です。Audio::Play::MPlayerの実行のsampleとして掲載されているのは以下のようなコードです。
use Audio::Play::MPlayer; # same as Audio::Play::MPG123 $player = Audio::Play::MPlayer->new; $player->load( "ex-mp30.mp3" ); print $player->title, "\n"; $player->poll( 1 ) until $player->state == 0;
ここで注目したいのは最終行だ、untillをつかっている。あからさまにココが怪しい、終了条件を探ってみよう。
Audio::Player::MPlayerの実装を確認しよう。
sub state { my( $self ) = @_; return $self->{state}; }
単純にstateを返却しているようだ、ではstateはどこで確認しているのかというと、なんとこのコード
どこにもmplayerのステータスを確認している行が無い!!
信じられないがこれが現実だ。つまり、これは再生が終了してようと終了していまいとステータスに変化はないということだ。
具体的にいうとモジュール内でstopが読み出されたらstatusを停止に、などと変更しているだけで実際のmplayerのモードを確認しているコードは一つもないのだ
では、自分で実装しようと思うのがプログラマ心だ。mplayerからステータスを受け取るだけなら単純だろうと思い
mplayerのslaveモード(このプラグインはslaveモードを使う事でmplayerを操作しようとしている)のコマンドを確認すると......
なんと、MPlayerにもステータスを確認するコマンドが無い残念ながらこのタイマーのプログラムからなんとMPlayerのソースをいじる必要までに発展したのである。
と、いうわけで現状Audio::Play::MPlayerがまともに動作する可能性はほぼ無い。しかしSTATコマンドでステータスを確認できるmpg123プログラムをカバーしたAudio::Play::MPG123モジュールは無事動作した、よって私はAudio::Play::MPG123を代替として利用する事を進めようとおもう。