Создание интерактивного видеоплеера: архитектура и компромиссы

Автор: Николай СапуновОбновлено: август 202622 мин чтения
Содержание статьи +

Кратко

Интерактивный видеоплеер не только проигрывает урок: он показывает поверх видео квизы, хотспоты, развилки сюжета и следит за действиями учащегося. Сам движок воспроизведения почти никогда не пишут с нуля – с этим хорошо справляются браузер и несколько зрелых open-source-библиотек. Настоящая разработка – выше. Шина событий слушает события видео (play, pause, перемотку), слой оверлеев показывает интеракции в нужную секунду, хранилище интеракций помнит действия учащегося, а мост трекинга превращает всё это в xAPI-утверждения, понятные LMS. Поэтому вопрос «строить или купить» звучит не как «нужен ли свой плеер», а как «какую часть интерактива взять у вендора, а какую сделать своей». Ответ зависит от того, составляют ли контроль над каталогом и собственные интеракции суть продукта или это просто пункт в требованиях. В статье – каждый слой простыми словами, мост от события плеера к xAPI в коде, расчёт стоимости и чек-лист «строить или купить», чтобы бюджет уходил на то, что действительно отличает ваш продукт.

Почему это важно

Если вы отвечаете за корпоративное обучение, основали EdTech-продукт или развиваете платформу тренингов, видеоплеер для вас – место, где контент встречается с учащимся. От него зависят почти весь интерактив, трекинг и выполнение требований доступности. Ошибётесь с границей «строить или купить» – и либо будете годами платить вендору за плеер, из которого выросли, либо потратите месяцы разработки на воспроизведение, которое браузер даёт бесплатно. Удачные команды тратят бюджет в одном месте: на тонкий, но ценный слой, который делает видео интерактивным и измеримым. Само проигрывание – неблагодарную работу, полную багов, – они отдают проверенным библиотекам. Здесь есть всё, чтобы провести эту границу: словарь, архитектура для брифа инженерам и цифры, чтобы защитить решение перед финансовым директором.

Что такое интерактивный видеоплеер

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

Получается, что интерактивный плеер состоит из двух частей. Движок воспроизведения превращает видеофайл в картинку и звук. Слой интеракций следит за воспроизведением и добавляет к нему смысл. Из этого деления следует главное решение статьи. Движок воспроизведения вы писать не будете: браузер и несколько зрелых библиотек справляются с ним лучше, чем вы можете себе позволить. А вот какую часть слоя интеракций делать своей – решать вам, и дальше речь пойдёт о том, где провести эту границу.

Про движок – конкретнее. В браузере уже есть полноценный плеер: элемент <video>, описанный в HTML Living Standard – постоянно обновляемой спецификации веб-платформы (WHATWG HTML Living Standard, медиаэлементы). Он декодирует распространённые форматы, рисует стандартные контролы и предоставляет богатый программный интерфейс HTMLMediaElement: через него код запускает воспроизведение, читает текущее время и подписывается на события. На этом интерфейсе построены все варианты из статьи, включая коммерческие.

Рисунок 1. Три пути на одной шкале. Слева направо контроль и владение уступают скорости запуска: расширить нативный HTML5-плеер, взять open-source-фреймворк (Video.js, Shaka) или подключить готовую видеоплатформу с плеером. Большинство обучающих продуктов выбирают середину и строят только слой интеракций.

Три способа построить плеер

Честных путей три, и они лежат на шкале от «всё ваше» до «всё у вендора». Чётко их назвать – уже половина решения.

Путь первый: расширить нативный HTML5-плеер. Вы берёте встроенный элемент <video> и строите контролы, оверлеи и трекинг прямо на его программном интерфейсе, подключая максимум одну небольшую библиотеку. Это полный контроль и минимум кода, но все кросс-браузерные баги – ваши, а их много.

Путь второй: взять open-source JS-фреймворк. Вы строите продукт на зрелой бесплатной библиотеке, которая уже решила кросс-браузерные проблемы и даёт понятную структуру для расширения. Чаще всего звучат два имени – Video.js и Shaka Player, и задачи у них разные (об этом ниже). Так устроено большинство обучающих продуктов, сделанных на заказ: библиотека отвечает за воспроизведение и даёт точки расширения, а вы строите слой интеракций.

