【问题标题】:How do I prevent the browser from preloading the <video> tag?如何防止浏览器预加载 <video> 标签?
【发布时间】:2016-06-19 07:20:17
【问题描述】:

我使用 JavaScript 为 Chrome 编写了一个用户脚本扩展,以防止视频和音频标签在页面加载时自动下载

这是代码:

var videoTags = document.getElementsByTagName("Video");
var i;
for(i=0; i<videoTags.length; i++)
{
    videoTags[i].setAttribute("preload", "none");
    videoTags[i].removeAttribute("autoplay");
}

var audioTags = document.getElementsByTagName("audio");
var i;
for(i=0; i<audioTags.length; i++)
{
    audioTags[i].setAttribute("preload", "none");
    audioTags[i].removeAttribute("autoplay");
}

这是 manifest.json 文件:

   {
      "content_scripts": [ {
      "exclude_globs": [  ],
      "exclude_matches": [  ],
      "include_globs": [ "*" ],
      "js": [ "script.js" ],
      "matches": [ "http://*/*", "https://*/*" ],
      "run_at": "document_start"
   } ],
      "converted_from_user_script": true,
      "description": "",
      "key": "an2xaeZJluPfnpmcsHPXI4aajQPL1cBm5C2kKjaQwXA=",
      "name": "test.user.js",
      "version": "1.0"
  }

问题是我的脚本会在一段时间后运行,然后浏览器 (Chrome) 会下载一部分视频/音频文件。

【问题讨论】:

  • 你不能用 JS 完全完成你的任务。浏览器可能会在 HMTL 解析为 DOM 后立即开始下载,而您只能修改生成的 DOM。如果是图像(将来也可能适用于视频),还有一个预加载解析器。

标签: javascript userscripts


【解决方案1】:

一个似乎可行的肮脏解决方案是使用用户脚本中的MutationObserver,一旦您确定它确实在文档启动时运行。

这个 TamperMonkey 脚本对我有用:

// ==UserScript==
// @name         Block videos preloading
// @include      *
// @run-at document-start
// ==/UserScript==

(function() {
  'use strict';
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      var nodes = mutation.addedNodes;
      for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].nodeName == "VIDEO") {
          nodes[i].setAttribute('preload', 'none');
          nodes[i].removeAttribute('autoplay');
        }
      }
    })
  });
  observer.observe(document.documentElement, {
    childList: true,
    subtree: true
  });

})();

如果您不希望脚本随后插入其他视频元素,您可能需要在 DOMContentLoaded 上致电 observer.disconnect()

【讨论】:

  • 请注意,问题的@AlexanderFarkas comment's确实是正确的,并且在对img元素发出请求后,突变事件将触发。也许将来也会用于视频和音频......
  • 非常感谢,它在 TamperMonkey 中工作,但我想在没有 TamperMonkey 扩展的情况下执行此操作,然后我将您的代码复制到我的 script.js 中而不是在那里!
【解决方案2】:

检查你认为的事情是否真的发生了。这应该是不可能的,因为"run_at": "document_start""run_at": "document_end" 都应该让你的代码在加载之前运行。

来自 developer.chrome.com 中的文档:

在“document_start”的情况下,文件是在任何来自 css 的文件之后注入的,但在构造任何其他 DOM 或运行任何其他脚本之前。

在“document_end”的情况下,文件在 DOM 完成后立即注入,但在图像和框架等子资源加载之前。

此外,由于您的代码在document_start 中运行,document.getElementsByTagName("Video") 应该会失败,因为甚至还没有构建 DOM。

尝试调试您的代码(从检查控制台中的错误开始)。另外,请在此处阅读有关 "run_at" 属性的更多信息:https://developer.chrome.com/extensions/content_scripts#run_at

