检测任何网站上YouTube视频的播放状态

3
我想编写一个网络扩展程序,能够检测用户访问的任何YouTube视频的播放状态。我研究了YouTube API,但似乎只能访问我自己嵌入的YouTube视频。然而,在这种情况下,我没有嵌入它们。
有没有办法做到这一点?

@Sudarshan дёҚпјҢйӮЈз§Қж–№жі•еҸӘйҖӮз”ЁдәҺIFrameеөҢе…ҘпјҲзү№еҲ«жҳҜеёҰжңү&enablejsapi=1жҹҘиҜўеӯ—з¬ҰдёІеҸӮж•°зҡ„жғ…еҶөпјүгҖӮиҜҘж–№жі•дҫқиө–дәҺcontentWindow.postMessageпјҢдҪҶеҜ№дәҺеҶ…е®№и„ҡжң¬пјҢcontentWindowжңӘе®ҡд№үгҖӮ - Rob W
@RobW:哦,我的错,我删除了我的评论。 - Sudarshan
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,则此方法无效;当我尝试使用类似的解决方案时,它是一个或元素,并且虽然我可以很好地检测到它,但我无法设置侦听器来捕获事件。我可能忽略了某些内容,或者事件被不同地触发,因此我无法获得所需的绑定。

D)一种不太有用的解决方法是操作DOM并删除嵌入式视频,然后重新嵌入自己的视频,并设置更直接的绑定和侦听器(正如另一个答案建议的那样)。但是,如果原始页面本身正在使用API,则此操作将破坏其侦听器,因此如果您看到的视频是基于API的Web应用程序的一部分,则可能会产生意想不到的后果。

希望这些信息对您有用。


0

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

如果您提供更多信息,我可以为您提供更多详细信息...

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接