エントリの編集画面にyoutubeの動画を追加するボタンをつける、ってもんなんだけど、めちゃくちゃハマった。
やりたかったこと
- youtube動画のエントリへの埋め込み、再生や停止のタイミングでなんかする。
- エントリ編集画面でダイアログを開いて、いろいろ操作して埋め込む内容をプレビューしながら決定する
iframe地獄
ワードプレスの投稿内に、youtubeの埋め込み用iframeを直接書くのは全然難しくない。
しかし、このプラグインの場合、再生開始や終了のタイミングを取得したいという事情があり、
youtube player apiを動かさないといけなかった。
iframe 組み込みの YouTube Player API リファレンス - YouTube — Google Developers
また、ダイアログの中にiframeでプレビュー画面をつくって、その中で動画が再生できる必要があった。
youtube player api動かすには下みたいな感じでjavascriptのコードをエントリ内に入れる必要がある。
こうすれば、再生や停止のタイミングでonStateChangeが呼ばれる。
var player; function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: '390', width: '640', videoId: 'M7lc1UVf-VE', events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); }
上記はサンプル通りなんだけど、tinyMCEに作らせたダイアログの中にプレビュー画面を作ってこれを流し込んでも動かなかった。
2行目の'player'ってのはyoutube動画のiframeに置き換える要素のidなんだけど、これが見つからないようだ。
iframeが以下のように入れ子になっている状況なんだけど、3のプレビュー画面内でyoutube apiのjsを読み込んで実行しているのに、スコープが2になっているようだ。
1. エントリ編集画面
2. tinyMCEが開くダイアログ
3. プレビュー画面
上記のコードを実行するスコープを変えるとかいろいろやってみたが全然だめで、
最後に上記のYT.Playerというコンストラクタの第一引数に3にあるiframeの要素を直接渡すことができることを発見してなんとかうごかすことができた。
var player; var element = frames[0].document.getElementById("player"); function onYouTubeIframeAPIReady() { player = new YT.Player(element , { height: '390', width: '640', videoId: 'M7lc1UVf-VE', events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); }
frames[0].document.getElementById("player")とかやって下のiframeの要素を取得しているのがポイント。
onYouTubeIframeAPIReadyが一回しか発火しない
一度ダイアログを開いたら、プレビュー画面のiframeを何度も読み込み直すんだけど、最初の一回しかonYouTubeIframeAPIReadyが動かなかった。
これは適当なイベントを取ってこいつを直接たたいてやった。
他にもいろいろあったけど忘れた。