Путь третий: подключить готовую видеоплатформу. Вы платите российскому вендору – Kinescope, Boomstream, Facecast, Yandex Cloud Video и другим – за хостинг и плеер, в котором уже есть защита контента, аналитика просмотров, API, а иногда и элементы интерактива. Запуск быстрый, кода мало, но продукт подстраивается под возможности вендора, платежи регулярные, а трекинг и экспорт данных – такие, какие есть. Зарубежные видеоплатформы в России эту задачу почти не решают: с оплатой сложности, а данные учащихся по ч. 5 ст. 18 152-ФЗ нельзя хранить в зарубежных базах.

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

Архитектура: пять слоёв

Какой бы путь вы ни выбрали, у работающего интерактивного плеера одни и те же пять слоёв. Зная их, вы точно видите, что даёт вендор, а что остаётся на вас. Представьте стопку: внизу байты, наверху дашборд.

Рисунок 2. Пять слоёв интерактивного видеоплеера. Движок воспроизведения и шину событий в основном закрывают браузер и open-source-библиотеки; слой оверлеев, хранилище интеракций и мост трекинга – ваша разработка и ваше отличие.

Слой первый – движок воспроизведения. Он превращает видео в картинку и звук и берёт на себя сложные части стриминга: подстройку качества под сеть, буферизацию, воспроизведение защищённого контента. Для одного локального файла хватит элемента <video>. Для адаптивного стриминга, когда качество переключается на лету, браузер предоставляет Media Source Extensions (MSE) – спецификацию W3C, которая позволяет JavaScript самому собирать медиапоток (W3C Media Source Extensions). Для защищённого контента есть Encrypted Media Extensions (EME) – рекомендация W3C, через которую плеер без плагинов работает с модулем DRM (W3C Encrypted Media Extensions, Recommendation, 2017). Напрямую с MSE и EME вы почти не работаете: это делает библиотека. Устройство адаптивного стриминга – отдельная большая тема, адаптивному битрейту и протоколам посвящён раздел Video Streaming. Здесь воспроизведение считаем решённой задачей и строим поверх него.

Слой второй – шина событий. Это пульс интерактивного плеера и самый недооценённый слой. Во время воспроизведения интерфейс HTMLMediaElement непрерывно генерирует события: play, pause, seeking, seeked, timeupdate (повторяется по мере движения позиции), ended и другие (WHATWG HTML Living Standard, медиасобытия). Это внутренняя система оповещений плеера: «воспроизведение началось», «учащийся перешёл на 5:40», «видео закончилось». Все слои выше подписаны на эти оповещения. Оверлеи узнают из них, когда появиться, трекинг – что записать, доступные кастомные контролы – какое состояние показать. Шину событий не столько строят, сколько организуют, и от этой организации зависит, будет плеер работать гладко или сбоить.

Слой третий – оверлеи. Здесь интерактив становится видимым: карточка квиза на 4:30, кликабельный хотспот, выбор ветки, заметка, привязанная к моменту видео. Технически оверлей – это HTML поверх видео, который показывается и скрывается по текущему времени из шины событий. Как именно ведут себя квизы, хотспоты и ветвления, подробно разобрано в отдельных статьях (квизы и опросы в плеере, хотспоты, оверлеи и кликабельное видео и ветвящиеся сценарии). Задача плеера уже, но критична: дать каждому оверлею точные часы и надёжный контейнер. Ниже увидим, почему и то и другое сложнее, чем кажется.

Слой четвёртый – хранилище интеракций. Когда учащийся отвечает на квиз или выбирает ветку, результат нужно где-то сохранить: сначала в памяти плеера на время сессии, затем надёжнее, чтобы после перезагрузки или возвращения прогресс не пропал. Это краткосрочная память плеера: ответы, текущая ветка, просмотренные фрагменты, позиция для продолжения. Слой небольшой, но именно он отличает плеер, который бережёт время учащегося, от плеера, который заставляет начинать заново.

Слой пятый – мост трекинга. Он превращает всё, что видел плеер, в данные, с которыми может работать система обучения. Мост слушает шину событий и хранилище интеракций и отправляет xAPI-утверждения – короткие стандартизированные записи вида «Мария верно ответила на вопрос на 4:30» – в Learning Record Store (LRS), базу для их хранения. xAPI (Experience API) – стандарт данных об обучении, который развивает ADL; для видео в нём есть отдельный Video Profile, где точно описано, как фиксировать видеособытия (xAPI Video Profile, ADL, v1.0.3). Именно этот мост делает интерактивное видео измеримым; подробно он разобран в статье о трекинге видео через xAPI Video Profile. Ниже соберём его упрощённую версию, чтобы увидеть механизм.

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

