HTML5 视频背景颜色与网站背景颜色不匹配 -- 在某些浏览器中,有时
HTML5 video background color not matching background color of website -- in some browsers, sometimes
我有一个客户想要 "seamlessly" 放在网站上的视频。视频的 HEX 背景颜色与网站的 HEX 背景颜色相匹配,并在某些浏览器、某些版本、某些时间呈现这种颜色?
最奇怪的是 Chrome 以不同方式呈现视频背景,直到您打开颜色选择器。然后他们突然匹配。需要明确的是,它只会在我打开颜色选择器而不是调试器后修复它(阅读:这不是重绘问题)。
当我第一次导航到该站点时,Firefox 呈现不同,但如果我按下 cmd+r,它就会变得完美无缝。
看看屏幕截图 - 他们说的比我能说的还要多。
我正在说服客户将视频更改为白色背景,因为这肯定会 "fix",但我非常好奇这是怎么回事/为什么会这样。
各位大侠有什么见解吗?
代码笔: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>
检查此工作 demo。
将视频容器的背景颜色定义为#e1dcd8;
或将您现有的 css 替换为以下内容:
body, html {
height: 100%;
margin: 0;
padding: 0;
}
.background {
background-color: #e1dcd8;
width: 100%;
height: 100%;
}
.video-container{
background: #e1dcd8;
}
video {
margin-left: 5%;
margin-top: 5%;
}
这似乎是浏览器呈现视频的基础,而不是简单的 CSS/HTML 修复。您的问题听起来类似于 this question。我打赌答案在于渲染引擎和色彩空间差异的某种组合,这可能意味着没有跨浏览器修复它的好方法。
在 firefox 上,您可以尝试调整颜色管理设置,看看是否会改变行为。这不能解决问题,但可以帮助解释问题。在 URL/search 栏中,输入 "about:config"。它应该带你到一个选项页面。页面中将出现另一个搜索栏,输入 "gfx.color_management.mode"。该选项可以取值 0、1、2。尝试将它们切换并重新加载页面(可能需要重新启动 firefox)以查看是否可以获得一致的差异。如果一开始就没有管理颜色,可能不会有任何区别。
同样,您可以尝试在 chrome 中禁用硬件加速视频解码。在chromeURL/search栏中输入"chrome://flags",然后找到标志"Disable hardware-accelerated video decode"。更改任何值,重新启动 chrome,然后再次检查颜色。
这些都不是我意识到的解决方案,这可能更适合作为评论,但我还没有代表。
导出 sRGB
或 Adobe RGB
中的视频和图像应该可以解决此问题。我们有一个颜色配置文件 HD (1-1-1)
的视频,这导致视频背景在 Safari 中比在 Chrome 中稍微亮一些。 已在 macOS 上测试
该问题不仅取决于浏览器,还取决于渲染。一旦浏览器使用硬件加速渲染视频,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
这是我解决这个问题的方法:
我已经在智能手机、Edge、Firefox 和 Internet Explorer 11 上使用 Chrome、Chrome 对其进行了测试。 编辑:测试是从 2017 年开始的,但正如评论中提到的那样
,它不再适用于 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 这样的浏览器,它们有时已经触发了 canplay
事件,尽管 [= canvas.
函数的15=]
如果 canplay
或 play
事件在 canvas 可以获取像素之前被触发,函数 isColorInRange
可以防止剧烈的背景变化。
重要的是,在视频元素之前定义函数。
如果您加载文档末尾的 javascript(由于页面加载性能而经常建议这样做),那么该方法将不起作用。
我觉得这里的正确解决方案是使用绿屏拍摄(您可能已经这样做了)并使用
- 透明 webm 视频或
- 使用 javascript canvas
将绿色像素替换为透明像素
可以在此处找到透明视频的示例:
https://jakearchibald.com/scratch/alphavid/
如果您的背景是纯黑色或纯白色,您只需稍微增加 css 中的对比度即可完全解决问题:
filter: contrast(101%);
来自 Jack 的原创想法。
导出第二个视频,但仅限于主视频的背景颜色。所以现在你有了你的原始视频,以及第二个长度为 1 秒且只有纯色的视频。
该视频标签应具有以下内容 css:
#bg-video {
position: fixed;
width: 100vw;
z-index: -1;
}
并且视频标签可以位于文档的顶部。
<body>
<video id="bg-video" src="assets/bg.mp4" muted></video>
<div>your main site html here</div>
</body>
由于两个视频的导出方式相同,因此颜色在多个浏览器 and/or 操作系统上也应该呈现相同。
*请注意,您的 'background video' 应该或多或少是 square/rectangle,这样当它缩放时,它将覆盖浏览器的宽度和高度。
我有一个客户想要 "seamlessly" 放在网站上的视频。视频的 HEX 背景颜色与网站的 HEX 背景颜色相匹配,并在某些浏览器、某些版本、某些时间呈现这种颜色?
最奇怪的是 Chrome 以不同方式呈现视频背景,直到您打开颜色选择器。然后他们突然匹配。需要明确的是,它只会在我打开颜色选择器而不是调试器后修复它(阅读:这不是重绘问题)。
当我第一次导航到该站点时,Firefox 呈现不同,但如果我按下 cmd+r,它就会变得完美无缝。
看看屏幕截图 - 他们说的比我能说的还要多。
我正在说服客户将视频更改为白色背景,因为这肯定会 "fix",但我非常好奇这是怎么回事/为什么会这样。
各位大侠有什么见解吗?
代码笔: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>
检查此工作 demo。
将视频容器的背景颜色定义为#e1dcd8;
或将您现有的 css 替换为以下内容:
body, html {
height: 100%;
margin: 0;
padding: 0;
}
.background {
background-color: #e1dcd8;
width: 100%;
height: 100%;
}
.video-container{
background: #e1dcd8;
}
video {
margin-left: 5%;
margin-top: 5%;
}
这似乎是浏览器呈现视频的基础,而不是简单的 CSS/HTML 修复。您的问题听起来类似于 this question。我打赌答案在于渲染引擎和色彩空间差异的某种组合,这可能意味着没有跨浏览器修复它的好方法。
在 firefox 上,您可以尝试调整颜色管理设置,看看是否会改变行为。这不能解决问题,但可以帮助解释问题。在 URL/search 栏中,输入 "about:config"。它应该带你到一个选项页面。页面中将出现另一个搜索栏,输入 "gfx.color_management.mode"。该选项可以取值 0、1、2。尝试将它们切换并重新加载页面(可能需要重新启动 firefox)以查看是否可以获得一致的差异。如果一开始就没有管理颜色,可能不会有任何区别。
同样,您可以尝试在 chrome 中禁用硬件加速视频解码。在chromeURL/search栏中输入"chrome://flags",然后找到标志"Disable hardware-accelerated video decode"。更改任何值,重新启动 chrome,然后再次检查颜色。
这些都不是我意识到的解决方案,这可能更适合作为评论,但我还没有代表。
导出 sRGB
或 Adobe RGB
中的视频和图像应该可以解决此问题。我们有一个颜色配置文件 HD (1-1-1)
的视频,这导致视频背景在 Safari 中比在 Chrome 中稍微亮一些。 已在 macOS 上测试
该问题不仅取决于浏览器,还取决于渲染。一旦浏览器使用硬件加速渲染视频,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
这是我解决这个问题的方法:
我已经在智能手机、Edge、Firefox 和 Internet Explorer 11 上使用 Chrome、Chrome 对其进行了测试。 编辑:测试是从 2017 年开始的,但正如评论中提到的那样
一旦视频准备好播放或回放,请检查视频的第一个像素并相应地更改周围容器的背景颜色。无论浏览器设置和渲染配置如何,这都会起作用。
这是代码:
<!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 这样的浏览器,它们有时已经触发了 canplay
事件,尽管 [= canvas.
如果 canplay
或 play
事件在 canvas 可以获取像素之前被触发,函数 isColorInRange
可以防止剧烈的背景变化。
重要的是,在视频元素之前定义函数。 如果您加载文档末尾的 javascript(由于页面加载性能而经常建议这样做),那么该方法将不起作用。
我觉得这里的正确解决方案是使用绿屏拍摄(您可能已经这样做了)并使用
- 透明 webm 视频或
- 使用 javascript canvas 将绿色像素替换为透明像素
可以在此处找到透明视频的示例: https://jakearchibald.com/scratch/alphavid/
如果您的背景是纯黑色或纯白色,您只需稍微增加 css 中的对比度即可完全解决问题:
filter: contrast(101%);
来自 Jack 的原创想法。
导出第二个视频,但仅限于主视频的背景颜色。所以现在你有了你的原始视频,以及第二个长度为 1 秒且只有纯色的视频。
该视频标签应具有以下内容 css:
#bg-video {
position: fixed;
width: 100vw;
z-index: -1;
}
并且视频标签可以位于文档的顶部。
<body>
<video id="bg-video" src="assets/bg.mp4" muted></video>
<div>your main site html here</div>
</body>
由于两个视频的导出方式相同,因此颜色在多个浏览器 and/or 操作系统上也应该呈现相同。
*请注意,您的 'background video' 应该或多或少是 square/rectangle,这样当它缩放时,它将覆盖浏览器的宽度和高度。