Создание интерактивного видео на HTML5

Благодаря элементу <video> из спецификации HTML5, теперь вставить видео на сайт так же просто, как картинку. И если принять во внимание, что все ведущие браузеры поддерживают <video> с 2011 года, сейчас это ещё и самый надёжный способ показать людям ваши движущиеся картинки.

Относительно новым в HTML5-семействе является элемент <track>. Это дочерний элемент для <video>, предназначенный для упрощения доступа к временной шкале видеоролика. В основном он нужен для добавления субтитров. Субтитры загружаются из отдельного текстового файла (в формате WebVTT) и воспроизводятся в нижней части области отображаемого видео. Ян Девлин (Ian Devlin) написал отличную статью на эту тему.

Однако, помимо субтитров, элемент <track> можно использовать для любых видов взаимодействия с временной шкалой видеоролика. В этой статье будут рассмотрены три примера: метки эпизодов, миниатюры предпросмотра и поиск по временной шкале. После прочтения статьи вы будете значительно лучше понимать принцип работы <track> и его API, что позволит вам создавать собственные интерактивные видеоролики.

Метки эпизодов

Давайте начнём с примера, который многим стал знаком благодаря DVD-дискам: метки эпизодов. Они позволяют зрителям быстро перейти к конкретному эпизоду. Это особенно удобно когда видео длинное как «Синтел»:

Метки эпизодов в этом примере помещены во внешний VTT-файл и загружаются на страницу с помощью элемента <track>, со своего рода разделами. В этом коде <track> установлен для загрузки по умолчанию:

<video width="480" height="204" poster="assets/sintel.jpg" controls>
  <source src="assets/sintel.mp4" type="video/mp4">
  <track src="assets/chapters.vtt" kind="chapters" default>
</video>

Затем мы используем JavaScript чтобы загрузить подписи из текстовой дорожки, отформатировать их и вывести в панели управления под видео. Обратите внимание, что нам нужно подождать пока загрузится VTT-файл:

track.addEventListener('load',function() {
    var c = video.textTracks[0].cues;
    for (var i=0; i<c.length; i++) {
      var s = document.createElement("span");
      s.innerHTML = c[i].text;
      s.setAttribute('data-start',c[i].startTime);
      s.addEventListener("click",seek);
      controlbar.appendChild(s);
    }
});

В этом коде мы добавляем 2 свойства списку записей чтобы получить интерактивность. Во-первых, мы устанавливаем атрибут data для хранения информации о начальной позиции эпизода, во-вторых, мы добавляем обработчик клика для внешней функции поиска. Эта функция будет проматывать видео к начальной позиции эпизода. Если видео (ещё) не проигрывается, это делается так:

function seek() {
  video.currentTime = this.getAttribute('data-start');
  if(video.paused){ video.play(); }
};

Вот и всё! Теперь у вас есть визуальное меню с эпизодами для вашего видеоролика, созданное с помощью VTT-дорожки. Обратите внимание, что в действующем примере создания меток для эпизодов используется большее количество кода, чем было описано выше, например, код для запуска проигрывания по клику, код для обновления позиции видео в панели эпизодов и немного CSS-стилей.

Миниатюры предпросмотра

Вторым примером является замечательная фича, популярности которой способствовали видеосервисы Hulu и Netflix: миниатюры предварительного просмотра. При наведении курсора на панель управления (или при перетягивании на мобильных устройствах), отображается превью для позиции, к которой вы собираетесь перейти:

Этот пример также сделан с помощью внешнего VTT-файла, загруженного в дорожку метаданных. Вместо текста метки в этом VTT-файле содержат ссылки на отдельные JPG-изображения. Каждая метка может содержать ссылку на отдельный файл, однако в этом случае мы отдали предпочтение JPG-спрайту из соображений быстрой загрузки и удобной поддержки в дальнейшем. Метки привязаны к соответствующему участку спрайта с помощью URI медиа фрагментов. Пример:

http://example.com/assets/thumbs.jpg?xywh=0,0,160,90

Вся важная логика получения правильной миниатюры и её отображения содержится в обработчике события mousemove для панели управления:

controlbar.addEventListener('mousemove',function(e) {
  // сначала на основе позиции мыши рассчитываем позицию во времени ..
  var p = (e.pageX - controlbar.offsetLeft) * video.duration / 480;

  // ..затем находим соответствующую метку..
  var c = video.textTracks[0].cues;
  for (var i=0; i p) {
          break;
      };
  }

  // ..затем определяем url-адрес изображения и медиа фрагмента..
  var url =c[i].text.split('#')[0];
  var xywh = c[i].text.substr(c[i].text.indexOf("=")+1).split(',');

  // ..и наконец стилизируем перекрытие миниатюрой
  thumbnail.style.backgroundImage = 'url('+c[i].text.split('#')[0]+')';
  thumbnail.style.backgroundPosition = '-'+xywh[0]+'px -'+xywh[1]+'px';
  thumbnail.style.left = e.pageX - xywh[2]/2+'px';
  thumbnail.style.top = controlbar.offsetTop - xywh[3]+8+'px';
  thumbnail.style.width = xywh[2]+'px';
  thumbnail.style.height = xywh[3]+'px';
});

Вот и всё. Опять же, актуальный пример с миниатюрами для предпросмотра содержит дополнительный код. В нём предусмотрена та же логика запуска воспроизведения и поиска, а также отображения/скрытия миниатюр при наведении курсора на панель управления.

Поиск по временной шкале

В нашем последнем примере рассмотрим ещё один способ добраться до контента, на этот раз с помощью поиска внутри видео:

В этом примере использован ранее созданный VTT-файл с титрами , который загружается в дорожку субтитров. Под видео и панелью управления мы выводим простую форму поиска:

Как в примере с миниатюрами, вся ключевая логика помещена в одну функцию. Например, это обработчик события для отправки формы:

form.addEventListener('submit',function(e) {
  // Сначала мы блокируем перезагрузку страницы и извлекаем ключевое слово/запрос..
  e.preventDefault();
  var c = video.textTracks[0].cues;
  var q = document.querySelector("input").value.toLowerCase();

  // ..затем находим все подходящие метки..
  var a = [];
  for(var j=0; j -1) {
      a.push(c[j]);
    }
  }

  // ..и выводим найденные метки в панели управления
  for (var i=0; i<a.length; i++) {
    var s = document.createElement("span");
    s.style.left = (a[i].startTime/video.duration*480-2)+"px";
    bar.appendChild(s);
  }
});

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

Подведём итоги

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

HTML5-элемент <track> представляет простой в применении, кроссплатформенный способ добавления интерактивности в ваши видеоролики. И хотя вам придётся потратить некоторое время на создание VTT-файлов и выстраивание взаимодействия, вы отметите улучшение доступности ваших роликов и повышение интереса к ним. Удачи!