chrome 扩展内容脚本中的 youtube 视频
youtube video in chrome extension content script
我正在尝试借助 chrome 扩展内容脚本将带有 iframe API 的 YouTube 视频插入现有页面。但是我无法让 onYouTubeIframeAPIReady
触发。
manifest.json
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*", "file://*/*", "*://*/*"],
"js": ["content-script.js"]
}
],
内容-script.js
const appEl = document.createElement('div');
appEl.id = 'my-app';
appEl.innerHTML = `<div id="youtube-iframe"></div>`;
const bodyEl = document.querySelector('body');
bodyEl.insertBefore(appEl, bodyEl.firstChild);
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
document.querySelector('body').appendChild(tag);
window.onYouTubeIframeAPIReady = () => {
this.player = new YT.Player('youtube-iframe', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
}
});
}
function onPlayerReady(event) {
console.log('player ready');
event.target.playVideo();
};
在 chrome-app 中,我能够使其与 webview
一起使用,但这似乎在扩展中不可用。
我解决了这个问题,这里是解决方案。
我尝试了代码注入方法的所有变体,但问题是 YouTube API 脚本定义了一个匿名函数,该函数需要 window 作为输入参数。因此,即使遵循了不加载外部脚本的建议(chrome 网上商店可能会删除您的扩展程序)并且拥有一个包含不同内容的本地文件,这意味着我无法触发 onYouTubeIframeAPIReady
通过 YouTube API 脚本。只有将脚本粘贴到我定义 onYouTubeIframeAPIReady
的同一个文件后,我才能看到视频。然而,为了更好地组织代码,使其与 ES6 导入一起工作(通过 Webpack),我执行了以下步骤。
将 YouTube API 脚本 (https://www.youtube.com/iframe_api see https://developers.google.com/youtube/iframe_api_reference) 下载到本地文件。
通过将脚本从
更改为采用脚本作为模块工作
(function(){var g,k=this;function l(a){a=a.split(".");
...
Ub=l("onYouTubePlayerAPIReady");Ub&&Ub();})();
到
export default function(){var g,k=window;function l(a){a=a.split(".")
...
Ub=l("onYouTubePlayerAPIReady");Ub&&Ub();}
这将匿名函数调用更改为以 ES6 模块样式导出的函数,并且匿名函数中的 this
对象与 window
交换。我将其保存在文件中 youtube-iframe-api.js
现在我可以通过以下代码在另一个模块中使用 YouTube API
import youtubeApi from './youtube-iframe-api';
function onPlayerReady(event) {
event.target.playVideo();
},
window.onYouTubeIframeAPIReady = () => {
this.player = new YT.Player('youtube-iframe', {
height: '100',
width: '100',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
}
});
}
youtubeApi();
我正在尝试借助 chrome 扩展内容脚本将带有 iframe API 的 YouTube 视频插入现有页面。但是我无法让 onYouTubeIframeAPIReady
触发。
manifest.json
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*", "file://*/*", "*://*/*"],
"js": ["content-script.js"]
}
],
内容-script.js
const appEl = document.createElement('div');
appEl.id = 'my-app';
appEl.innerHTML = `<div id="youtube-iframe"></div>`;
const bodyEl = document.querySelector('body');
bodyEl.insertBefore(appEl, bodyEl.firstChild);
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
document.querySelector('body').appendChild(tag);
window.onYouTubeIframeAPIReady = () => {
this.player = new YT.Player('youtube-iframe', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
}
});
}
function onPlayerReady(event) {
console.log('player ready');
event.target.playVideo();
};
在 chrome-app 中,我能够使其与 webview
一起使用,但这似乎在扩展中不可用。
我解决了这个问题,这里是解决方案。
我尝试了代码注入方法的所有变体,但问题是 YouTube API 脚本定义了一个匿名函数,该函数需要 window 作为输入参数。因此,即使遵循了不加载外部脚本的建议(chrome 网上商店可能会删除您的扩展程序)并且拥有一个包含不同内容的本地文件,这意味着我无法触发 onYouTubeIframeAPIReady
通过 YouTube API 脚本。只有将脚本粘贴到我定义 onYouTubeIframeAPIReady
的同一个文件后,我才能看到视频。然而,为了更好地组织代码,使其与 ES6 导入一起工作(通过 Webpack),我执行了以下步骤。
将 YouTube API 脚本 (https://www.youtube.com/iframe_api see https://developers.google.com/youtube/iframe_api_reference) 下载到本地文件。
通过将脚本从
更改为采用脚本作为模块工作(function(){var g,k=this;function l(a){a=a.split(".");
...
Ub=l("onYouTubePlayerAPIReady");Ub&&Ub();})();
到
export default function(){var g,k=window;function l(a){a=a.split(".")
...
Ub=l("onYouTubePlayerAPIReady");Ub&&Ub();}
这将匿名函数调用更改为以 ES6 模块样式导出的函数,并且匿名函数中的 this
对象与 window
交换。我将其保存在文件中 youtube-iframe-api.js
现在我可以通过以下代码在另一个模块中使用 YouTube API
import youtubeApi from './youtube-iframe-api';
function onPlayerReady(event) {
event.target.playVideo();
},
window.onYouTubeIframeAPIReady = () => {
this.player = new YT.Player('youtube-iframe', {
height: '100',
width: '100',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
}
});
}
youtubeApi();