Video Playback¶
VideoPlayer provides full-window MP4 playback through AppContext. It is
intended for intro movies, cutscenes, and other video that temporarily overlays
the rendered game.
The API is available when SNOWPULSE_HAS_VIDEO is enabled. Actual playback is
controlled by the SNOWPULSE_ENABLE_MP4_VIDEO CMake option, which defaults to
ON. The PLAYABLE_AD web profile removes the video API entirely.
Platform Support¶
| Platform | Backend | Status |
|---|---|---|
| macOS desktop | AVFoundation (AVPlayer) |
Supported |
| Windows desktop | No encoder/player backend | Unavailable |
| Web | Browser <video> overlay |
Supported |
| iOS | AVFoundation (AVPlayer) |
Supported |
| Android | Media3 ExoPlayer asset:/// overlay |
Supported |
Videos are resolved relative to AppContext::assetRoot() unless the supplied
path is already absolute. Apple native backends require a local file. Android
requires a valid packaged-asset path and passes an asset:/// URI to Media3. Web playback
first checks Emscripten's virtual filesystem and creates an MP4 object URL when
the file is mounted; otherwise it treats the path as a browser URL.
Playback Lifecycle¶
#if SNOWPULSE_HAS_VIDEO
auto* video = context()->videoPlayer();
if (video && video->load("video/intro.mp4")) {
// load() is asynchronous. Wait for ReadyPaused before playing.
}
// In scene update:
if (video && video->state() == snowpulse::VideoPlaybackState::ReadyPaused) {
video->play();
}
#endif
VideoPlaybackState has these values:
Unavailable: no loaded video or no platform backend.Loading: the backend is preparing the asset.ReadyPaused: the first frame is ready and playback may begin.Playing: playback is active.Ended: playback reached the end.Failed: loading or playback failed.
App calls VideoPlayer::update() once per active frame, so game code normally
only needs to poll state(). play() and pause() return false when the
current state does not allow the requested transition. stop() removes the
overlay and returns to Unavailable.
Use setVisible(false) to hide the video overlay without stopping playback.
The native overlays do not consume pointer input. On web, the overlay handles a
tap while ReadyPaused so mobile browsers can satisfy their user-activation
requirement and retry a play() rejected by autoplay policy.
Android Media3 work runs on the Activity main thread. Pause and destruction release or suspend the player without callbacks reaching destroyed C++ state; the overlay has no controls and sits above the GLES surface.
Portal Pause Behavior¶
When Playgama or YouTube reports a portal pause, App pauses a playing video.
It resumes the video only if the portal was responsible for pausing it. A video
that game code had already paused remains paused.
Build Configuration¶
Disable MP4 playback for builds that do not use it:
This leaves VideoPlayer present in a full-profile build, but operations report
Unavailable. In PLAYABLE_AD, SNOWPULSE_HAS_VIDEO=0, so the service and
umbrella include are compile-time gated.