首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么youtube ytplayer对象在youtube视频之间导航时不更新?

为什么youtube ytplayer对象在youtube视频之间导航时不更新?
EN

Stack Overflow用户
提问于 2019-02-09 21:06:57
回答 1查看 610关注 0票数 2

我正在开发一个铬扩展名,它使用contentscript.js文件中youtube页面中的ytplayer对象。在过去,ytplayer对象每次导航到一个新的youtube视频时都会更新。到目前为止,我已经看不到它的更新了。

如何复制

  1. 转到youtube的chrome视频页面(例如,https://www.youtube.com/watch?v=KUh2O8HylUM)
  2. 打开dev工具控制台
  3. 在控制台中键入“ytplayer.config.args”
  4. 捕获ytplayer.config.args对象
  5. 单击推荐列表中的另一个视频,导航到另一个youtube视频。
  6. 再次键入ytplayer.config.args
  7. 与之前捕获的ytplayer.config.args相比

您将看到ytplayer在导航到第二个视频后不会更新。我的扩展使用这个对象。问题是,在导航到另一个视频后,该对象已失效。当我在每次视频导航之后提取ytplayer对象时,我会显示错误的数据,因为ytplayer总是来自第一个视频。

问题。

  1. 有什么方法可以得到更新的ytplayer吗?
  2. 有办法让ytplayer重新加载吗?(我可以在js代码中添加一个location.reload(),它修复了这个问题,但它很麻烦,很差劲)
  3. 有没有其他方法可以从youtube视频页面中获取ytplayer.conf.args数据?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-10 06:41:49

Youtube是一个现代化的网站,它只使用来自服务器的部分数据来更新页面。这意味着只有一个完整的页面加载,在此期间,ytplayer是在内联<script>标记中构建的。这也意味着您的内容脚本只运行一次。

所提出的解决方案是通过在open中重写XHR page context方法来拦截站点的网络通信,以获得新的ytplayer对象。

manifest.json:

代码语言:javascript
复制
"content_scripts": [{
  "run_at": "document_start",
  "matches": ["https://www.youtube.com/*"],
  "js": ["content.js"]
}]

content.js:

代码语言:javascript
复制
const token = chrome.runtime.id + ':' + performance.now() + ':' + Math.random();

window.addEventListener(token, e => {
  console.log('gotPlayerArgs', e.detail);
  chrome.runtime.sendMessage({
    action: 'gotPlayerArgs',
    data: e.detail,
  });
});

const script = document.createElement('script');
script.textContent = '(' + (token => {
  const origOpen = XMLHttpRequest.prototype.open;
  const dispatch = data => window.dispatchEvent(new CustomEvent(token, {detail: data}));
  const onLoad = e => {
    const json = e.target.response;
    const player = (Array.isArray(json) && json.find(_ => _.player) || {}).player || {};
    dispatch(player.args);
  };
  // get the initial config
  try {
    dispatch(window.ytplayer.config.args);
  } catch (e) {}
  // intercept the subsequent config queries
  XMLHttpRequest.prototype.open = function (method, url) {
    if (url.startsWith('https://www.youtube.com/watch?')) {
      this.addEventListener('load', onLoad);
    }
    return origOpen.apply(this, arguments);
  };
}) + `)("${token}")`;
document.documentElement.appendChild(script);
script.remove();

还有一个警告仍然存在:(1)如果您的扩展被更新/重新加载或禁用/重新启用,而(2) youtube页面不是第一个导航,那么初始的config对象将是错误的。要解决这个问题,您可以将视频的id (从URL中提取)与配置(例如“loaderUrl”属性)中的id进行比较,如果它不匹配,只需通过get_video_info端点获得args,这很容易解析(由&拆分,然后使用decodeURIComponent):'https://www.youtube.com/get_video_info?video_id=' + id + '&hl=en_US&html5=1&el=embedded'

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54610750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档