Видеоресурсы и воспроизведение
Документация, принадлежащая движку. В этом руководстве описаны привязанный к ревизии декодер Ogg/Theora и примитивы показа из
cvet/fonline. Игра отвечает за каталог роликов, триггеры, получателей, правила пропуска, субтитры, локализацию, последствия для сохранения, мастеринг, происхождение ресурсов и визуальные приёмочные тесты.
Точные стабильные идентификаторы контракта, проверенные привязки к исходникам и машиночитаемые значения приведены в сгенерированном справочнике video.
Статус контракта
Штатный видеотракт имеет статус experimental. Он подходит для управляемой интеграции в проект, но пока не является версионированной production-медиасистемой:
- реализация распознаёт только контейнер Ogg с видео Theora;
- перед декодированием сжатый ресурс целиком загружается в память;
- декодирование и преобразование YCbCr в RGBA выполняются на CPU клиента;
- аудиодорожка контейнера Ogg не декодируется;
- нет сфокусированного нативного теста декодера, рендеринга, очереди или цикла;
- нет встроенного слоя субтитров, доступности, вписывания по пропорциям, потоковой загрузки или состояния кинематографической сцены.
Фиксируйте точную ревизию Engine и повторяйте визуальные приёмочные тесты при любом изменении декодера, рендеринга, ресурсов, ввода или аудиотракта.
Карта исходников
Source/Client/VideoClip.*отвечает за приём пакетов Ogg, настройку Theora, тайминг кадров, преобразование пикселей, состояния остановки/паузы и флаг зацикливания.Source/Client/Client.*отвечает за полноэкранное воспроизведение, очередь, прерывание вводом, отдельную музыку, порядок рисования и состояние.Source/Scripting/ClientGlobalScriptMethods.cppэкспортирует методы полноэкранного и управляемого скриптом воспроизведения.Source/Client/SpriteManager.cppопределяет поведение целевого прямоугольника, используемое при рисовании видео.Source/Common/Settings.incобъявляет.ogvрасширением для raw copy.Source/Tools/RawCopyBaker.*доставляет авторские байты без транскодирования.BuildTools/cmake/stages/ThirdParty.cmakeподключает Ogg и Theora к клиентским целям.BuildTools/VideoInterface.jsonявляется проверяемым контрактом документации.
Доставка видео
Отдельного video baker нет. В стандартном Baking.RawCopyFileExtensions уже
есть ogv; встраиваемый проект также должен включить RawCopy в видимый
клиенту ресурсный пакет, которому принадлежат файлы. Рекомендуется отдельный
клиентский видеопакет, чтобы состав payload сервера и mapper оставался явным.
Обе поверхности воспроизведения используют точные пути ресурсов:
Game.PlayVideo("Video/Intro.ogv", true, false);
VideoPlayback video = Game.CreateVideoPlayback("Video/Terminal.ogv", false);
Указывайте суффикс .ogv. Нет ни расширения по умолчанию, ни нормализованного
индекса основ имени видео, ни языкового fallback, ни поиска по файловой
системе. На регистрозависимых платформах написание пути и регистр должны точно
совпадать с доставленным ресурсом.
Наличие ogv в RawCopyFileExtensions только разрешает копирование. Оно не
выбирает ресурсный пакет, не доказывает получение файла клиентом и не проверяет
контейнер или кодек.
Требования к подготовке ресурсов
Подготовьте ресурс Ogg с корректным потоком Theora. Декодеру нужны допустимые размеры изображения, числитель и знаменатель частоты кадров, setup-заголовки и один из следующих пиксельных форматов Theora:
TH_PF_420;TH_PF_422;TH_PF_444.
Engine не запускает инструмент подготовки ресурсов. Обычная отправная точка для ролика без звука:
ffmpeg -i input.mov -an -c:v libtheora output.ogv
Это пример авторинга, а не доказательство совместимости. Проверьте полученный поток, запеките его точные байты и запустите на каждом поддерживаемом клиенте. Размеры и частоту кадров выбирайте по измеренным бюджетам платформы. Не предполагайте, что другой кодек в контейнере Ogg будет работать.
Видеотракт не декодирует звук из контейнера. Экспортируйте звук отдельно в формате из руководства «Аудиоресурсы и воспроизведение». Встроенный полноэкранный тракт может запустить один отдельный музыкальный ресурс, но не обеспечивает поточечную синхронизацию, альтернативные дорожки, приглушение под диалог или выбор языка.
Память и производительность
Resources.ReadFile(...).GetData() переносит весь сжатый файл в VideoClip.
Реализация не выполняет потоковое чтение с диска, из хранилища пакета или сети.
Каждое активное воспроизведение также владеет:
- CPU-буфером одного непрозрачного RGBA-кадра;
- состоянием декодера Ogg/Theora;
- GPU-текстурой размером с закодированное изображение.
Для каждого одновременно воспроизводимого ролика закладывайте как минимум
compressed file size + width * height * 4 байт CPU-памяти, а также GPU-текстуру
и накладные расходы декодера. Встроенные экземпляры хранят собственную копию и
текстуру. Не предзагружайте множество длинных роликов созданием бездействующих
объектов VideoPlayback.
Данные Ogg подаются парсеру из резидентного буфера порциями по 1024 байта. Это деталь реализации, а не потоковая доставка ресурса. Выбор кадра использует монотонные часы и закодированное отношение частоты кадров; при отставании один вызов рисования может декодировать несколько пакетов до загрузки кадра. Профилируйте CPU-преобразование и загрузку текстуры на самой слабой поддерживаемой платформе.
Полноэкранное воспроизведение
Вызовите:
Game.PlayVideo(videoName, canInterrupt, enqueue);
bool pending = Game.IsVideoPlaying();
Метод не возвращает признак успеха. При отсутствии файла активного воспроизведения не будет, а текущая реализация не выдаёт отдельной диагностики об отсутствующем видео на этом пути. Проверяйте ресурсы до перехода, который зависит от завершения ролика.
Game.IsVideoPlaying() возвращает true, когда активен ролик или не пуста
полноэкранная очередь. Это не доказывает, что кадр сейчас виден.
Очередь и замена
При enqueue = false метод Game.PlayVideo уничтожает текущий ролик, очищает
всю очередь и только затем пытается загрузить запрошенный файл. Поэтому пустая
строка выполняет полноэкранную остановку с очисткой очереди.
При enqueue = true и активном ролике запрос добавляется в конец. Если ролика
нет, тот же запрос запускается сразу и не создаёт состояние ожидания без
воспроизведения. Элементы очереди стартуют последовательно после остановки
предыдущего ролика. Проверьте отсутствующий элемент очереди: ошибка загрузки
может продвинуть очередь без показа кадра.
Прерывание
При canInterrupt = true текущий ролик останавливается по событиям:
- key-down;
- mouse-down;
- touch down, move, up, tap, double-tap, scroll или zoom.
Это широкий транспортный примитив, а не готовая политика пропуска. Если игре нужны удержание для пропуска, защищённый начальный интервал, подтверждение, подавление дребезга ввода или обязательное сюжетное состояние, реализуйте это вокруг собственного контроллера роликов.
Отдельная музыка
Полноэкранная строка принимает один необязательный путь музыки после |:
Game.PlayVideo("Video/Intro.ogv|Sound/Intro.ogg", true, false);
Engine загружает первый компонент как видео, а второй использует как
однократно воспроизводимую музыку. Дополнительные разделители не образуют
плейлист. Запуск связанного запроса сначала останавливает текущую музыку.
Завершение или прерывание любого полноэкранного ролика также безусловно
вызывает StopMusic(), даже если этот ролик не запускал связанную музыку.
Не основывайте восстановление важной для игрового процесса музыки на предположении, что видеотракт сохраняет предыдущую музыкальную группу. Проектный контроллер должен явно записывать и восстанавливать требуемое состояние.
Рисование и пропорции
Полноэкранные кадры загружаются и рисуются после Game.OnRenderIface.
Рисование без исходной и целевой областей заполняет всю текущую цель рендеринга
с отключённым alpha blending. Если пропорции закодированного изображения и
цели отличаются, изображение растягивается.
Во встроенном тракте нет letterbox, pillarbox, safe area, crop, субтитров, оверлеев или политики переходов. Когда это важно, используйте проектное встроенное представление.
Встроенное воспроизведение
Создайте управляемый скриптом экземпляр:
VideoPlayback video = Game.CreateVideoPlayback("Video/Terminal.ogv", false);
В отличие от полноэкранного воспроизведения, отсутствующий ресурс выбрасывает
Video file not found. Возвращаемый объект с подсчётом ссылок владеет
независимым состоянием декодера и текстурой.
Рисуйте его только во время Game.OnRenderIface:
void RenderTerminalVideo()
{
Game.DrawVideoPlayback(video, ipos(120, 80), isize(640, 360));
}
Точный синтаксис подписки на событие принадлежит встраиваемому скриптовому модулю. Ширина и высота цели должны быть положительными. Неположительный размер пропускает декодирование кадра, загрузку и рисование, поэтому скрытый экземпляр через этот API не продвигается.
Engine рисует точно заданный прямоугольник и не сохраняет пропорции. Вписывание, обрезку, полосы, safe area и адаптивную раскладку вычисляйте в проектном UI-коде. Передача null или экземпляра с освобождёнными ресурсами ничего не делает.
VideoPlayback.Stopped становится true, только когда следующий вызов
Game.DrawVideoPlayback обнаружит остановившийся ролик, очистит его ресурсы и
обновит поле. Продолжайте рисовать или опрашивать через контроллер, пока этот
переход очистки не произойдёт.
Зацикливание
Game.CreateVideoPlayback(path, true) открывает флаг loop в VideoClip. В
конце потока текущий исходник вызывает Stop(), затем Resume(), но нет
сфокусированного теста, который доказывал бы перемотку декодера, сброс состояния
пакетов и счётчика кадров или непрерывный вывод нескольких циклов.
Считайте зацикливание экспериментальным даже внутри этой экспериментальной подсистемы. Не обещайте production ambient loop, пока визуальный тест не пройдёт несколько циклов точного ресурса на каждой заявленной платформе. Если непрерывность важна, предусмотрите явный проектный fallback.
Диагностика
При создании и декодировании кадров возможны следующие ошибки:
- ошибка поиска пакета или декодирования заголовка Theora;
- отсутствие setup-данных или ошибка выделения декодера;
- повреждённые данные закодированного кадра;
- ошибка выдачи цветового буфера;
- неподдерживаемый пиксельный формат Theora.
Проверяйте клиентский лог около первой попытки показать кадр. Для отсутствующих полноэкранных файлов отдельно проверяйте запечённые ресурсы, поскольку этот поиск сейчас завершается без сообщения. Успешный конструктор всё ещё не доказывает устойчивый рендеринг, правильные пропорции, синхронный звук, очистку или непрерывность цикла.
Процесс проверки
Запустите проверки документационного контракта по исходникам:
python BuildTools\docs_video.py --check
python -m unittest BuildTools.tests.test_docs_video
python BuildTools\docs_validate.py
Затем проверьте каждый репрезентативный ресурс в видимом клиенте:
- Запеките и подтвердите точный путь клиентского ресурса и идентичность байтов.
- Покажите первый кадр и устойчивое движение в целевом разрешении.
- Дождитесь естественного завершения и проверьте очистку ресурсов.
- Проверьте каждый разрешённый ввод прерывания и проектную политику пропуска.
- Проверьте замену, несколько элементов очереди и заведомо отсутствующий путь.
- Проверьте изменение размера цели, пропорции, safe area, оверлеи и субтитры.
- Проверьте запуск, остановку и восстановление отдельной музыки и допустимый drift.
- Профилируйте память, CPU-декодирование/преобразование, frame pacing и загрузку текстуры.
- Для loop-воспроизведения наблюдайте несколько полных циклов.
- Повторите на каждой native, Web, Android и mapper-платформе, заявленной проектом.
Сейчас нет сфокусированного нативного video fixture. Проверки по исходникам поддерживают честность документации, но не заменяют видимые игроку доказательства.
Граница проекта
Engine отвечает за:
- загрузку клиентского ресурса по точному пути;
- декодирование пакетов и кадров Ogg/Theora;
- CPU-преобразование RGBA и загрузку текстуры;
- полноэкранную замену, очередь, прерывание и связь с отдельной музыкой;
- создание управляемого скриптом воспроизведения и рисование прямоугольника интерфейса.
Встраиваемая игра отвечает за:
- ресурсный видеопакет и каталог ресурсов;
- триггеры роликов, получателей, authority и правила повторного просмотра;
- политику пропуска/очереди и последствия для сохранения;
- субтитры, локализацию, доступность, пропорции, safe area и оверлеи;
- стратегию музыки/голоса и восстановление;
- исходные ресурсы, лицензии, атрибуцию и provenance;
- бюджеты файлов, памяти, CPU, GPU, пакета и загрузки;
- визуальные приёмочные тесты и заявления о поддержке платформ.
Проектная документация может ссылаться сюда за механикой Engine. Она должна описывать собственную интеграцию, а не считать скрипты или ресурсы другой игры контрактом движка.
Сопровождение
При изменении поведения видео:
- обновите
BuildTools/VideoInterface.jsonи его привязки к исходникам; - выполните
python BuildTools/docs_video.py --write; - обновите это руководство, если изменился смысл авторинга или эксплуатации;
- добавьте или обновите сфокусированные нативные тесты, когда декодер станет тестируемым;
- выполните diff документационного контракта и disposition workflow;
- потребуйте от встраиваемых проектов повторить визуальную приёмку затронутых ресурсов и целей.
Сгенерированный справочник является машиночитаемым доказательством для текущей ревизии, но не заменяет политику совместимости или production-тесты медиа.