Отображать одно и то же видео в нескольких тегах <video>

У меня есть видео (пусть его называют композитным видео), состоящим из нескольких других видео, объединенных с помощью какого-то шаблона. Например, см. Скриншот видео ниже, составленный двумя и четырьмя другими видео соответственно:

Пример 2-видео

Пример 4-видео

Однако мне нужно отобразить его по-разному: одно главное, большее, видео и N-1 видео эскизы, где N - общее количество видео. Вот этот другой дисплей, соответствующий видео выше:

Основное видео + 1 эскиз

Основное видео + 3 эскиза

Чтобы отобразить основной, я использую комбинацию HTML и CSS для размещения видео, которое я хочу в более крупном div. Он работает плавно, независимо от количества видео в композитных видео.

Чтобы отобразить миниатюры, я использую <canvas> для рисования частей, которые я хочу:

video.addEventListener('play', function() {
  (function loop() {
    drawThumbnails();
    setTimeout(loop, 1000 / 30); // drawing at 30fps
  })();
}, false);

function drawThumbnails() {
  for (var i = thumbs.length - 1; i >= 0; i--) {
    drawThumbnail(thumbs[i]);
  };
}

function drawThumbnail(thumb) {
  var thumbNumber = Number(thumb.id.match(/\d+/g));
  var canvasContext = thumb.getContext('2d');
  var thumbCoordinates = getVideoCoordinates(thumbNumber);
  var srcX = thumbCoordinates.column * videoWidth;
  var srcY = thumbCoordinates.row * videoHeight;

  canvasContext.drawImage(
      video, srcX, srcY, videoWidth, videoHeight, // Source
      0, 0, thumb.width, thumb.height); // Destination
}

Он работал хорошо для 3 (иногда 4) видео. Однако по мере увеличения количества видеороликов в композитном видеоролики видеоролики в миниатюрах начинают замораживаться и запускаться не плавно. Это, вероятно, происходит потому, что в тоже время выполняется слишком большая обработка изображений.

Я думаю, что правильный способ сделать это - каким-то образом использовать <video> и методы, специфичные для видео, а не для изображений. Я также попытался использовать те же src в нескольких тегах <video> (по одному для каждого миниатюры) и добавить eventListeners, чтобы воспроизводить/приостанавливать видео в миниатюрах, как только основное видео воспроизводится/приостанавливается. Это не очень эффективно, особенно потому, что видео иногда может выходить из синхронизации при поиске/буферизации.

Есть ли способ использовать только одно видео в нескольких тегах <video> и использовать только один из них (в моем случае тот, который содержит основное видео), чтобы управлять всеми остальными? Если нет способа сделать это, есть ли альтернативный подход к моей проблеме?

Большое спасибо,

P.S. Наличие нескольких разделенных видео не является вариантом в моей ситуации. Это займет очень много времени, чтобы обработать входное видео и разделить его на несколько видеороликов.

Ответ 1

Я знаю, что я опаздываю, и вы, возможно, уже нашли ответ. Однако, если кто-то еще сталкивается с этим вопросом, вот мой ответ:

Вы можете использовать несколько видеоэлементов с одним и тем же источником. Способ сделать это с помощью css.

.wrapper {
    height: /*height of one video*/;
    width: /*width of one video*/;
    overflow: hidden;
}
video {
    position: relative;
    top: /*height offset*/;
    left: /*width offset*/;
}

И HTML

<div class="wrapper">
    <video src="myvideo.mp4"></video>
</div>

Итак, если бы я делал видео в правом верхнем углу, и каждый из них был 250px на 250px, я бы установил свою обертку height и width в 250px и мое видео top на 0px и мое видео left до 250px

Ответ 2

Вы можете ссылаться на одно и то же видео на несколько видеоэлементов. Клонирование оригинала и добавление его в виде видеороликов для миниатюр может облегчить некоторые из скуки.

Итерация над эскизами и .play() их использование должно быть прекрасным до тех пор, пока вы установите для них currentTime значение основного видео до воспроизведения, чтобы свести к минимуму дрейф. Может возникнуть необходимость ждать, пока canplay загорится на главном видео и/или миниатюрах в зависимости от того, что вы хотите выполнить.

Если каждому миниатюре предоставлен родительский контейнер, вы можете поместить элемент видео, служащий в качестве миниатюры таким образом, чтобы видна только часть видео, которую вы хотите видеть, и отсекайте остальные.

FWIW, Маскировка CSS может представлять интерес для вас как оптимизацию производительности, если она помогает в производительности компоновки.

Вам нужно будет вручную координировать воспроизведение/приостановку всех элементов видео, но это должно быть достаточно легко сделать с фасадным объектом, который обрабатывает паузу воспроизведения всех "связанных" видеоэлементов.

Ответ 3

Какой формат основного видео? Это файл mp4/webm по запросу?

Если вы все еще хотите пойти с вашим подходом к захвату кадров и нарисовать их, но сталкиваетесь с проблемами производительности, подумайте об использовании веб-работников для тяжелых работ. Здесь вы можете найти несколько примеров манипуляции с видео/холстом с веб-рабочими.