3

ユーザーがアクセスしたYouTube ビデオの再生ステータスを検出できる Web 拡張機能を作成したいと考えています。YouTube API を調べましたが、自分で埋め込んだ YouTube 動画にしかアクセスできないようです。ただし、この状況では、それらを埋め込んでいません。

これを行う方法はありますか?

4

2 に答える 2

1

尋ねられて以来、私はこの質問に興味をそそられてきました.今夜、地元の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 アプリの一部である場合、意図しない結果が生じる可能性があります。

これが有用な情報であることを願っています。

于 2012-12-13T07:12:35.737 に答える
0

それでは、動画を自分で埋め込んでください。content-scripts を使用して、ロードする前に YouTube フレームを変更するか、さらに良い方法で... YouTube API がどのように機能するかはわかりませんが、おそらくChrome の Web Request APIでビデオ リクエストをインターセプトし、リクエスト データを変更して取得することができますあなたが欲しいもの。

詳しい方がいらっしゃいましたら、詳しい方法を教えていただけないでしょうか...

幸運を!

于 2012-12-10T17:38:55.490 に答える