简体   繁体   English

CSS背景图像转换使视频标签缓冲

[英]CSS background-image transition makes video tag buffer

I have a video tag that I want to play continuously while a user can simultaneously do stuff on the site. 我有一个视频标签,我想连续播放,而用户可以同时在网站上做东西。 However I have found that if the background transitions between background images that the video starts buffering. 但是我发现,如果背景在视频开始缓冲的背景图像之间转换。 I have a runnable example in the snippet below. 我在下面的代码段中有一个可运行的示例。

Note: The buffering does not seem to occur if the snippet is run normally, but does occur if you put the snippet in '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/stackoverflow-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/stackoverflow-com-logo-png-transparent.png")'; break; } default: { break; } } } const element = document.getElementById('background'); element.style.backgroundImage = 'url("https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-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> 

What could be the cause and is there a way to prevent the video from buffering while still having a background image transition? 可能是什么原因,有没有办法阻止视频缓冲仍然有背景图像转换?

Edit: May be important to add that I'm on Chrome on MacOS. 编辑:添加我在MacOS上的Chrome上可能很重要。

Edit 2: From the responses I have gathered not everyone can reproduce the problem, so I went to an old-timey windows PC and tried it there. 编辑2:从我收集的回复不是每个人都可以重现问题,所以我去了一个旧的Windows PC并在那里尝试。 Found out that the background-transition was being really slow and laggy but the video kept playing without problem. 发现背景转换真的很慢而且很迟钝,但视频一直播放没有问题。 It also works on safari on MacOS so this appears to be a Chrome MacOS-only problem. 它也适用于MacOS上的Safari,因此这似乎只是Chrome MacOS问题。

尝试在Chrome上启用/禁用硬件加速。

I have to admit I'm not entirely sure of what happens here... Given it's not a 100% repro case, it's also hard to be sure any workaround actually works... 我不得不承认我不完全确定这里发生了什么......鉴于它不是100%的复制案例,也很难确定任何解决方法实际上有效......

But here are some comments and ideas. 但这里有一些评论和想法。


It seems this happens only with .mp4 files. 这似乎只发生在.mp4文件中。 I could reproduce with other .mp4 videos but never with any .webm file. 我可以使用其他.mp4视频重现,但从不使用任何.webm文件。
So one thing you may want to try is to reencode your video in webm, it could be that Chrome's mp4 decoder has some issues. 因此,您可能想要尝试的一件事是在webm中重新编码您的视频,可能是Chrome的mp4解码器存在一些问题。


It seems that CSS animations do not cause this issue. 似乎CSS 动画不会导致此问题。 So you could rewrite your transition code into a CSS animation, with the major problem that you won't be able to stop it in the middle (but it seems background-transitions are bad at this anyway). 因此,您可以将转换代码重写为CSS动画,主要问题是您无法在中间停止它(但无论如何,背景转换似乎都很糟糕)。

 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/stackoverflow-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/stackoverflow-com-logo-png-transparent.png"); } } @keyframes SO-to-apple { from { background-image: url("https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-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> 

Now if you prefer js control, it seems that Web-Animations aren't affected either. 现在,如果您更喜欢js控件,那么Web-Animations似乎也不会受到影响。

 let current = 1; const urls = [ "https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-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/stackoverflow-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> 

I can't reproduce the problem so it might be an issue with your ISP and latency (I don't have that problem at 145 Mbps). 我无法重现这个问题所以它可能是你的ISP和延迟的问题(我没有145 Mbps的问题)。 Looking at your code it isn't very efficient with that switch. 查看代码,使用该开关效率不高。 The demo below uses an array (added another image as well). 下面的演示使用一个数组(也添加了另一个图像)。 BTW add flex to elements that contain children elements otherwise it's pointless. BTW将flex添加到包含子元素的元素,否则它是没有意义的。

 document.getElementById('button').onclick = changeBackground; let i = 0; function changeBackground(e) { const images = ["https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-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/stackoverflow-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> 

This question is interesting. 这个问题很有意思。

I think the buffer may be due to 我认为缓冲区可能是由于

  1. This line Math.floor(Math.random()*16777215).toString(16); 这一行Math.floor(Math.random()* 16777215).toString(16);
  2. also about the video resolution and to what extent it has been resized 还有关于视频分辨率以及调整大小的程度
  3. also may be due to some unnecessary codes if any. 也可能是由于一些不必要的代码(如果有的话)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM