何を作ったか?
以前、Youtubeの埋め込みコードに開始時間を設定する拡張を書いた。
YouTubeを途中再生できるように埋め込みコードを改変するChrome拡張をつくった - not good but great
Embed Screen Jump Code for YouTube™ - Chrome ウェブストア
それの技術的な解説を書こうと思う。
アプリの設計
拡張の作り方、用語の解説
構成や、拡張の作り方はこのページを参考にした。
2013-09-09
行程1
//background.js chrome.tabs.onUpdated.addListener(function (tabId,changeInfo,tab){ if(tab.url.indexOf("youtube.com/watch?v=") != -1){ chrome.pageAction.show(tabId); } });
Youtubeの視聴ページのURL(youtube.com/watch?v=)がURLに含まれるなら、アイコンをアドレスバーに表示する。
行程2
Content Scriptの実行タイミングを設定
・manifest.json
"content_scripts":[ { "matches":["http://www.youtube.com/watch?v=*"], "js":["js/jquery.js","js/contentscript.js"], "run_at":"document_end" } ],
"run_at"にいつ実行するのかを設定する。“document_start“、“document_end“、“document_idle“の値がある。
matchesはbackground.jsでurl指定しているので、もしかしたら要らないかもしれない。
Youtubeの動画オブジェクトを取得
方法がわからないかったので、Youtubeを使った拡張機能をダウンロードして、ソースを読んで参考にした。参考にした拡張は繰り返し再生の機能を持たせる拡張だった。
https://chrome.google.com/webstore/detail/auto-replay-for-youtube/kanbnempkjnhadplbfgdaagijdbdbjeb
//contentscript.js var ytobj = { startTime: 0, createHTML5Player: function(videoEle){ ytobj.videoEle = videoEle; return{ getCurrentTime: function(){ return videoEle.currentTime; } } }, getMoviePlayer:function(){ var p = $("#movie_player"); if(p.is(".html5-video-player")){ var _p = p.find("video")[0]; if(_p){ p = ytobj.createHTML5Player(_p); console.log(p.getCurrentTime()); } }else{ p = p[0]; } return p; } }; ytobj.player = ytobj.getMoviePlayer(); ytobj.startTime = ytobj.player.getCurrentTime();
jQueryでidを指定して、動画を囲っているdiv要素を取得する。そのあとvideoタグをfindで検索する。
疑問だったのはhtmlソースで「video」という文字列を検索しても見つからないこと。どうなっているんだろうかw
Youtubeのオブジェクトを取得して何が出来るかというのは、Youtube player APIのドキュメントを見るのが良い。
iframe 組み込みの YouTube Player API リファレンス | YouTube IFrame Player API | Google Developers
player.getCurrentTime():Number
動画の再生を開始してからの経過時間を秒数で返します。
現在の再生時間を得たいので、getCurrentTime()を使う。
行程3
Background Scriptに再生時間のデータを送る
//contentscript.js chrome.runtime.sendMessage({time: ytobj.startTime}, function(response){ console.log("message sent"); });
再生時間をオブジェクトの値に設定して、sendMessageの引数に設定する。
メッセージの送り方のドキュメントはこちら。
Message passing - Chrome Developers
行程4
Background Scriptでデータを受け取る
chrome.runtime.onMessage.addListener( function(request,sender,sendResponse){ parseItems = []; console.log(request); console.log(sender); console.log(sendResponse); startTime = request.time; url = sender.url; var res = "finish"; sendResponse(res); } );
メッセージを受け取ると、onMessageのイベントリスナが起動され、関数が実行される。
ここでは開始時間と送り主のURLを取得している。URLは後で、埋め込みコードを生成するときに必要なので取得した。
Popup.htmlにデータを渡す
・popup.html
<script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/popup.js"></script>
jsファイルは外部から読み込むようにする。htmlファイルに直接scriptを書くと、クロスドメイン?に引っかかり実行できない。クロスドメインわからん。
//popup.js var startTime = ~~chrome.extension.getBackgroundPage().startTime, url = chrome.extension.getBackgroundPage().url;
"chrome.extension.getBackgroundPage()"の後に変数名を書けば、backgroundが持っているデータを引き出せる。
あとはpopup.jsで受け取ったデータを処理して、埋め込みコードを生成してる。
改善したいところ
現在の時間の取得タイミング
今は最初にPageActionを押した時間しか抜き出せていない。だから少し再生して、もう一回押してもそのときの再生時間にならない。これをするやり方がわからない。
Youtubeの動画の下のメニューにある「共有」を押すと、URLに開始時間を加えることが出来る。それはリアルタイムで開始時間が変化している。それのように拡張の方も動いたらいいのになと思う。