我想编写一个网络扩展程序,可以检测用户访问的任何 YouTube视频的播放状态。我查看了youtube API,但似乎我只能访问自己嵌入的YouTube视频。但是在这种情况下,我没有嵌入它们。
有没有办法做到这一点?
答案 0 :(得分: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应用程序的一部分,则可能会产生意想不到的后果。希望这是有用的信息。
答案 1 :(得分:0)
好吧,所以自己嵌入视频吧! 你可以使用内容脚本在加载之前修改youtube框架,甚至更好...... 我不确定youtube api是如何工作的,但您可以使用Chrome's Web Request API拦截视频请求并更改请求数据以获得您想要的内容。
如果您提供更多信息,我是否可以为您提供更多详细信息...
祝你好运!