3

我想编写一个网络扩展程序,能够检测用户访问的任何youtube 视频的播放状态。我查看了 youtube API,但似乎我只能访问我自己嵌入的 youtube 视频。但是在这种情况下,我没有嵌入它们。

有没有办法做到这一点?

4

2 回答 2

1

自从有人问到这个问题后,我就对这个问题很感兴趣,今晚在我们当地的 GDG 上,我们举办了一个 Chrome 扩展程序黑客马拉松,在那里我进行了一些实验进行测试。这是我发现的。

A) 扩展沙箱真的很难;我尝试过的任何东西都无法获取编码到页面中的javascript(如果存在的话)。

B)在某些情况下效果很好的一种解决方案是使用内容脚本进行代码注入,并在现有的 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)一个不太有用的解决方法是操纵 DOM 并删除嵌入的视频,通过更直接的绑定和设置的侦听器自己重新嵌入(正如另一个答案所建议的那样)。但是,如果原始页面一直在使用 API 本身,则此类操作会破坏其侦听器,因此如果您看到的视频是基于 API 的 Web 应用程序的一部分,则可能会产生意想不到的后果。

希望这是有用的信息。

于 2012-12-13T07:12:35.737 回答
0

好吧,所以自己嵌入视频!您可以使用内容脚本在加载之前修改 youtube 框架,甚至更好...我不确定 youtube api 是如何工作的,但您可以使用Chrome 的 Web 请求 API拦截视频请求并更改请求数据以获取你想要什么。

如果您提供更多信息,我可以为您提供有关如何执行此操作的更多详细信息...

祝你好运!

于 2012-12-10T17:38:55.490 回答