Модель событий и есть архитектура

Если запомнить из статьи одну техническую мысль, пусть это будет она: в хорошо построенном интерактивном плеере поток событий видео – центральная нервная система, а каждая функция на него подписана. Новички используют эти события только для движения ползунка. Сильные команды превращают их в шину, к которой подключены оверлеи, ветвление, трекинг и доступность. События те же, архитектура совсем другая.

Первая тонкость отличает отточенный плеер от дёрганого. Самое очевидное событие о текущей позиции, timeupdate, намеренно неточное. Браузер генерирует его раз в 15–250 миллисекунд, и частота зависит от нагрузки на систему (MDN, событие timeupdate). Для ползунка этого достаточно: никто не заметит, что полоса обновляется четыре раза в секунду. Для оверлея, который должен появиться на точном кадре, это слишком грубо: квиз всплывёт на четверть секунды позже и будет выглядеть сломанным. Современное решение – колбэк requestVideoFrameCallback: он срабатывает на каждый показанный кадр и передаёт время, точно привязанное к часам видео (MDN, requestVideoFrameCallback). На практике timeupdate годится для дешёвых и нетребовательных обновлений вроде ползунка, а покадровый колбэк – для интеракций, которые должны попасть точно в момент. В списке функций такое знание не видно, зато хорошо чувствуется в работе продукта.

Вторая тонкость рано или поздно настигает каждую команду, которая строит трекинг. Событие сообщает, что сделал медиаэлемент, но не почему. Увидев pause, нельзя понять, нажал ли паузу учащийся или ваш же оверлей с квизом остановил видео до ответа. Инженеры Mux, которые поддерживают популярный плеер, после многих лет такой работы сформулировали это прямо: события «могут сработать, могут не сработать, могут прийти пачкой подряд», а отличить действие пользователя от действия системы – отдельная сложная задача (Mux, «6 Years Building Video Players», 2026). Отсюда требование к архитектуре: хранилище интеракций должно записывать рядом с сырым событием его причину, иначе аналитика исказит картину того, что делали учащиеся.

Строим мост трекинга: от события плеера к xAPI

Разберём мост трекинга на коде: этот слой напрямую связан с ценностью обучающего продукта. Для решения «строить или купить» читать код не обязательно, но одного взгляда хватит, чтобы убедиться: мост маленький, и ничего экзотического в трекинге нет.

xAPI Video Profile задаёт для видео небольшой фиксированный словарь. В нём три собственных глагола – played, paused и seeked, – а для остального используются стандартные глаголы xAPI: initialized, когда видео готово, completed, когда достигнут порог завершения, и terminated при выходе (xAPI Video Profile, ADL, v1.0.3). Профиль также определяет, куда записывать детали: в result-расширения time, time-from, time-to, progress и played-segments – точные тайминги, в context-расширения – длительность видео и признак включённых субтитров (xAPI Video Profile, ADL, v1.0.3).

Так что мост работает как таблица перевода: на входе событие браузера, на выходе xAPI-утверждение. Ниже минимальный рабочий набросок; данные учащегося в нём заведомо вымышленные:

const video = document.querySelector("video");
const actor = { mbox: "mailto:learner@example.org", name: "Test Learner" };
const object = { id: "https://example.org/courses/safety/video-7" };

function sendStatement(verbId, verbLabel, resultExtensions) {
  const statement = {
    actor,
    verb: { id: verbId, display: { "ru-RU": verbLabel } },
    object,
    result: { extensions: resultExtensions }
  };
  // Отправляем утверждение в ваш Learning Record Store (LRS)
  navigator.sendBeacon("/lrs/statements", JSON.stringify(statement));
}

// Событие плеера  ->  глагол xAPI + тайминг
video.addEventListener("play", () =>
  sendStatement("https://w3id.org/xapi/video/verbs/played",
                "played", { "https://w3id.org/xapi/video/extensions/time": video.currentTime }));

video.addEventListener("seeked", () =>
  sendStatement("https://w3id.org/xapi/video/verbs/seeked", "seeked", {
    "https://w3id.org/xapi/video/extensions/time-from": lastTime,
    "https://w3id.org/xapi/video/extensions/time-to": video.currentTime
  }));

