Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在youtube视频之间导航时,为什么youtube播放器对象不更新?_Javascript_Google Chrome Extension_Youtube_Ytplayer - Fatal编程技术网

Javascript 在youtube视频之间导航时,为什么youtube播放器对象不更新?

Javascript 在youtube视频之间导航时,为什么youtube播放器对象不更新?,javascript,google-chrome-extension,youtube,ytplayer,Javascript,Google Chrome Extension,Youtube,Ytplayer,我正在开发一个chrome扩展,它在我的contentscript.js文件中使用youtube页面上的ytplayer对象。过去,每次导航到新的youtube视频时,ytplayer对象都会更新。到目前为止,我看不到任何更新 如何复制 转到chrome中的youtube视频页面(例如) 打开开发工具控制台 在控制台中键入“ytplayer.config.args” 捕获ytplayer.config.args对象 通过单击推荐列表中的其他视频导航到其他youtube视频 再次输入ytplaye

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

如何复制

  • 转到chrome中的youtube视频页面(例如)
  • 打开开发工具控制台
  • 在控制台中键入“ytplayer.config.args”
  • 捕获ytplayer.config.args对象
  • 通过单击推荐列表中的其他视频导航到其他youtube视频
  • 再次输入ytplayer.config.args
  • 与之前捕获的ytplayer.config.args进行比较
  • 您将看到,在导航到第二个视频后,播放器不会更新。我的扩展使用这个对象。问题是对象在导航到另一个视频后已过时。每次视频导航后拉动ytplayer对象时,都会显示错误的数据,因为ytplayer始终来自第一个视频

    问题

  • 有没有办法得到最新的播放器

  • 有没有办法让玩家重新加载?(我可以在我的js代码中添加一个location.reload(),它修复了这个问题,但它既粗糙又蹩脚)

  • 有没有其他方法可以从chrome中的youtube视频页面获取ytplayer.conf.args数据


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

    建议的解决方案是通过覆盖中的XHR
    open
    方法来拦截站点的网络通信,以获取新的ytplayer对象

    manifest.json:

    "content_scripts": [{
      "run_at": "document_start",
      "matches": ["https://www.youtube.com/*"],
      "js": ["content.js"]
    }]
    
    content.js:

    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页面不是第一个导航,那么初始配置对象将是错误的。要解决此问题,您可以将视频的id(从URL中提取)与配置中的id(例如,“loaderUrl”属性)进行比较,如果不匹配,只需通过get_video_info端点获取参数,该端点易于解析(按
    &
    拆分,然后按
    =
    拆分,然后使用decodeURIComponent):
    'https://www.youtube.com/get_video_info?video_id=“+id+”&hl=en_-US&html5=1&el=embedded'

    感谢您的支持!。到目前为止,我一直在控制台中获取
    gotPlayerArgs null
    。不过我会继续玩它。我通过更改这一行
    constplayer=Array.isArray(json)和&json.find(=>.player)|{}
    to
    constplayer=JSON.parse(JSON)[2]。player
    感谢您的调试。我在答案中添加了一个不同的修正,因为我不想依赖硬编码索引。