CSS 背景图像转换使视频标记缓冲区
CSS background-image transition makes video tag buffer
我有一个视频标签,我想连续播放,而用户可以同时在网站上做一些事情。但是我发现,如果视频开始缓冲的背景图像之间的背景转换。我在下面的代码片段中有一个 运行nable 示例。
注意: 如果片段正常 运行,缓冲似乎不会发生,但如果将片段放在 'full page' 中,缓冲就会发生。
function changeBackground() {
const randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
const element = document.getElementById('background');
const currentOpacity = element.style.opacity;
const currentBackground = element.style.backgroundImage;
switch (currentBackground) {
case 'url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png")': {
element.style.backgroundImage = 'url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")';
break;
}
case 'url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")': {
element.style.backgroundImage = 'url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png")';
break;
}
default: {
break;
}
}
}
const element = document.getElementById('background');
element.style.backgroundImage = 'url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png")'
#background {
display: flex;
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
transition: background-image 3s ease-in-out;
}
#button {
display: flex;
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
display: flex;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button' onClick="changeBackground()">Click me to change the background!</div>
<video
id='video'
autoplay
muted
loop
controls
src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"/>
</div>
可能是什么原因造成的?有什么方法可以防止视频缓冲,同时仍然有背景图像转换?
编辑:补充一点可能很重要,我在 MacOS 上 Chrome。
编辑 2:从我收集到的回复来看,并不是每个人都能重现这个问题,所以我找了一台老式的 windows PC 试了一下。发现背景转换非常缓慢且滞后,但视频继续播放没有问题。它也适用于 MacOS 上的 safari,因此这似乎是一个 Chrome 仅限 MacOS 的问题。
我无法重现该问题,因此这可能是您的 ISP 和延迟问题(我在 145 Mbps 时没有遇到该问题)。查看您的代码,该开关效率不高。下面的演示使用了一个数组(也添加了另一个图像)。顺便说一句,为包含子元素的元素添加 flex,否则它毫无意义。
document.getElementById('button').onclick = changeBackground;
let i = 0;
function changeBackground(e) {
const images = ["https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png", "https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg", "https://media.istockphoto.com/vectors/circuit-board-seamless-pattern-vector-background-microchip-technology-vector-id1018272944"];
const background = document.getElementById('background');
i++;
if (i >= images.length) {
i = 0;
}
background.style.backgroundImage = `url(${images[i]})`;
return false;
}
#background {
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
background-image: url(https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png);
transition: background-image 3s ease-in-out;
background-repeat: repeat-x;
}
#button {
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button'>Click me to change the background!</div>
<video id='video' autoplay muted loop controls src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"></video>
</div>
这个问题很有意思。
我认为缓冲区可能是由于
- 这一行Math.floor(Math.random()*16777215).toString(16);
- 还有关于视频分辨率及其大小调整的程度
- 也可能是一些不必要的代码,如果有的话。
尝试在 Chrome 上启用/禁用 hardware-acceleration。
我不得不承认我不完全确定这里发生了什么......鉴于这不是 100% 的重现案例,也很难确定任何解决方法是否真的有效......
但这里有一些评论和想法。
这似乎只发生在 .mp4 文件中。我可以使用其他 .mp4 视频进行复制,但不能使用任何 .webm 文件进行复制。
所以你可能想尝试的一件事是在 webm 中重新编码你的视频,可能是 Chrome 的 mp4 解码器有一些问题。
似乎 CSS 动画 不会导致此问题。所以你可以将你的转换代码重写成一个 CSS 动画,主要问题是你无法在中间停止它(但似乎 background-transitions 在这方面很糟糕)。
function changeBackground() {
const element = document.getElementById('background');
if(element.classList.contains('apple')) {
element.classList.remove('apple');
element.classList.add('so');
}
else {
element.classList.add('apple');
element.classList.remove('so');
}
}
#background {
display: flex;
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
background-image: url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png");
}
#background.apple {
animation: apple-to-SO 3s ease-in-out forwards;
}
#background.so {
animation: SO-to-apple 3s ease-in-out forwards;
}
@keyframes apple-to-SO {
from {
background-image: url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")
}
to {
background-image: url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png");
}
}
@keyframes SO-to-apple {
from {
background-image: url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png");
}
to {
background-image: url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")
}
}
#button {
display: flex;
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
display: flex;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button' onClick="changeBackground()">Click me to change the background!</div>
<video
id='video'
autoplay
muted
loop
controls
src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"/>
</div>
现在如果喜欢js控制,好像Web-Animations也不受影响
let current = 1;
const urls = [
"https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png",
"https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg"
];
function changeBackground() {
const element = document.getElementById('background');
element.animate({
backgroundImage: ['url(' + urls[current] + ')', 'url(' + urls[+(!current)] + ')']
}
, {
duration: 3000,
iterations: 1,
fill: 'both'
}
);
current = (current + 1) % 2;
}
#background {
display: flex;
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
background-image: url(https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png);
}
#button {
display: flex;
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
display: flex;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button' onClick="changeBackground()">Click me to change the background!</div>
<video
id='video'
autoplay
muted
loop
controls
src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"/>
</div>
我有一个视频标签,我想连续播放,而用户可以同时在网站上做一些事情。但是我发现,如果视频开始缓冲的背景图像之间的背景转换。我在下面的代码片段中有一个 运行nable 示例。
注意: 如果片段正常 运行,缓冲似乎不会发生,但如果将片段放在 'full page' 中,缓冲就会发生。
function changeBackground() {
const randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
const element = document.getElementById('background');
const currentOpacity = element.style.opacity;
const currentBackground = element.style.backgroundImage;
switch (currentBackground) {
case 'url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png")': {
element.style.backgroundImage = 'url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")';
break;
}
case 'url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")': {
element.style.backgroundImage = 'url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png")';
break;
}
default: {
break;
}
}
}
const element = document.getElementById('background');
element.style.backgroundImage = 'url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png")'
#background {
display: flex;
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
transition: background-image 3s ease-in-out;
}
#button {
display: flex;
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
display: flex;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button' onClick="changeBackground()">Click me to change the background!</div>
<video
id='video'
autoplay
muted
loop
controls
src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"/>
</div>
可能是什么原因造成的?有什么方法可以防止视频缓冲,同时仍然有背景图像转换?
编辑:补充一点可能很重要,我在 MacOS 上 Chrome。
编辑 2:从我收集到的回复来看,并不是每个人都能重现这个问题,所以我找了一台老式的 windows PC 试了一下。发现背景转换非常缓慢且滞后,但视频继续播放没有问题。它也适用于 MacOS 上的 safari,因此这似乎是一个 Chrome 仅限 MacOS 的问题。
我无法重现该问题,因此这可能是您的 ISP 和延迟问题(我在 145 Mbps 时没有遇到该问题)。查看您的代码,该开关效率不高。下面的演示使用了一个数组(也添加了另一个图像)。顺便说一句,为包含子元素的元素添加 flex,否则它毫无意义。
document.getElementById('button').onclick = changeBackground;
let i = 0;
function changeBackground(e) {
const images = ["https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png", "https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg", "https://media.istockphoto.com/vectors/circuit-board-seamless-pattern-vector-background-microchip-technology-vector-id1018272944"];
const background = document.getElementById('background');
i++;
if (i >= images.length) {
i = 0;
}
background.style.backgroundImage = `url(${images[i]})`;
return false;
}
#background {
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
background-image: url(https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png);
transition: background-image 3s ease-in-out;
background-repeat: repeat-x;
}
#button {
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button'>Click me to change the background!</div>
<video id='video' autoplay muted loop controls src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"></video>
</div>
这个问题很有意思。
我认为缓冲区可能是由于
- 这一行Math.floor(Math.random()*16777215).toString(16);
- 还有关于视频分辨率及其大小调整的程度
- 也可能是一些不必要的代码,如果有的话。
尝试在 Chrome 上启用/禁用 hardware-acceleration。
我不得不承认我不完全确定这里发生了什么......鉴于这不是 100% 的重现案例,也很难确定任何解决方法是否真的有效......
但这里有一些评论和想法。
这似乎只发生在 .mp4 文件中。我可以使用其他 .mp4 视频进行复制,但不能使用任何 .webm 文件进行复制。
所以你可能想尝试的一件事是在 webm 中重新编码你的视频,可能是 Chrome 的 mp4 解码器有一些问题。
似乎 CSS 动画 不会导致此问题。所以你可以将你的转换代码重写成一个 CSS 动画,主要问题是你无法在中间停止它(但似乎 background-transitions 在这方面很糟糕)。
function changeBackground() {
const element = document.getElementById('background');
if(element.classList.contains('apple')) {
element.classList.remove('apple');
element.classList.add('so');
}
else {
element.classList.add('apple');
element.classList.remove('so');
}
}
#background {
display: flex;
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
background-image: url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png");
}
#background.apple {
animation: apple-to-SO 3s ease-in-out forwards;
}
#background.so {
animation: SO-to-apple 3s ease-in-out forwards;
}
@keyframes apple-to-SO {
from {
background-image: url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")
}
to {
background-image: url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png");
}
}
@keyframes SO-to-apple {
from {
background-image: url("https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png");
}
to {
background-image: url("https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg")
}
}
#button {
display: flex;
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
display: flex;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button' onClick="changeBackground()">Click me to change the background!</div>
<video
id='video'
autoplay
muted
loop
controls
src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"/>
</div>
现在如果喜欢js控制,好像Web-Animations也不受影响
let current = 1;
const urls = [
"https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png",
"https://i5.walmartimages.ca/images/Large/428/5_r/6000195494285_R.jpg"
];
function changeBackground() {
const element = document.getElementById('background');
element.animate({
backgroundImage: ['url(' + urls[current] + ')', 'url(' + urls[+(!current)] + ')']
}
, {
duration: 3000,
iterations: 1,
fill: 'both'
}
);
current = (current + 1) % 2;
}
#background {
display: flex;
position: absolute;
width: 100%;
height: 100%;
z-index: -10;
background-size: contain;
background-image: url(https://cdn.freebiesupply.com/logos/large/2x/Whosebug-com-logo-png-transparent.png);
}
#button {
display: flex;
width: 200px;
height: 100px;
background-color: orange;
text-align: center;
}
#video {
display: flex;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 350px;
}
<div id='root' style='width: 100%; height: 500px'>
<div id='background'></div>
<div id='button' onClick="changeBackground()">Click me to change the background!</div>
<video
id='video'
autoplay
muted
loop
controls
src="https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4"/>
</div>