Вся идея в этом: слушаем шину событий, переводим в стандартный словарь, отправляем в хранилище. Учтите, что actor в каждом утверждении – персональные данные учащегося, поэтому LRS, куда пишет мост, должен работать на базах данных в России. Сложности начинаются в трёх пограничных случаях, которые наивная версия выше обрабатывает неверно. О них стоит знать, чтобы задать вопросы команде.

Первый – шторм перемоток. Пока учащийся тянет ползунок, браузер может выдать десятки событий seeked в секунду. Если отправлять всё как есть, LRS утонет в шуме. Решение – debounce: дождаться, пока перетаскивание закончится, и отправить одно утверждение о переходе «откуда – куда».

Второй – порог завершения. «Досмотрел до конца» и «завершил» – разные вещи, и Video Profile говорит об этом прямо: завершение определяется порогом (по умолчанию – всё видео, но порог настраивается) и считается по фактически просмотренным фрагментам, а не по тому, дошла ли позиция до последней секунды (xAPI Video Profile, ADL). Учащийся, который перемотал в конец, оказался на последней секунде, ничего не посмотрев. Расширение played-segments нужно как раз для того, чтобы отличать такие случаи. Это та же ловушка «просмотрено 100% ≠ завершено», которая проходит через всю тему метрик обучения.

Третий – пакетная отправка и надёжность. Отправлять по HTTP-запросу на каждое событие расточительно и ненадёжно: если учащийся закроет вкладку посреди запроса, утверждение потеряется. Зрелые мосты копят утверждения в буфере и отправляют пачками, причём способом, который переживает закрытие страницы. Задачи эти давно решены, но если вы строите мост сами, решать их придётся вам. Поэтому некоторые команды и ценят вендоров, у которых трекинг уже всё это умеет.

Рисунок 3. Мост трекинга. Сырые события плеера (play, pause, seeked, ended) сглаживаются, переводятся в глаголы xAPI Video Profile с расширениями для таймингов, собираются в пакеты и уходят в Learning Record Store, откуда данные получают аналитика и LMS.

Video.js, Shaka Player или чистый HTML5

На open-source-пути выбор обычно идёт между двумя библиотеками, и это не совсем конкуренты: они закрывают разные слои. Если понять разницу заранее, команда не выберет не тот инструмент и не будет потом переписывать продукт.

Video.js – фреймворк для расширения плеера. Его ценность в структуре: дерево UI-компонентов, которые можно регистрировать и переставлять, двухуровневая система плагинов (простые плагины-функции и плагины с состоянием и собственным жизненным циклом) и абстракция Tech, позволяющая одному плееру работать с разными технологиями воспроизведения (документация Video.js). Лицензия Apache 2.0, бесплатно. Обучающему продукту он даёт готовое место для слоя оверлеев и моста трекинга: фреймворк создавался именно для таких расширений. Сложного адаптивного стриминга и аналитики в базовой поставке нет, их добавляют отдельно.

Shaka Player от Google – движок воспроизведения, а не UI-фреймворк. Его задача – адаптивный стриминг: он проигрывает DASH и HLS, два основных адаптивных формата, через MSE и EME, умеет офлайн-загрузку и DRM (Widevine, PlayReady, FairPlay) и поставляется с отдельной необязательной UI-библиотекой для контролов (Shaka Player, Google, Apache 2.0). Оверлеев, хотспотов, квизов и прочих учебных интеракций в нём нет. Если главное – надёжный стриминг защищённого адаптивного контента, Shaka будет сильным выбором, но слой интеракций поверх него вы строите сами.

Есть и варианты полегче. hls.js и dash.js – чистые движки воспроизведения, каждый для одного формата стриминга, без интерфейса: их подключают к голому <video>, а всё остальное делают сами. Plyr и MediaElement.js – лёгкие доступные плееры с готовым интерфейсом для простых задач. Они названы здесь, чтобы показать: за словами «взять open-source-плеер» стоит выбор на шкале от «только контролы» (Plyr) через «только стриминг» (Shaka, hls.js) до «фреймворка для расширения» (Video.js). Для большинства интерактивных обучающих продуктов естественная основа – Video.js, потому что он создан для расширения; Shaka добавляют, когда адаптивный стриминг и DRM входят в обязательные требования.

