Feedsの利用

Feedsを導入してYouTubeの動画のRSS Feedからノードを作成し、サイトで利用する方法について記載します。
この設定をしておけば登録したフィードが更新されるとそれにあわせて新しいノードが自動的に作成できるようになります。

前回、Media FeatureのMedia Contentでテスト用のノードが作成できなかったので、手入力するのもアレですのでRSS Feedを使って一括登録しようというものです。RSS Feedを使っているのでリモートのサイトが更新されれば自動的に当サイトの内容も更新されますので、現実的な方法だと思います。

1.モジュールの導入

必要なモジュールは以下になります。ついでにtokenとpathautoモジュールも導入しました。

Feeds リモートサイトからRSSフィードを取得する以外にファイルからも可能です。
Fetch/Parser/Processorをそれぞれ設定することでサイトにデータのインポートが可能になります。
Job Scheduler Feedsの要件になっているモジュールです。
リモートサイトから新たにRSS Feedを取得し更新する時間を管理するものだと思います。
Media Feeds ProcessorのマッピングでMedia Assetが選択できるようになります。
media internet(WEBに入力したURL)とmedia libarary(ライブラリに登録されたファイル名)の2種類から選択可能になります。
Feeds YouTube Parser YouTubeフィード用のパーサーを追加するモジュールです。YouTubeで公開されているAPIに対応していますので、他のパーサより詳細な情報を入手可能になります。使用できるフィードURLを選ぶようなのでチューニングが必要になります。
Token pathauto(自動URLエイリアス)の要件になっているモジュールのため導入しました。pathauto以外でも利用するので導入していても損はありません。
 
Pathauto URLエイリアスを自動作成するために導入しました。
通常コンテントはすべてcontent/ノードタイトルのパスになりますが、動画関連のコンテントはmedia/ノードタイトルに設定しようと予定しています。

導入は「drush core-cli」でdrushを起動し、「dl モジュール名」でダウンロードおよび「sites/all/modules」に配置までしてくれますので、drushを使うと早いです。
※ただし、テンポラリにディレクトリが作成されたままになりますので注意してください。

あとはモジュールを有効にするだけです。
※simplepipeパーサーを利用する場合は、「feeds/libraries」以下に「simplepipe.inc」を置いてください。なおsimplepipeのバージョンは1.2以降が必要です。

2.Feedsインポータの作成

RSSフィード用のインポータがデフォルトで作成されていますが、今回はこれを複製して利用することにしました。

以下の内容でYouTubeのRSSフィード用のインポータを作成します。

基本設定
基本設定

基本設定(環境設定)
基本設定(環境設定)

フェッチャー(選択)
フェッチャー(選択)

フェッチャー(環境設定)
フェッチャー(環境設定)

パーサー(選択)
パーサー(選択)

パーサー(環境設定)
パーサー(環境設定)

Processor(選択)
Processor(選択)

Processor(環境設定)
Processor(環境設定)

Processor(Mapping)
Processor(Mapping)
 

3.フィードノードの登録

Feedsモジュールを登録するとコンテンツタイプに「フィード」と「Feed Item」が作成されています。
ここでは「フィード」コンテンツタイプでノードを作成します。
作成は、通常の方法ではなく2番で作成したインポータの添付(Attechment)のリンクから作成します。
そうすることでインポータとフィードノードが関連付けされるようです。

作成するフィードノードには【タイトル】と【フィードURL】を入力します。
※【フィードURL】は使用しているフィードパーサーにあったフォーマットで入力してください。
※今回利用したYouTubeパーサは正常に動作するURLのフォーマットはかなり限定されます。
フィードノードの作成

参考:フィードURLの例(ユーザIDがtheKatsuieの動画用)

http://gdata.youtube.com/feeds/api/videos?alt=rss&orderby=published&author=theKatsuie

フィードURLの数だけフィードノードを作成します。

4.Viewsの調整(Optional)

Feedsモジュールを導入するとViewsに「feeds_defaults_feed_items」が作成されています。
デフォルトではフィードノードによってFeed Itemコンテンツタイプでノードが作成されますが、ViewsでこのFeed Itemコンテンツタイプのノード一覧を表示できるようになっています。
今回はメディアコンテンツタイプのノードを作成するようにインポータを設定しましたので、その修正をViewsの「feeds_defaults_feed_items」にします。

修正箇所は以下の2点です。

(1)ノードタイプの追加

作成されるノードタイプが表示されるように修正しました。
表示するノードタイプの追加
 

(2)フィードノードを表示するViewsページを追加します。

