ユーザーがアクセスしたYouTube ビデオの再生ステータスを検出できる Web 拡張機能を作成したいと考えています。YouTube API を調べましたが、自分で埋め込んだ YouTube 動画にしかアクセスできないようです。ただし、この状況では、それらを埋め込んでいません。
これを行う方法はありますか?
ユーザーがアクセスしたYouTube ビデオの再生ステータスを検出できる Web 拡張機能を作成したいと考えています。YouTube API を調べましたが、自分で埋め込んだ YouTube 動画にしかアクセスできないようです。ただし、この状況では、それらを埋め込んでいません。
これを行う方法はありますか?
尋ねられて以来、私はこの質問に興味をそそられてきました.今夜、地元のGDGでChrome拡張ハッカソンがあり、いくつかの実験をテストしました. これが私が発見したものです。
A) 拡張サンドボックスは本当に大変です。私が試したものは、ページにコード化されたJavaScriptを取得できませんでした(存在する場合)。
B) 特定の状況下で非常にうまく機能する 1 つの解決策は、コンテンツ スクリプトを使用してコード インジェクションを行い、既存の iframe 埋め込みに独自のリスナーを設定することです。このようなものは動作します:
var regex = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w]*(?:['"][^<>]*>|<\/a>))[?=&+%\w]*/ig;
var node, nodes = document.evaluate("(//iframe/@src)",document,null,XPathResult.UNORDERED_NODE_ITERATOR_TYPE,null);
var hasvid=false,vids = [];
while (node=nodes.iterateNext()) { // uses regex to run through DOM, looking for embeds
if (regex.test(node.nodeValue)) {
hasvid=true;
vids.push(node.ownerElement);
}
}
// Now inject a script that sets up a YT.player object and bind it to our extension's functions
if (hasvid) {
playerlines=['function onYouTubePlayerAPIReady() {'];
for (i=0;i<vids.length; i++) {
playerlines.push('player = new YT.Player(\''+vids[i].id+'\', { events: {\'onStateChange\': onPlayerStateChange}});}');
}
callbacklines=['function onPlayerStateChange(event) {',
'if (event.data == YT.PlayerState.ENDED) { alert(\'video is over\'); }',
'else if (event.data == YT.PlayerState.PAUSED) { alert(\'player is paused\'); }',
'else if (event.data == YT.PlayerState.PLAYING) { alert(\'player is playing\'); } }'];
// notify the background page to actually do the injecting of the script
chrome.extension.sendRequest({}, function(response) {});
codelines=playerlines.concat(callbacklines);
var actualCode=codelines.join('\n');
var script = document.createElement('script');
script.textContent = actualCode;
var jsapi = document.createElement('script');
jsapi.src = "http://www.youtube.com/player_api";
(document.head||document.documentElement).appendChild(jsapi);
(document.head||document.documentElement).appendChild(script);
そのようなものを使用すると、アラートを実行するだけでなく、理論的にはすべてのイベントをバックグラウンド ページに送り返して、イベントの内容に基づいて必要なことを行うことができます。
C) 動画に iFrame が埋め込まれていない場合、これは役に立ちません。or 要素の場合に同様の解決策を採用しようとしましたが、問題なく検出できましたが、イベントをキャプチャするようにリスナーを設定できませんでした。何かを見落としていた可能性があります。または、イベントの発生方法が異なるため、必要なバインディングを取得できなかった可能性があります。
D)あまり役に立たない回避策の1つは、DOMを操作して埋め込みビデオを削除し、より直接的なバインディングとリスナーを設定して自分で再埋め込みすることです(別の回答が示唆しているように)。ただし、元のページが API 自体を使用していた場合、そのようなアクションはそのリスナーを破壊するため、表示されているビデオが API ベースの Web アプリの一部である場合、意図しない結果が生じる可能性があります。
これが有用な情報であることを願っています。
それでは、動画を自分で埋め込んでください。content-scripts を使用して、ロードする前に YouTube フレームを変更するか、さらに良い方法で... YouTube API がどのように機能するかはわかりませんが、おそらくChrome の Web Request APIでビデオ リクエストをインターセプトし、リクエスト データを変更して取得することができますあなたが欲しいもの。
詳しい方がいらっしゃいましたら、詳しい方法を教えていただけないでしょうか...
幸運を!