【讨论】:

    【解决方案3】:

    尝试存储&lt;audio&gt;&lt;video&gt;src值,然后从&lt;audio&gt;&lt;video&gt;元素中删除src属性,用于设置preloadautoplay属性;使用DOMContentLoaded事件

    DOMContentLoaded 事件在初始 HTML 文档时触发 已完全加载并解析,无需等待 样式表、图像和子框架以完成加载。

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <script>
        var sources = [];
        document.addEventListener("DOMContentLoaded", function(event) {
          var media = document.querySelectorAll("audio, video");
          [].forEach.call(media, function(el) {
            if (el.src) {
              sources.push(el.src);
              el.removeAttribute("src");
            }
            var src = el.querySelectorAll("source");
            if (src.length) {
              [].forEach.call(src, function(source) {
                sources.push(source.src);
                source.removeAttribute("src");
              });
            };
          });
          console.log(sources);
        });
      </script>
    </head>
    <body style="height:270px">
      <video src="http://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm" controls></video>
     <audio controls>
        <source src="https://upload.wikimedia.org/wikipedia/commons/6/6e/Micronesia_National_Anthem.ogg" type="video/ogg" />
      </audio>
    </body>
    </html>

    编辑、更新

    你可以在用户脚本中测试它吗?

    manifest.json 中使用content_scripts"run_at": "document_start" 以铬、铬扩展名的形式返回预期结果;也就是说,&lt;audio&gt;&lt;video&gt;&lt;source&gt; 元素的src 属性应该从document 中删除。

    manifest.json

    {
      "manifest_version": 2,
      "name": "blockmedia",
      "description": "remove src from audio, video elements",
      "version": "1.0",
      "permissions": ["<all_urls>"],
      "content_scripts": [
        {
          "matches": ["<all_urls>"],
          "js": ["script.js"],
          "run_at": "document_start"
        }
      ]
    }
    

    script.js

    var sources = [];
    document.addEventListener("DOMContentLoaded", function(event) {
      var media = document.querySelectorAll("audio, video");
      [].forEach.call(media, function(el) {
        if (el.src) {
          sources.push(el.src);
          el.removeAttribute("src");
        }
        var src = el.querySelectorAll("source");
        if (src.length) {
          [].forEach.call(src, function(source) {
            sources.push(source.src);
            source.removeAttribute("src");
          });
        };
      });
     console.log(sources);
    });
    

    【讨论】:

    • 谢谢,但它只适用于文档脚本,不适用于用户脚本
      你能在用户脚本中测试它吗?我不能!
    • 无效!浏览器仍然会自动缓冲百分之几的视频
    • @user6350942 “不行!浏览器仍然会自动缓冲百分之几的视频” 不在这里。当加载扩展时,加载了相同的html,出现在本地的stacksn-ps,当查看Network选项卡时,似乎没有对资源提出请求。删除了src 属性的视频如何请求?
    • 您自己测试过吗?我认为我的脚本在页面加载之后执行并且视频源已经获取(在删除之前)并且浏览器开始缓冲它
    • @user6350942 “你自己测试过吗?” 是的。在 stacksn-ps 使用相同的 htmlmanifest.jsonscript.js 在更新的帖子中,作为铬扩展加载。在DevToolsNetwork 选项卡上,没有记录对与&lt;audio&gt;&lt;video&gt; 元素对应的媒体资源的网络请求。
    【解决方案4】:

    您正在与 Chrome 解析器预加载器作斗争。

    即使您在文档开始时注入内容脚本,使用 Mutation Observer 或上面建议的其他技术,您仍然无法在浏览器预加载器之前操作 HTML。

    阅读这篇对我有帮助的文章。

    https://andydavies.me/blog/2013/10/22/how-the-browser-pre-loader-makes-pages-load-faster/

    要实现您想要做的,您将需要使用 Chrome webRequest API 来阻止请求。

    https://developer.chrome.com/extensions/webRequest

    您需要根据媒体类型过滤请求,然后在标题中搜索要阻止的文件类型。

    【讨论】:

      猜你喜欢
      • 2016-03-31
      • 2012-05-21
      • 2020-05-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-11
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多