Путь чистого HTML5 тоже рабочий, а для продукта с узкими задачами может оказаться самым аккуратным: библиотеки не добавляют лишнего веса. Но тогда вы вручную заново решаете кросс-браузерные проблемы, ради которых эти библиотеки и существуют. Худшие из них – в следующем разделе.

Подводные камни, которых нет в списке функций

В интерактивном видео много мелких неприятных ловушек. Каждая из описанных ниже уже ломала реальные продукты в продакшене. Зная их, вы проверите продукт до запуска и зададите вендорам правильные вопросы.

Полноэкранный режим скрывает оверлеи. В полноэкранном режиме браузер выводит поверх всего один элемент с его потомками, а остальное скрывает (MDN, Fullscreen API). Если оверлеи – соседи <video>, а не потомки контейнера, который разворачивается на весь экран, они исчезают, как только учащийся нажимает кнопку: квизы, хотспоты – всё. Решение архитектурное: каждый оверлей должен жить внутри того же контейнера, который уходит в полноэкранный режим. Обычно команды узнают об этом уже после релиза, из обращения «квиз пропадает на проекторе».

У мобильного Safari свои правила. На iPhone видео без атрибута playsinline при старте сразу открывается в системном полноэкранном плеере, и весь ваш интерфейс – контролы, оверлеи, элементы трекинга – пропадает (WebKit, «New video policies for iOS»). Кроме того, автовоспроизведение работает только без звука. Решение известно: playsinline, автозапуск без звука и включение звука по касанию. Но команда, которая не проверила плеер на настоящем iPhone, узнаёт об этом из отзыва с одной звездой.

DRM может помешать оверлеям. Это действительно сложный случай, и о нём почти не пишут. Когда контент защищён DRM на базе EME, кадры видео могут выводиться по защищённому пути, недоступному остальной странице. Отрисовать защищённый кадр на HTML-холсте (canvas) нельзя, а холст, на который попал защищённый или кросс-доменный контент, выдаёт ошибку при попытке прочитать пиксели (W3C EME; MDN, CORS-enabled image). Если оверлеи задуманы с чтением кадров – генерацией превью, размытием участка, эффектами наложения, – DRM это сломает. Поэтому решите про DRM заранее: он ограничивает возможности слоя оверлеев. И проектируйте оверлеи как DOM-элементы поверх видео, а не как эффекты, которые рисуются в самом кадре.

Кастомные контролы незаметно ломают доступность. Стандартные контролы браузера работают с клавиатуры и озвучиваются скринридером без дополнительных усилий. Заменив их своими стилизованными (а так поступает большинство брендированных обучающих плееров), вы обязаны воспроизвести эту доступность вручную. Типичная ошибка – ползунок из обычного <div> без управления с клавиатуры и без role="slider". Вспомогательные технологии его не видят, и он нарушает критерий 2.1.1 «Клавиатура» уровня A из WCAG 2.1 (W3C WCAG), а значит, и российский ГОСТ Р 52872-2019, основанный на WCAG 2.1. Субтитры – отдельное требование: критерий 1.2.2 (субтитры для записанного контента) относится к уровню A, живые субтитры по 1.2.4 – к уровню AA (W3C WCAG 2.2). Отказываться из-за этого от кастомного плеера не нужно, но бюджет на доступность заложить стоит; подробности – в статье WCAG 2.1 AA и ГОСТ Р 52872-2019 для учебного видео.

Ловушка переписывания. Самая коварная проблема – рост масштаба. Плеер начинается с «просто play и pause», потом нужны субтитры, адаптивный стриминг, DRM, аналитика, реклама, офлайн, и каждое добавление кажется небольшим. Команда Mux после девяти миллиардов запросов к плееру пришла к выводу, что даже хорошо построенный плеер, который поддерживает один сильный инженер, в масштабе «неустойчив»: объём того, что приходится поддерживать, растёт без остановки (Mux, 2026). Это сильнейший аргумент против собственного движка воспроизведения и за то, чтобы строить только тонкий слой интеракций, который действительно ваш.

Цифры: сколько стоит своя разработка

Посчитаем: «строить или купить» – финансовое решение в технической обёртке. Цифры ниже – инженерные оценки 2026 года (сверьте со ставками своей команды), но важнее структура затрат.