フィードノード一覧を表示するページを新規作成しました。
フィードノード一覧用ページ作成

5.ショートカットの作成(Optional)

操作性アップのため、作成したインポータやフィードノードの表示用のショートカットリンクを登録しておきます。
※この機能を利用するにはモジュール一覧でコアのshortcutモジュールを有効にする必要があります。

6.フィードのインポート

実際にリモートサイトのフィードを読み取りノードを作成します。
※この部分はD6のFeedAPI+Feed Element Mapperと操作は同じです。
5番で作成したショートカットを利用してフィードノード一覧を表示させ、一覧からインポートしたいフィードノードを選択します。
選択すると以下の画面が表示されます。手動の場合はこの画面で操作を行ないます。

【インポート】ボタンをクリックすると実際にインポートが開始されノードが作成されます。
フィードのインポート操作

7.フィードアイテムの確認

インポートして作成されたノードはフィードアイテム(FeedItem)と呼ばれます。
【View Items】タブをクリックすればインポートされ作成されたノード一覧を表示できます。
※4番でViewsの調整をしていないとデフォルトのコンテンツタイプしか表示されません。
※一覧はノードのティーザー表示になっているので、右下のもっと読む(more)をクリックして完全なノードを表示させてください。

ノードの中身を参照して、動画プレイヤーが表示できるかまた再生が行えるかをチェックします。
インポートで作成したノード

※再生前に画像が表示されない(プレイヤー画面が真っ黒な状態)の場合は、画像URLが正しく取り込めていない可能性があります。
※エラーなどが発生しているケースもありますので【Log】タブで稼動ログを確認してみてください。ただし、ここに表示されていないからといって正常とは限らないようです。ノードが作成されていない(Itemタブに何もない)場合はパーサとプロセッサの設定およびフィードURLを疑って再確認してみてください。
 

8.フロントページの調整

フロントページはViewsのmediaで生成されたページが表示されるようになっています。
うまく設定ができていれば、画像+タイトル一覧の上にプレイヤーが表示された状態になります。

テストサイトの状態が以下の画像です。
フロントページ(不具合あり)

現在はこのように正常な状態ではありません。
画像が正しく表示されているのはMulimedia Assetを使用せずにファイルのファイルアップロードフィールドで作成したノードです。

※2012.01.18 問題は解決して現在のフロントページが以下のようになりました。
※media contentにあったタイトルのうち1つだけ手で登録してあります。
フロントページ(正常)

不具合の解説

Feedsでインポートする部分では、メディアノード作成で必須となるデータをRSS Feedで取得してノードを作成しています。
※Processor(Mapping)の画像を参照してください。

今回の設定では画像URLの取得はメディアライブラリに登録後にファイル名(パス)が決定されることを想定しています。


YouTubeサイトの画像URLはそのままでは「Video ID/0.jpg」といった命名則になっているため画像ファイル名は「0.jpg」になり、他のビデオとの重複が発生してしまうため都合が悪い状態です。そこで、Media:YouTubeによって、ビデオURLに含まれるVideoIDから画像のURLが決定されるようにしています。FeedsのパーサのMappingで画像URLをサムネイルにせずMedia:Youtubeに任せるようにソースを未選択のままにしたのもそれが理由になります。

Media:Youtubeによって画像URLは「Video ID.jpg」に変換されます。(※画像のオリジナルURLは「Video ID/0.jpg」)
ビデオURLと画像URLが決定されるとMediaモジュールによってメディアライブラリへの登録などが行われます。
このMediaモジュールの処理の中で、画像ファイルに関してはリモートサイト(今回はYouTube)からサーバ上にダウンロードされ画像ファイル名は「Video ID.jpg」でファイルシステム以下の「media_youtube」に保存されます。

この一連の処理の中で、メディアプレイヤーに利用される画像をリモートサイトからダウンロードするためにload_file()関数が使用され、そしてメディアライブラリなどへ登録する(ローカルサーバに保存する)ためにsave_file()関数が使用されています。この間にデータベースへの登録などが行われますが、データベースへの登録はsave_file()が実行されるときにコアのfile.incでファイルタイプなどのチェックをパスすれば正常に行われるようです。

今回はこのチェックでエラーが発生しているためにそれ以降が正常に処理できていません。
以下がエラーメッセージの例です。

Warning: filesize() [function.filesize]: stat failed for youtube://v/S0mmUarhhUk file_save() (【Drupalルートディレクトリ】/includes/file.inc ファイル 573行).

