HTML5 视频背景颜色与网站背景颜色不匹配——在某些浏览器中,有时

新手上路,请多包涵

我有一段视频,客户希望“无缝”地坐在网站上。视频的 HEX 背景颜色与网站的 HEX 背景颜色相匹配,并在某些浏览器、某些版本、某些时间呈现这种颜色?

最奇怪的是 Chrome 会以不同的方式呈现视频的背景,直到您打开颜色选择器。然后他们突然匹配。需要明确的是,它只会在我打开颜色选择器而不是调试器后修复它(阅读:这不是重绘问题)。

当我第一次导航到该站点时,Firefox 呈现不同,但如果我按下 cmd+r,它就会变得完美无缝。

看看屏幕截图 - 他们说的比我能用文字表达的还要多。

我正在说服客户将视频更改为白色背景,因为这肯定会“修复”它,但我非常好奇发生了什么/为什么会这样。

你们那里的巫师有什么见解吗?


代码笔: http ://codepen.io/anon/pen/zrJVpX

 <div class="background" style="background-color: #e1dcd8; width: 100%; height: 100%;">
<div class="video-container">
    <video id="video" poster="" width="90%" height="auto" preload="" controls style="margin-left: 5%; margin-top: 5%;">
      <source id="mp4" src="http://bigtomorrowdev.wpengine.com/wp-content/themes/bigtomorrow/images/videos/bt-process.mp4" type="video/mp4">
      <source id="webm" src="http://bigtomorrowdev.wpengine.com/wp-content/themes/bigtomorrow/images/videos/bt-process.webm" type="video/webm">
      <source id="ogg" src="http://bigtomorrowdev.wpengine.com/wp-content/themes/bigtomorrow/images/videos/bt-process.ogv" type="video/ogg">
      We're sorry. This video is unable to be played on your browser.
      </video>
    </div>
</div>

不同浏览器的截图。

原文由 tayvano 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 752
2 个回答

看起来它可能是浏览器如何呈现视频的基础,而不是简单的 CSS/HTML 修复。你的问题听起来与 这个问题 相似。我打赌答案在于渲染引擎和色彩空间差异的某种组合,这可能意味着没有跨浏览器修复它的好方法。

在 firefox 上,您可以尝试摆弄颜色管理设置,看看是否会改变行为。这不能解决问题,但可以帮助解释问题。在 URL/搜索栏中,输入“about:config”。它应该带你到一个选项页面。页面中将出现另一个搜索栏,输入“gfx.color_management.mode”。该选项可以取值 0、1、2。尝试将它们切换并重新加载页面(可能需要重新启动 firefox)以查看是否可以获得一致的差异。如果一开始就没有管理颜色,它可能不会有任何区别。

同样,您可以尝试在 chrome 中禁用硬件加速视频解码。在 chrome URL/搜索栏中输入“chrome://flags”,然后找到“禁用硬件加速视频解码”标志。更改任何值,重新启动 chrome,然后再次检查颜色。

这些都不是我意识到的解决方案,这可能更好地作为评论,但我还没有代表。

原文由 Jeremy Watson 发布,翻译遵循 CC BY-SA 3.0 许可协议

该问题不仅取决于浏览器,还取决于渲染。一旦浏览器使用硬件加速渲染视频,GPU 偏好就会影响颜色。

例如,如果您使用的是 Nvidia 显卡,则可以在 Nvidia 控制面板中更改颜色首选项。桌面显示器通常使用从 0 到 255 的完整 RGB 范围,但您也可以配置从 16 到 235 的有限 RGB 范围。有限范围通常由电视使用。

一方面,显卡驱动程序有时会将桌面显示器的颜色范围默认为有限的 RGB 范围。另一方面,用户可以自己更改此值。由于您无法影响用户的浏览器设置或显卡驱动程序设置,因此不同的用户总会有差异。

颜色如何受到影响:

 Full RGB range -> limited RGB range
#000000 becomes #161616
#081F3C becomes #172A43
#FFFFFF becomes #EBEBEB

这是我解决这个问题的方法:

我已经使用 Chrome、智能手机上的 Chrome、Edge、Firefox 和Internet Explorer 11对其进行了测试。 编辑:测试是从 2017 年开始的,但正如 Jomal Johny 在评论中提到的那样,它不再适用于 IE11。经过测试,我可以确认,它在 2021 年的 IE11 中不起作用。

一旦视频准备好播放或回放,检查视频的第一个像素并相应地更改周围容器的背景颜色。无论浏览器设置和呈现配置如何,这都将起作用。

这是代码:

 <!doctype html>

<html>
<head>
    <title>Video</title>
    <script>
        function isColorInRange(expectedColor, givenColor) {
            const THRESHOLD = 40;
            for (var i = 0; i < 3; i++) {
                if (((expectedColor[i] - THRESHOLD) > givenColor[i])
                 || ((expectedColor[i] + THRESHOLD) < givenColor[i])) {
                    return false;
                }
            }
            return true;
        }

        function setVideoBgColor(vid, nativeColor) {
            if (vid) {
                var vidBg = vid.parentElement;
                if (vidBg) {
                    // draw first pixel of video to a canvas
                    // then get pixel color from that canvas
                    var canvas = document.createElement("canvas");
                    canvas.width = 1;
                    canvas.height = 1;
                    var ctx = canvas.getContext("2d");
                    ctx.drawImage(vid, 0, 0, 1, 1);

                    var p = ctx.getImageData(0, 0, 1, 1).data;
                    //console.log("rgb(" + p[0] + "," + p[1] + "," + p[2] + ")");
                    if (isColorInRange(nativeColor, p)) {
                        vidBg.style.backgroundColor = "rgb(" + p[0] + "," + p[1] + "," + p[2] + ")";
                    }
                }
            }
        }

        function setVideoBgColorDelayed(vid, nativeColor) {
            setTimeout(setVideoBgColor, 100, vid, nativeColor);
        }
    </script>
    <style>
    body {
        margin: 0;
    }

    #my-video-bg {
        height: 100vh;
        display: flex;
        align-items: center;
        background-color: rgb(8,31,60);
    }

    #my-video {
        max-width: 100%;
        margin: 0 auto;
    }
    </style>
</head>
<body>
    <div id="my-video-bg">
        <video id="my-video" preload="metadata" onplay="setVideoBgColorDelayed(this,[8,31,60])" oncanplay="setVideoBgColorDelayed(this,[8,31,60])" controls>
            <source src="video.mp4" type="video/mp4">
        </video>
    </div>
</body>
</html>

play 事件和 setVideoBgColorDelayed 函数适用于像 Internet Explorer 这样的浏览器,它有时已经触发了 drawImage canplay 事件,尽管视频数据尚不可用 --- 画布的功能。

函数 isColorInRange 防止严重的背景变化,如果 canplayplay 事件在画布获得像素之前被触发。

重要的是,函数在视频元素之前定义。如果您在文档末尾加载 javascript(由于页面加载性能而经常建议这样做),那么该方法将不起作用。

原文由 feng 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题