CSS background-image transition делает буфер видео тега - PullRequest
7 голосов
/ 21 мая 2019

У меня есть видео-тег, который я хочу воспроизводить непрерывно, пока пользователь может одновременно что-то делать на сайте. Однако я обнаружил, что если фоновые переходы между фоновыми изображениями, то видео начинает буферизироваться. В приведенном ниже фрагменте у меня есть работающий пример.

Примечание: Похоже, что буферизация не происходит, если фрагмент выполняется нормально, но происходит, если вы помещаете фрагмент в «полную страницу».

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>

В чем может быть причина, и есть ли способ предотвратить буферизацию видео при сохранении перехода к фоновому изображению?

Редактировать: может быть важно добавить, что я нахожусь на Chrome на MacOS.

Редактировать 2: Из ответов, которые я собрал, не все могут воспроизвести проблему, поэтому я пошел к старому Windows-ПК и попробовал его там. Выяснилось, что фоновый переход был очень медленным и медленным, но видео продолжало воспроизводиться без проблем. Он также работает в Safari на MacOS, так что, похоже, это проблема Chrome MacOS .

Ответы [ 4 ]

1 голос
/ 05 июня 2019

Я должен признать, что я не совсем уверен в том, что здесь происходит ... Учитывая, что это не 100% случай репро, также трудно быть уверенным, что любой обходной путь действительно работает ...

Но здесьВот некоторые комментарии и идеи.


Кажется, что это происходит только с .mp4 файлами.Я мог бы воспроизводить с другими .mp4 видео, но никогда с любым .webm файлом.
Так что одна вещь, которую вы можете попробовать, это перекодировать ваше видео в webm, это может бытьчто у mp4-декодера Chrome есть некоторые проблемы.


Кажется, что 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, кажется, что веб-анимация также не затрагивается.

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>
1 голос
/ 05 июня 2019

Попробуйте включить / отключить аппаратное ускорение в Chrome.

0 голосов
/ 02 июня 2019

Этот вопрос интересный.

Я думаю, что буфер может быть из-за

  1. Эта строка Math.floor (Math.random () * 16777215) .toString (16);
  2. также о разрешении видео и в какой степени оно было изменено
  3. также может быть связано с некоторыми ненужными кодами, если таковые имеются.
0 голосов
/ 21 мая 2019

Я не могу воспроизвести проблему, поэтому это может быть проблема с вашим провайдером и задержкой (у меня нет этой проблемы при 145 Мбит / с).Глядя на ваш код, он не очень эффективен с этим переключателем.В демонстрации ниже используется массив (также добавлено другое изображение).Кстати, добавьте 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>
...