Gekkaoブログ

趣味やソフトウェアに関するメモや記録

Opera での swfobject (Youtube API)がうまく動作しないケース

2009年06月03日 | javascript
Youtube APIを使って再生する処理を作っていて、
Operaの場合にうまく行かないことがあったのでメモしておきます。
その原因は、swfobjectでの再生用オブジェクトを残したまま次のページに移動したときにおこるようですが・・

・主な使用ライブラリ

swfobject.js
swffit.js
Youtube API
json.js

・不具合と思われる現象

再生中にページをリロードすると次から正常に再生されない。
Youtubeの再生準備 onYouTubePlayerReady まで処理がこない。
playerapiidで指定したオブジェクトは存在するが、そのオブジェクトに本来あるplay()などの関数が定義されていない。
再生準備が整わずに待っているときに、ウインドウのサイズを変更したり再描画させると動作し始める。

・考えられる原因

1)swffit.jsではresizeイベントリスナーを使っている。生成タイミングでリサイズイベントが処理されないなどの問題が起きているのか?
2)YoutubeAPIをjavascriptから扱えるようにする処理で、何らかの不具合が発生している?

・対応方法とその結果

1)まずは、swffit.jsを使わないとどうなるか
 swffitでは、swfobjectが作ったオブジェクトを取り出し何かの追加処理をしている(Hook的な処理?)。ただし、必要なオブジェクトがすぐに正しく生成されていなければ、何らかの不具合の原因になる可能性がある。
 そこで、swffitをoperaの場合には使わないようにする。
→結果:この場合には、うまく再生できることもあるが、再生できない場合も残っている。

2)swffitでのサイズ変更を繰り返し呼び出す。
 ウインドウをリサイズまたは再描画すれば再生されるので、強制的にリサイズされるような処理を付け加えたり、何らかのDIV要素を追加してはずすといった処理をすればうまく行くのではないか?
→結果:うまく再生されることもあるが、途中で待ち状態に入った後は、それらの処理自体が呼び出されない。場合によっては、javascriptのエラーで、timeout待ちのあとのYoutubeAPIを使った再生処理が定義されていないいというエラーとなる。再生用関数play()が定義されているかを呼び出す前にチェックすることでエラーは回避できたが、根本的な問題は未解決となる。

3)再生用オブジェクトやswffitの処理のタイミングを変える。
 動作がおかしいときには、onYouTubePlayerReadyがまったく呼び出されないというのではない。途中でalert()などで何か表示させるとそれは動作する。ただし、その後の処理は動画の音声だけが再生されるようになったり、YoutubeAPIの一部の機能が使えない状態になったりと不定の状態になる。
 onYouTubePlayerReadyや再生リストを読み込んだ後の再生処理などは、後から動的にHTMLを追加した後の非同期的な処理として実行されているはずである。それがおかしくなる場合、それらを一旦本流のタイムアウトでのコールバック中に行うようにすればある程度改善されるのではないだろうか?タイムアウト関数を使った繰り返しではイベント駆動的な処理(イベントをPostし、コールバック中に該当イベントを処理する)を実装しているので、そこでリサイズや再生オブジェクトの生成などを行うように変更する。
→結果:onYouTubePlayerReadyが呼び出されることは多くなったが、完全にクリアーになったわけではない。

4)ある意味お手上げ状態だが、次のページに切り替える前には必ずswfobjectが生成したものを削除するようにしてはどうか?
 今の実装では、swfobjectの生成したものを削除せずに次のページに移動することがある。その場合、前のオブジェクトが残ったままになり、うまく処理できなくなるのではないか?たとえば、onYouTubePlayerReadyやYotubeAPIの準備が前のオブジェクトのあるウインドウに対して行われるなど。そのため、切り替える前には完全に再生用オブジェクトを停止、削除するようにしてみる。
→結果:連続再生でのプログラムによる次のムービーへの移動や、ボタンによる処理の前でswfobjectが生成した再生用オブジェクトを停止、削除するようにした。すると、うまく再生される場合がかなり増えた。うまく再生されないケースはまだあるが、それは、再生中にページリロードさせたときにおかしくなる。ただし、そのときの動画を再生するときはおかしくなるが、別の動画に移動(再生用オブジェクトは削除する)すると、うまく再生される。

・現段階で考えられる原因

上記の結果より、swfobjectで生成した再生用オブジェクトを削除せずにページを移動し、そこで新しいものを呼び出したときに何らかの不具合的な処理となることが分かった。
ただし現在の実装状態では、ユーザが再生中にリロードしたときにはどうしようもない。そのイベントをjavascriptがチェックできるかどうか? ページ移動の前にダイアログなどを表示して確認させることができるようなので、その処理でリロードの前にjavascriptへの呼び出しがあるかを調べる。ページ移動前にはwindow.onbeforeunload , onunloadという呼び出しがあるようだ。しかし、それらはoperaでは使えないらしい・・。まあ、それで解決できるのなら、swfobject内部でもイベントを拾ってちゃんとやってくれてると思うのだが・・
 ムービーを開いた後に5秒以内にonYouTubePlayerReadyがよばれていなかったらswffitでサイズをリサイズして描画イベントを発生させるという変な処理をそのままに残しておこう。



最新の画像もっと見る