【问题标题】:CSS background-image transition makes video tag bufferCSS background-image 过渡使视频标签缓冲
【发布时间】:2019-06-05 15:45:04
【问题描述】:

我有一个视频标签,我想连续播放,同时用户可以同时在网站上做一些事情。但是我发现,如果视频开始缓冲的背景图像之间的背景转换。我在下面的 sn-p 中有一个可运行的示例。

注意: 如果 sn-p 正常运行,似乎不会发生缓冲,但如果将 sn-p 放在“整页”中,就会发生缓冲。

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>

可能是什么原因,有没有办法防止视频缓冲,同时仍然有背景图像过渡?

编辑:添加我在 MacOS 上使用 Chrome 可能很重要。

编辑 2:从我收集的回复来看,并不是每个人都能重现这个问题,所以我去了一台老式的 Windows PC 并在那里试了一下。发现背景转换非常缓慢且滞后,但视频继续播放没有问题。它也适用于 MacOS 上的 safari,因此这似乎是 Chrome MacOS-only 问题。

【问题讨论】:

  • 我尝试了几次(Win10 上的 Chrome),但它并没有一直这样。有时它不显示缓冲,有时仅在第一次转换时显示。
  • 当我测试并根据您和 zer00nes 的响应时,它似乎不会在 Windows 上发生,但它确实发生在多台 Mac 上。

标签: javascript macos google-chrome html5-video css-transitions


【解决方案1】:

我不得不承认我并不完全确定这里会发生什么...鉴于这不是 100% 的重现案例,也很难确定任何解决方法确实有效...

但这里有一些 cmets 和想法。


这似乎只发生在 .mp4 文件中。我可以使用其他 .mp4 视频进行复制,但不能使用任何 .webm 文件。
因此,您可能想尝试的一件事是在 webm 中重新编码您的视频,这可能是 Chrome 的 mp4 解码器存在一些问题。


似乎 CSS 动画 不会导致此问题。因此,您可以将过渡代码重写为 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>

现在如果你更喜欢 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>

【讨论】:

  • 感谢您的响应和很好的发现,它似乎没有使用 .webm 文件进行缓冲。至于 .mp4 不幸的是 sn-p #1 对我来说似乎仍然存在问题(尽管它看起来更好但也许我在想象事情)。 #2 在点击时没有动画,并给出错误“未捕获的 NotSupportedError:无法执行 animate' on 'Element': Partial keyframes are not supported.。关于如何修复该问题的任何想法?
  • 哎呀,我的错,我忘了我有实验功能,稳定版仍然不支持这种语法......
【解决方案2】:

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

【讨论】:

  • 这似乎可行,但我希望有一个不需要我的用户更改 chrome 设置的解决方案。不过感谢您的建议!
  • 我知道你期待一个解决方案,但你的代码对我来说似乎很好。读了一点后,我发现缓冲是操作系统下 Chrome 的一个常见问题。希望能在这个人的帮助下解决问题。
【解决方案3】:

我无法重现该问题,因此可能是您的 ISP 和延迟问题(我在 145 Mbps 时没有该问题)。查看您的代码,该开关效率不高。下面的演示使用了一个数组(还添加了另一个图像)。顺便说一句,将 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>

【讨论】:

  • 感谢您的回复,不幸的是,我看到与您改进的代码相同的视频缓冲。我认为这可能与处理能力有关?
【解决方案4】:

这个问题很有趣。

我认为缓冲区可能是由于

  1. 这一行 Math.floor(Math.random()*16777215).toString(16);
  2. 还有关于视频分辨率以及调整大小的程度
  3. 也可能是由于一些不必要的代码(如果有的话)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2016-09-13
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    相关资源
    最近更新 更多