これは、対象ファイルをデータベースに登録するために必要な情報(ファイルサイズなど)を取得する際にエラーが発生しているというものです。
ここで気になるのはファイルのパス名が「youtube:」で始まっている点と「//v/S0mmUarhhUk」となっている点(拡張子がない)です。
※D7からは内部のファイルパス名に「public:」や「private:」で表記されるようになり、これらはファイルシステムに設定したパス名に置き換わるようです。

不都合箇所

不都合箇所は2箇所あり、(2)に関する事項が致命的になっています。
これは前の記事でMedia contentが利用できなかった理由と同じで、共通してMultiMedia Assetに関する問題だと思います。
※2012.01.18に解決済みです。

(1)メディアプレイヤーに画像が表示されない

Feedのインポートでメディアノードを作成した際、各ノードのページにはそれぞれメディアプレイヤーが表示されます。
動画の再生は正常ですが、再生前の状態でメディアプレイヤーに画像が表示されていません。
このとき、最近のログメッセージにImageCacheファイルが保存できないエラーメッセージが出力されていました。
これは、ファイルシステムをデフォルトのパスから変更しているために発生したようです。
Drupal導入直後の状態ではファイルシステム以下には「.htaccess」(ファイル)、「language」(ディレクトリ)、「style」(ディレクトリ)が存在しています。
ファイルシステムを変更すると変更先のディレクトリと「.htaccess」は作成されます。
さらにキャッシュクリアを実行するかcron.phpを実行すると「language」が新しい場所に作成されます。
しかし、ImageCacheで使用される「style」だけは作成されませんので、マニュアルで新しい場所へコピーしました。
「style」に関してはこれだけでは不十分だったらしく、画像スタイル(画像キャッシュプリセット)画面で上書き保存をすべてのプリセットに対して実行しないといけなかったようです。この作業を実行しすればプリセット名のディレクトリが作成されるためImageCacheのエラーメッセージがなくなりました。

(2)画像フィールドが空の状態

フロントページのViewsページを表示する場所には、すべてのメディアノードのタイトルと画像の一覧が表示されなければなりませんが、タイトルしか表示されません。※先ほどの「function.filesize」のエラーメッセージが原因です。
これはMediaモジュール内のsave_load()関数から呼び出されているようで、画像URLからファイルサイズが取得できなかったことを示すメッセージのようでした。正常に動作していれば、ファイルシステム以下のmedia_youtubeに「Video ID.jpg」のファイル名で画像ファイルが作成されているはずですが、何もありません。
ここでもしmedia_youtubeフォルダ内に画像ファイルが存在していればファイルスタイルの設定をチューニングするだけで解決できます。

しかし、画像ファイルがない状態なので、サイトにはダウンロードできておらずメディアライブラリにも登録されていないので何をしても画像を表示することはできません。Multimedia Assetフィールドを使用している限りうまくいかないようです。

想定原因

Media:YouTubeモジュールで画像URLの処理は様々な条件で決定されるようで、恐らくサイトの状態(たとえばPHPのバージョンに起因するもの)の影響で条件を満たさず正常に画像URLが設定できていないように推測されます。
正常ではない画像URLのままMediaモジュールにわたされるため、save_file()関数から呼び出されるコアのfile.incでエラーになっているのでしょう。

エラーメッセージに表示されているfilesize関数に渡されている画像のURLは「youtube://v/Video ID」になっています。
これがそもそも想定されたURLパスであるのか疑うところから調査をはじめるしかなさそうです。

Acquia Dev Desktopではうまくいっている箇所ですが、なぜさくらのレンタルサーバではダメなのか?
PHPのバージョンは5.2.17で同じです。使用しているモジュールおよびそれらのバージョンも同じです。
あとは、php.iniの設定とかPHPの動作モードとかウェブサーバのバージョンや設定がことなることとOSが異なる点くらいしか思い浮かびません。

とりあえず、filesize関数に渡されるURLが正常な状態ではどうなっているかを調査することからはじめようと思います。
ぱっとMedia:YouTube内を見た感じではURLをノーマライズ処理しているのでなんかおかしいように思いますが条件文により多岐にわかれているので内部でどの処理が実行されているのかデバッグしなければなりません。

そもそも今回導入したモジュールは開発のステータスのものがほとんどで何を基準にすればよいのかも定かではなく、調査には時間とスキルが必要そうなのでギブアップ!といったところです。

次回は、これまでにできるようになったことや新たにできないことが見つかったのでその辺りを整理して、今後、どのように進めるかについて検討したいと思います。
 

Drupalバージョン

Drupal 7.x モジュール