« &autoplay=1 | メイン | たまったプロセスを一気にkillする »

P::P::Filter::YouTubeFromTitle

Last.FMとはてなミュージックがはくRSSのエントリーtitleを検索キーにしてYouTubeの映像をとってきてembedのhtmlをbodyにぶち込むというPlaggerのFilter作ってみた。野良Pluginってやつだね。例えば、iTunesで最近聞いた曲に関係するYouTubeの映像が見れる(はず)。 Filter::DegradeYouTubeと組み合わせるといい感じ。config.yamlはこんな

plugins:

  - module: Subscription::Config
     config:
      feed:
#         - url: http://music.hatelabo.jp/username/?type=recent&mode=rss
         - url: http://ws.audioscrobbler.com/1.0/user/username/recenttracks.rss

  - module: Filter::YouTubeFromTitle
     config:
       search_sort: video_view_count # optional

  - module: Filter::DegradeYouTube
     config:
       dev_id: xxxxxxxxxx

以下、Plagger::Plugin::Filter::YouTubeFromTitle。文字コード関係と正規表現にてこずった。汚いコードだと思うが、一応動いちょる。pmファイルも、ここに置いとく。

package Plagger::Plugin::Filter::YouTubeFromTitle;

use strict;
use base qw( Plagger::Plugin );
use Encode;
use HTML::Entities;

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'update.entry.fixup' => \&filter,
    );
}

sub filter {
    my($self, $context, $args) = @_;
    my $e = $args->{entry};
        my ($keywords, $title, $artist,$video_id);

        $title = $e->title;
        $title = encode('UTF-8',$title);
        
        #hatena music
        if($title =~ /(.*?)\s-\s.*?\s-\s(.*?)\Z/){
                $title = decode('UTF-8',$1);
                $artist = decode('UTF-8',$2);
        }
        #Last.FM/audioscrobbler
        elsif($title =~ /(.*?)\s\342\200\223\s(.*?)\Z/){
                $artist = decode('UTF-8',$1);
                $title = decode('UTF-8',$2);
        }
        $keywords = $artist . " " . $title;
        
        $video_id = search_youtube($self,$context,$keywords);
        unless($video_id eq ''){
                $e->title( $title . " by " . $artist );
        }else{
                $video_id = search_youtube($self,$context,$artist);
                $e->title($artist);
        }
        
        unless($video_id eq ''){
                $e->link("http://www.youtube.com/watch?v=$video_id");
                $e->body(embed($video_id));
        }

}

sub embed{
        my ($video_id) = @_;
        my $html = '<object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/%s"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/%s" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object>';
        $html = sprintf($html, $video_id);
        return $html;
}

sub search_youtube{
        my ($self,$context,$query) = @_;
#        my $query = decode_entities($query);
    my $url  = URI->new('http://youtube.com/results');
    my $file = $self->cache->path_to('youtube_search_result.html');

    $query = encode('UTF-8', $query) unless $context->conf->{no_decode_utf8};
    $context->log( info => 'Getting YouTube search results for ' . $query );

    my $ua = Plagger::UserAgent->new;
        $url->query_form(
                                         search_type     => 'search_videos',
                                         search_query    => $query,
                                         search_sort     => $self->conf->{search_sort} || 'video_view_count',
                                 );
        
        my $res = $ua->mirror( $url->as_string => $file );
        if($res->is_error){
                $context->log( error => $res->status );
                return;
        }
        
        open my $fh, "<:encoding(utf-8)", $file
            or return $context->log(error => "$file: $!");

        my $video_id;
        while (<$fh>) {
                if(m!<a href="/watch\?v=(.*?)"!){
                        $video_id = $1;
                        $context->log(info => "Found YouTube video: $video_id");
                        last;
                }
        }
        return $video_id;
}

1;
__END__

=head1 NAME

Plagger::Plugin::Filter::YouTubeFromTitle - get YouTube movie related entry title

=head1 SYNOPSIS

  - module: Filter::YouTubeFromTitle
    config:
      search_sort: video_view_count

=head1 CONFIG

=over 4

=item search_sort

Sort method. Optional.

=back

=head1 AUTHOR

Yusuke Wada

=head1 SEE ALSO

L<Plagger>

=cut

と、これを使えば、Last.FM及びはてなミュージックとYouTubeのマッシュアップサイトができるかもしれないが(ダイナミックに動かそうと思ってyappoさんのCatalyt::Plugin::Plaggerを使ってみたが動かなかったYO)、もうすでに「I Love Music Video」というすごいサイトがあるんだな。ま、これはPlaggerなんでいろいろ応用利きそう(そいえばLast.FMというかaudioscrobblerとはてなのRSSにはCCのライセンスがついてるよ)。

トラックバック

このエントリーのトラックバックURL:
http://yusukebe.com/mt/mt-tb.cgi/2060

この一覧は、次のエントリーを参照しています: P::P::Filter::YouTubeFromTitle:

» PlaggerでFFmpeg 送信元 Wiki Number8 (PukiWiki/TrackBack 0.4)
準備 ffmpeg aacなどをサポートしたffmpegを取得。下記リンク参照。 FFmpeg.pm $ svn co http://svn.mizz... [詳しくはこちら]

» Plagger+MT4.1で洋楽Video情報提供サイトfm+tubesを作ってみました 送信元 WEBデザイン BLOG
PlaggerとMT4.1を使って自動更新できるサイトを構築してみました。その仕組み、コードなどの情報を紹介しています。 [詳しくはこちら]

コメント (2)

june29 Author Profile Page:

ゆーすけべーさん

初めまして,cameraLady管理人のjune29と申します.「エロリスト」のときにすごい衝撃を受けまして,ゆーすけべーさんがエロ以外のコンテンツも手がけたら破壊的だなぁと思っていました.そこにきて「CDTube」のリリースがあり,アイディアといい実装といいボクの中を貫くものがありました.尊敬しています!

Last.FMやはてなミュージックの情報を利用すると,ランキングも自動生成されるのでよりユーザ寄りのコンテンツが生み出されるばかりではなく,CDTVや他のランキングを作成している側から文句を言われることもなくなりますよね!YouTubeが白か黒かという議論は置いておくとすれば,今後の発展に期待せずにはいられません!

いきなりのコメントで失礼しました.これからもゆーすけべーさんの動向をチェックさせてもらいます!

尊敬なんて恥ずかしくなっちゃいますYO!

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)


ブログSEO対策:track word seo