Сделать только слой интеракций поверх open-source-плеера – оверлеи, хранилище интеракций, xAPI-мост, доступные кастомные контролы – проект с понятными границами. Разумная первая версия укладывается в 10–20 инженеро-недель. В деньгах:

  • 15 инженеро-недель × 40 часов × (допустим) 4 700 ₽/час средней ставки по команде = 2 820 000 ₽ (≈ 2,8 млн ₽) за надёжную первую версию.

Средняя ставка здесь – ориентир для команды с сеньорами или для подрядчика. Для штатной команды полезна другая точка отсчёта: медианные зарплаты по данным Хабр Карьеры в 2026 году – middle 178 тыс. ₽ и senior 304 тыс. ₽ в месяц на руки; полная стоимость часа для работодателя выше из-за налогов и накладных расходов.

Сделать полностью свой плеер вместе с движком воспроизведения – собственный адаптивный стриминг, интеграцию DRM, кросс-браузерное воспроизведение – задача совсем другого масштаба: 8–12 недель работы команды из 3–4 инженеров (24–48 инженеро-недель) до выхода на поддержку, обычно ≈ 4,5–9 млн ₽ (оценки Фора Софт по кастомным плеерам и стримингу). И поддержка обязательна: закладывайте примерно 25–30% стоимости разработки в год только на то, чтобы успевать за изменениями браузеров и исправлять баги.

Теперь сторона «купить». Тарифы видеоплатформ начинаются от нескольких тысяч рублей в месяц (Boomstream – от ≈ 3 000 ₽) и растут с объёмом и набором функций; корпоративные тарифы – по запросу. Возьмём для примера корпоративный тариф 130 000 ₽ в месяц: за три года это 36 × 130 000 ₽ = 4 680 000 ₽ (≈ 4,7 млн ₽), то есть 1,56 млн ₽ в год. Разработка слоя интеракций (≈ 2,8 млн ₽) стоит меньше двух лет такой подписки, но к ней добавляется поддержка: 25–30% в год – это ещё ≈ 0,7–0,85 млн ₽ ежегодно. За три года своё решение обойдётся в 2,82 млн ₽ + 3 × (0,7–0,85) млн ₽ ≈ 4,9–5,4 млн ₽ – примерно как подписка, а дешевле неё станет только на четвёртый год. Зато развитием продукта управляете вы, а не вендор. Учтите российскую специфику: готовые платформы закрывают хостинг, защиту и аналитику просмотров, но развитый интерактив и xAPI в базовой поставке публично не заявляют. Поэтому слой интеракций часто приходится строить в любом случае – поверх их Player API или open-source-плеера.

Как читать эти цифры. Не стройте движок воспроизведения, если только воспроизведение и есть ваш продукт (для обучающей компании так почти не бывает). С учётом поддержки собственный слой интеракций за три года стоит примерно столько же, сколько подписка на платформу, поэтому решает не голая стоимость, а то, даёт ли собственный слой то, чего не даст вендор: свои типы интеракций, свой конвейер данных и отсутствие ограничений по числу пользователей. Если это важно, разработка окупается; если нет, разумнее купить.

Строить, купить или расширить: сравнение

Ниже то же решение в виде таблицы, с указанием поддерживаемых стандартов: для обучающего продукта поддержка трекинга важнее всего.

ВариантЧто вы строитеИнтерактивТрекинг / стандартыКому подходит
Чистый HTML5 + ваш кодВсё над воспроизведениемПолностью свойxAPI-мост строите выУзкие задачи, без лишних библиотек
Video.js (расширить)Слой оверлеев, хранилище, трекингПолностью свой, на понятном фреймворкеxAPI Video Profile через плагинОбучающий продукт на заказ, полный контроль
Shaka PlayerВесь интерактив + UIСтроите самиxAPI-мост строите самиПриоритет – адаптивный стриминг с DRM
H5P (инструмент интерактивного видео)Только настройка автором курсаВстроенные квизы, закладки, переходыОтправляет xAPI сам; LRS размещаете выИнтерактив на уровне курса, быстро
iSpring Suite (авторинг курсов)Курс в редакторе, без своей разработкиТесты и интерактивности на уровне курса; видео – элемент курсаЭкспорт в SCORM 1.2/2004, xAPI, cmi5Курсы для LMS, быстро; в реестре отечественного ПО
Российская видеоплатформа (Kinescope, Boomstream, Facecast, Yandex Cloud Video)Конфигурация, тема, интеграция через Player API / SDKЗащищённый плеер (DRM и водяные знаки у Kinescope и Boomstream); интерактив поверх – обычно ваш слойАналитика просмотров; xAPI публично не заявлен – мост строите выБыстрый запуск, хостинг и данные в России

