A Kotlin Multiplatform reimplementation of Tencent's VAP (Video Animation Player), targeting Android and Desktop (JVM) with a Compose Multiplatform playback API and a Compose Desktop authoring tool.
VAP is a video container with a transparent alpha channel, designed to play short, richly animated
effects with hardware-accelerated decoding. Tencent's original implementation is Android-only; this
project ports the format to a KMP-friendly stack and adds a Compose-based playback layer with a
clean load → drive → render API.
The VAP container layout and the encode / decode pipeline are based on the design of Tencent's VAP (Video Animation Player).
| Module | Role | Coordinate |
|---|---|---|
vap-core |
models / VapSource |
com.zxhhyj:vap-core |
vap-decode |
vapc parsing (VapcParser) |
com.zxhhyj:vap-decode |
vap-encode |
PNG → VAP authoring pipeline (KMP) | com.zxhhyj:vap-encode |
vap-compose |
Compose VapAnimation; Android GLES; Desktop FFmpeg |
com.zxhhyj:vap-compose |
example-vap-shared |
Demo UI | no |
example-vap-android |
Android host | no |
example-vap-desktop |
Desktop host | no |
example-vap-tool |
Compose Desktop authoring tool | no |
implementation("com.zxhhyj:vap-core:<version>")
implementation("com.zxhhyj:vap-decode:<version>")
implementation("com.zxhhyj:vap-encode:<version>")
implementation("com.zxhhyj:vap-compose:<version>")Three layers: load → drive (decode session) → render. To survive page transitions, mount
the composition and state above the disposable subtree and only toggle isPlaying.
// Sync load (local / preload). Or async: rememberVapComposition(...)
val composition = remember(pathToMp4) {
loadVapComposition(VapCompositionSpec.File(pathToMp4))
}
val anim = animateVapCompositionAsState(
composition,
iterations = VapConstants.IterateForever,
isPlaying = pageVisible,
)
VapAnimation(anim, modifier = Modifier.fillMaxWidth().height(320.dp))The state is bound to the composable's subtree lifetime. Do not use this when you need keep-alive across page switches.
val composition by rememberVapComposition(VapCompositionSpec.File(pathToMp4))
VapAnimation(
composition = composition,
iterations = VapConstants.IterateForever,
modifier = Modifier.fillMaxWidth().height(320.dp),
)./gradlew :example-vap-android:assembleDebug
./gradlew :example-vap-desktop:run
./gradlew :example-vap-tool:run
./gradlew printPublishableModulesThe authoring tool needs a local ffmpeg.
This project is licensed under the MIT License.