Различные статьи по Qt и c++

Видео и анимированные изображения внутри справки: вставка медиаконтента в HTML

Введение

Текстовые описания сложных, многошаговых интерфейсных операций (например, настройка сложного фильтра в графическом редакторе) часто менее понятны, чем короткое видео или анимированный GIF, показывающий процесс наглядно. В статье рассмотрим, как встраивать видео и анимации в HTML-страницы справки, и какие ограничения накладывает выбор между QTextBrowser и QWebEngineView как движком отображения контента.

Концепция

QTextBrowser, основанный на ограниченном подмножестве HTML/CSS (статья 165), не поддерживает тег <video> и воспроизведение видео вообще — он способен отображать только статичные изображения, включая анимированные GIF (которые он действительно умеет проигрывать, поскольку анимация GIF реализована на уровне формата изображения, а не через видео-теги). Для настоящего видео внутри встроенной справки нужен QWebEngineView, который поддерживает HTML5 <video> через тот же движок Chromium, что используется и для остальной отрисовки страниц.

Пример кода: Видео и анимированные

<!-- documents.html — страница справки с анимированным GIF, работающим даже в QTextBrowser -->
<h2 id="filter-setup">Настройка фильтра изображения</h2>
<p>
    Следующая анимация показывает процесс настройки фильтра размытия шаг за шагом:
</p>
<img src="qthelp://com.mycompany.myapp.1.0/doc/images/filter_demo.gif"
     alt="Демонстрация настройки фильтра"
     width="480" />
<p>
    Если анимация выше не отображается, ознакомьтесь с
    <a href="#filter-setup-text">текстовым описанием</a> того же процесса.
</p>
<!-- Тот же раздел, но с настоящим видео — требует QWebEngineView -->
<h2 id="filter-setup">Настройка фильтра изображения</h2>
<video width="480" controls>
    <source src="qthelp://com.mycompany.myapp.1.0/doc/videos/filter_demo.mp4" type="video/mp4">
    Ваш браузер справки не поддерживает воспроизведение видео.
    Смотрите GIF-версию ниже.
</video>
// Расширение HelpBrowser (из статьи 165) для определения MIME-типа видеофайлов
QVariant HelpBrowser::loadResource(int type, const QUrl &url)
{
    if (url.scheme() == "qthelp") {
        return QVariant(m_helpEngine->fileData(url));
    }
    return QTextBrowser::loadResource(type, url);
}

// Для QWebEngineView нужно расширить QtHelpUrlSchemeHandler (статья 172)
// корректным определением MIME-типа на основе расширения файла
QString detectMimeType(const QString &path)
{
    if (path.endsWith(".mp4")) return "video/mp4";
    if (path.endsWith(".webm")) return "video/webm";
    if (path.endsWith(".gif")) return "image/gif";
    if (path.endsWith(".png")) return "image/png";
    return "text/html";
}
<!-- Добавление медиафайлов в .qhp -->
<files>
    <file>source/documents.html</file>
    <file>images/filter_demo.gif</file>
    <file>videos/filter_demo.mp4</file>
</files>

Пояснения к коду

Первый вариант HTML использует анимированный GIF — он работает одинаково в QTextBrowser и QWebEngineView, поскольку GIF — это просто формат изображения с встроенной анимацией кадров, не требующий поддержки видео-тегов или JavaScript. Текстовая альтернатива через ссылку #filter-setup-text — хорошая практика на случай, если по какой-то причине анимация не отображается (например, если в будущем справка будет открываться неким третьим инструментом с ограниченной поддержкой изображений).

Второй вариант с настоящим <video> принципиально требует QWebEngineView — detectMimeType() показывает необходимое расширение обработчика схемы qthelp:// (из статьи 172) для возврата корректного MIME-типа видеофайла, без которого браузер не поймёт, как интерпретировать байты, возвращённые из fileData(), и не запустит воспроизведение.

Подводные камни

  • Видеофайлы значительно увеличивают размер .qch и общий объём дистрибутива приложения. В отличие от текста и небольших изображений, видео даже умеренного качества может весить десятки мегабайт — для продуктов с очень компактным базовым дистрибутивом стоит рассмотреть хранение видео отдельно от основного .qch (например, в отдельном ресурсном пакете, подключаемом по требованию, а не встроенном в основной установочный файл).
  • QTextBrowser, не имеющий поддержки <video>, просто молча игнорирует тег без вывода ошибки или текста-заглушки внутри <video>...</video> (текст-заглушка в HTML5-видео показывается только в браузерах, действительно не поддерживающих формат, но интерпретирующих сам тег <video> — QTextBrowser не делает даже этого) — если справка должна одновременно поддерживать оба движка отображения (например, для разных версий приложения), нужно явно проектировать страницы с GIF как основным вариантом и видео — опционально, через JavaScript-определение поддержки, а не полагаться на фоллбэк внутри самого HTML5-тега.
  • Большие GIF-файлы с высоким разрешением и частотой кадров могут весить даже больше, чем сравнимое по длительности видео в современном кодеке (H.264) — для длинных демонстраций (больше 10-15 секунд) настоящее видео почти всегда эффективнее по объёму, чем GIF, и выбор GIF оправдан в первую очередь совместимостью с QTextBrowser, а не эффективностью сжатия.
  • Автовоспроизведение видео (autoplay) внутри справки без явного намерения пользователя может быть навязчивым и неожиданным опытом, особенно если у пользователя включён звук — атрибут controls без autoplay (как в примере) — более уважительный к пользователю выбор по умолчанию, оставляющий запуск воспроизведения на явное действие.