Plagger向けのFilter::FetchEnclosure::Mplayerを書いた*1.これでenclosureをmplayerでwavファイルにダンプできる.ていうか,このプラグインだけだと何の役にも立たない.せめて,Filter::Convert::Lame*2のようなものが必要だ.
これは,enclosureで指定されたファイルがmplayerで再生できれば,その音声をwavにダンプできる.もとがmp3とかm4aなファイルならそんなことする必要はまったくないわけだが,動画やストリーミングでさえFetchできるのがこのプラグインの強みなわけ.
なんかアレゲプラグインな匂いがぷんぷんしますが気のせいでしょうか.
性懲りもなくソースコード貼付ける.本日もう眠いのでコレで勘弁.
package Plagger::Plugin::Filter::FetchEnclosure::Mplayer; use strict; use base qw(Plagger::Plugin::Filter::FetchEnclosure); use POE; use POE::Session; use POE::Wheel::Run; sub register { my($self, $context) = @_; $context->register_hook( $self, 'update.entry.fixup' => \&enqueue, 'update.fixup' => \&fetch, ); } sub enqueue { my($self, $context, $args) = @_; my $body = $args->{entry}->body; $context->log(debug => "body = $body"); for my $enclosure ($args->{entry}->enclosures) { # TODO: do all of this in the base class ::Command my $feed_dir = File::Spec->catfile($self->conf->{dir}, $args->{feed}->id_safe); unless (-e $feed_dir && -d _) { $context->log(info => "mkdir $feed_dir"); mkdir $feed_dir, 0777; } my $path = File::Spec->catfile($feed_dir, $enclosure->filename); if ($enclosure->length && -e $path && -s _ == $enclosure->length) { # TODO: if-none-match $context->log(debug => $enclosure->url . "is already stored in $path"); next; } $context->log(info => "fetch " . $enclosure->url . " to " . $path); POE::Session->create( inline_states => { _start => sub { $_[HEAP]->{wheel} = POE::Wheel::Run->new( Program => [ 'mplayer', $enclosure->url, '-vc', 'dummy', '-vo', 'null', '-ao', "pcm:file=$path", ], StdoutEvent => 'stdout', ErrorEvent => 'wheel_close', CloseEvent => 'wheel_close', ); }, stdout => sub { if ($_[ARG0] =~ /Starting playback.../) { my $length = -s $path; $enclosure->local_path($path); $enclosure->type('audio/x-wav'); $context->log(info => "Dumping to $path is done [$length]"); } $context->log(debug => "$_[ARG0]"); }, wheel_close => sub { delete $_[HEAP]->{wheel}; }, }, ); } } sub fetch { Plagger->context->log(info => "Start dumping stream as wav files using mplayer."); POE::Kernel->run; Plagger->context->log(info => "Dumping finished."); } 1; __END__ =head1 NAME Plagger::Plugin::Filter::FetchEnclosure::Mplayer - Fetch enclosures using mplayer =head1 SYNOPSIS - module: Filter::FetchEnclosure::Mplayer config: dir: /path/to/download =head1 DESCRIPTION This plugin dumps audio/video stream to a wav file. =head1 AUTHOR Yohei Fushii =head1 SEE ALSO L<Plagger> =cut