Самый важный для обучающей команды столбец – трекинг. Ни один open-source-плеер не поставляет аналитику зрителей или xAPI: мост строите вы (код выше показывает, что это посильно). Российские видеоплатформы, судя по публичной документации, xAPI не заявляют: у них хорошая аналитика просмотров и качества доставки, но LMS не прочитает её как данные об обучении. Нативный xAPI на уровне курса дают H5P и инструменты авторинга вроде iSpring Suite (экспорт в xAPI и cmi5), но они работают внутри своего формата, а не в вашем плеере. H5P занимает удобную середину: сам генерирует xAPI-утверждения, но для пересылки в LRS полагается на вашу платформу (например, Moodle). Выбрать плеер, который отдаёт метрики качества воспроизведения, когда нужны записи об обучении, – одна из самых дорогих ошибок в этой области, и заметна она только в день интеграции.

Рисунок 4. Решение «строить или купить». Сначала исключите разработку движка воспроизведения, затем выбирайте ветку в зависимости от того, важны ли для продукта собственные интеракции и нативный xAPI-трекинг. Большинство обучающих продуктов расширяют open-source-фреймворк и строят слой интеракций.

Частая ошибка: путать «плеер» со «слоем интеракций»

Больше всего денег теряют, когда считают «сделать видеоплеер» одним неделимым решением. Тогда команды либо делают лишнее – заново создают воспроизведение, стриминг и DRM, которые Video.js и Shaka дают бесплатно, – либо переплачивают вендору за полную платформу, когда нужен был только слой интеракций на бесплатной основе. Вопрос нужно каждый раз делить на два. Воспроизведение – типовой, давно решённый слой, его берут у браузера или из библиотеки. Слой интеракций (оверлеи, хранилище, xAPI-мост) – то место, где ценность продукта и куда должен идти бюджет разработки. Скажите на планировании прямо: «мы делаем не плеер, а слой интерактива поверх него» – и ответ на «строить или купить» обычно становится очевидным.

Родственная ошибка – выбирать плеер до проверки трекинга. Инженеры берут библиотеку с самым приятным API или самыми гладкими контролами, два месяца разрабатывают, а на интеграции выясняют, что она отдаёт метрики качества стриминга, а не xAPI-записи, и LMS ничего не может прочитать. Сначала определите стандарт трекинга, потом выбирайте плеер с его поддержкой или сознательно закладывайте разработку моста.

Где здесь Фора Софт

Мы разрабатываем обучающие видеопродукты на заказ, и именно с интерактивным плеером чаще всего помогаем клиентам провести границу «строить или купить». Схема, которую мы рекомендуем почти всегда: не переписывать воспроизведение, а расширять проверенный open-source-фреймворк вроде Video.js (вместе с Shaka, если важны адаптивный стриминг и DRM), а бюджет разработки вкладывать в слой оверлеев, хранилище интеракций и xAPI-мост с LRS в российском контуре. Именно эти слои делают продукт вашим и измеримым. Мы работаем с видеоконференциями, стримингом, OTT и e-learning с 2005 года, и вывод повторяется из проекта в проект: плеер – в основном типовой компонент, а отличие продукта – в интерактиве и измеримости, поэтому тщательная инженерия окупается именно там. Проект мы рассчитываем так, чтобы типовые слои оставались дешёвыми, а ценный слой получал нужное внимание.

Ключевые выводы

  • Воспроизведение не пишут с нуля: берут проверенную библиотеку и строят над ней только слой интеракций.
  • Пять слоёв: движок воспроизведения, шина событий, оверлеи, хранилище интеракций, мост трекинга.
  • Поток событий видео и есть архитектура: каждая функция на него подписана.
  • timeupdate – для ползунка, requestVideoFrameCallback – для оверлеев с точностью до кадра.
  • xAPI-мост переводит события плеера в стандартные глаголы; сглаживайте перемотки, считайте реальное завершение.
  • Выберите стандарт трекинга до выбора плеера: видеоплатформы дают аналитику просмотров, а не xAPI; LRS держите в России.

Что почитать дальше

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.