Why Top-Tier Live-Stream Gifts Use VAP Instead of SVGA: A Technical Deep Dive

Compare VAP and SVGA for live-stream gift animations, including transparency, visual complexity, performance, file size, compatibility, and suitable use cases.

The video-based transparent animation format that powers the most visually impressive gift effects — and when you should reach for it over SVGA

In the previous article, we covered SVGA — the vector + bitmap animation format that’s become the workhorse of live-streaming gift effects. A lot of readers asked: “What about those really flashy big gifts — exploding fireworks, particle storms, full-screen light effects? Are those SVGA too?”

The answer: most of them aren’t. They’re VAP.

I’ve spent years leading a design team that builds virtual gift animations for live-streaming and voice-chat products. This post picks up where the SVGA piece left off and walks through VAP — how it works, when to use it, and how to integrate it on Android, iOS, and Web.

Here’s the counterintuitive bit up front: VAP files are several times larger than SVGA, but they actually perform better. Why? Read on.

1. What VAP Is: Where SVGA Hits Its Ceiling, VAP Takes Over

SVGA is a vector + bitmap format — lightweight, cross-platform consistent, and great for most gift animations. But it has a ceiling: frame-by-frame rendering of complex particle effects, light blooms, smoke, and atmospheric effects doesn’t translate well.

Example: a designer builds an exploding-fireworks effect in After Effects — thousands of particles, each with gradients, motion blur, and trails. Exporting that to SVGA means either losing detail (cut the particle count in half, simplify trails to flat colors) or ballooning the file size (store every particle as a bitmap).

VAP was built to break through that ceiling. The core idea is simple: if these effects are essentially frame-by-frame video anyway, just use a video container with an alpha channel for transparency.

Tencent’s eSports division open-sourced VAP in 2019 (GitHub: Tencent/vap). It’s now used by Kuaishou, Huya, Douyu, and other major live-streaming platforms for their top-tier gift effects. One-sentence positioning: more visually stunning than SVGA (video-grade fidelity), more efficient than image sequences (hardware decoding), better at complex bitmap effects than Lottie.

2. How It Works: What’s Inside a .mp4 File

A VAP file is a standard MP4 container holding two parts:

  1. RGB video stream: The normal color frames — the gift animation itself.

  2. Alpha channel: A grayscale video recording transparency for each pixel (white = opaque, black = fully transparent).

These can be packaged two ways:

Approach A: Side-by-Side Dual Channel

RGB and alpha are stitched horizontally into one video frame. For instance, a 750×1334 effect becomes a 1500×1334 video (left half RGB, right half alpha). The player splits and composites them at runtime.

Approach B: Separate Alpha Track

The MP4 container supports multiple tracks, so the alpha lives as a separate video track. This is structurally cleaner but slightly more complex to parse.

Tencent’s official recommendation is Approach A (side-by-side) — best compatibility, and both the Android and iOS SDKs assume this layout.

Why does a larger file perform better? Because VAP relies on hardware video decoders (Android’s MediaCodec, iOS’s AVFoundation) — the GPU handles it directly, and the CPU is barely touched. SVGA, by contrast, runs on the CPU (Protobuf parsing + Canvas rendering). For complex animations, SVGA can peg the CPU while VAP cruises on the GPU. That’s why VAP can handle full-screen, high-framerate effects that would stutter with SVGA.

3. From Design File to .mp4: Export Settings Set the Performance Ceiling

A pattern emerges after you’ve shipped a few gift-animation systems: whether it stutters or overheats in production is 80% determined at export time. VAP uses a video container, but the same rules apply — resolution, frame rate, bitrate, and duration directly control file size and decode load.

3.1 Resolution: Go Small When You Can

Video resolution scales file size dramatically. Common breakpoints:

  • Small gifts (1/4 screen): 540×960 or smaller

  • Medium gifts (1/2 screen): 750×1334

  • Full-screen big gifts: 1080×1920 max

Don’t export at 2K “just in case someone views it on an iPad.” In practice, gift animations appear for 2–3 seconds on a phone screen — users don’t scrutinize pixel-level detail. Clear enough is enough.

3.2 Frame Rate: 24fps Is the Sweet Spot

  • 24fps: Cinema standard, smooth enough, smallest file

  • 30fps: Slightly smoother, 25% larger

  • 60fps: Wasteful unless targeting flagship devices exclusively — low-end phones can’t decode it, and users won’t notice the difference

Diminishing returns kick in hard above 30fps. 24fps is the gold standard for live-stream gifts.

3.3 Duration: 2–4 Seconds Is the Sweet Zone

Gift animations don’t need to run their full length — too long disrupts the broadcast rhythm. Typical durations:

  • Small gifts: 1.5–2 seconds

  • Medium/large gifts: 2–3 seconds

  • Top-tier (carnival, rocket): 3–4 seconds max

Trim duration aggressively — it cuts file size fast.

3.4 Bitrate & Encoding: H.264 Is the Safe Choice

VAP recommends H.264 encoding (best hardware decode support across Android / iOS). Bitrate guidelines:

  • 540p: 1–2 Mbps

  • 750p: 2–3 Mbps

  • 1080p: 3–5 Mbps

Enable two-pass encoding + CRF quality control to balance quality and size.

3.5 Export Pipeline

After finishing the effect in AE:

  1. Export an alpha-embedded video sequence (PNG sequence or ProRes 4444)

  2. Composite with VapTool or FFmpeg:

  • Adobe Media Encoder can export side-by-side RGB+Alpha directly

  • Or use Tencent’s VapTool (JSON config specifies alpha channel layout)

Collaboration checkpoint: Design and engineering must agree on resolution / frame rate / duration caps upfront. Otherwise the designer exports a 1080p 60fps 5-second file, the engineer discovers low-end devices can’t decode it, and everyone reworks the asset. A mature workflow attaches an export parameter sheet (resolution / frame rate / duration / file size) to every gift-animation delivery — this convention emerged from painful experience.

4. Integration: Android / iOS / Web

VAP integration is slightly heavier than SVGA (you’re invoking video decoders), but Tencent’s official SDKs wrap it cleanly. The pattern is still load → configure → play.

4.1 Android

Dependencies

dependencies {
    implementation 'com.tencent.vap:animplayer:2.0.20'
}

Layout

VAP renders to a TextureView or SurfaceView:

<com.tencent.qgame.animplayer.AnimView
    android:id="@+id/vap_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Playback

val vapView = findViewById<AnimView>(R.id.vap_view)
// Play from local file
vapView.startPlay(File(context.filesDir, "gifts/rocket.mp4"))// For remote URLs: download first, then play
val file = File(context.cacheDir, "rocket.mp4")
// ... download logic
vapView.startPlay(file)// Listen for completion
vapView.setAnimListener(object : IAnimListener {
    override fun onVideoComplete() {
        Log.d("VAP", "Playback complete")
    }
    override fun onVideoDestroy() {
        Log.d("VAP", "Resources released")
    }
})

Key point: The Android SDK does not accept URLs directly — you must download the .mp4 to local storage first. Preloading is essential (covered in the performance section).

4.2 iOS

Dependencies (CocoaPods)

pod 'VAP', '~> 2.3.0'

Playback

import VAP
let vapView = QGVAPWrapView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
view.addSubview(vapView)// Play from local file
if let path = Bundle.main.path(forResource: "rocket", ofType: "mp4") {
    vapView.playHWD(filePath: path) { _, error in
        if let error = error {
            print("VAP playback failed: \(error)")
        } else {
            print("VAP playback complete")
        }
    }
}// Play from remote URL (SDK caches internally)
vapView.playHWD(urlStr: "https://your-cdn.com/gifts/rocket.mp4") { _, error in
    // Completion callback
}

The iOS SDK is friendlier than Android’s — it accepts URLs directly and handles caching internally.

4.3 Web (Third-Party Solutions)

Tencent did not release an official Web SDK. Community implementations exist:

  • vap-web (canvas + video element, manual alpha compositing)

  • Roll your own: use a <video> element for RGB, read frames via canvas, apply an alpha mask

In practice, Web VAP support is brittle — manual alpha compositing, inconsistent performance, compatibility headaches. Many teams use SVGA or Lottie on Web and reserve VAP for iOS / Android only.

If you must support Web, the approach looks like:

// Pseudocode
const video = document.createElement('video');
video.src = 'rocket.mp4';
const canvas = document.getElementById('gift-canvas');
const ctx = canvas.getContext('2d');
video.addEventListener('play', () => {
  function drawFrame() {
    ctx.drawImage(video, 0, 0, canvas.width / 2, canvas.height); // RGB left half
    // Read right half for alpha, manually composite transparency
    // ...
    if (!video.paused && !video.ended) {
      requestAnimationFrame(drawFrame);
    }
  }
  drawFrame();
});
video.play();

Honest take: Web VAP has a poor ROI. If your product is mobile-first, skip VAP on Web.

5. Dynamic Fusion: Inject User Avatars and Nicknames

Like SVGA, VAP supports dynamic element replacement — embedding user avatars, nicknames, and custom text at runtime. This is what separates virtual gifts from plain videos: every playback can be personalized.

How It Works

The designer tags specific layers in AE (e.g., name the avatar layer user_avatar, the text layer user_name). At export time, these tags are written to VAP metadata (JSON config). At playback, you pass replacement data and the SDK composites it in.

Android Dynamic Fusion

val source = VapxAnimSource(context, "gifts/rocket.mp4")
source.replacements = listOf(
    VapxReplacement().apply {
        tag = "user_avatar"  // Matches AE layer name
        bitmap = userAvatarBitmap
    },
    VapxReplacement().apply {
        tag = "user_name"
        text = "Alice sent a rocket"
        textColor = Color.WHITE
        textSize = 28f
    }
)vapView.startPlay(source)

iOS Dynamic Fusion

let source = QGVAPSourceInfo()
source.filePath = Bundle.main.path(forResource: "rocket", ofType: "mp4")
let avatarItem = QGVAPImageInfo()
avatarItem.tag = "user_avatar"
avatarItem.image = userAvatarUIImagelet nameItem = QGVAPTextInfo()
nameItem.tag = "user_name"
nameItem.text = "Bob sent a rocket"
nameItem.color = UIColor.white
nameItem.fontSize = 28source.images = [avatarItem]
source.texts = [nameItem]vapView.play(with: source)

Collaboration checkpoint: The tag must match the AE layer name exactly. Establish a layer-naming convention with your designer upfront — otherwise engineers won’t know which layer to target, and production builds will ship with broken replacements.

6. VAP vs SVGA: When to Choose Which

SVGA and VAP are the two dominant formats for live-stream gift animations. People often ask “which should I use?” The answer isn’t either/or — it’s tier your gifts by type and budget:

DimensionSVGAVAPHow it worksVector + bitmap, Flash-likeVideo container + alpha channelFile sizeSmall (tens to hundreds of KB)Large (hundreds of KB to several MB)FidelityHigh for simple animations, compromised for complex particles/lightingVideo-grade fidelity, perfect for frame-by-frame effectsPerformanceCPU parsing + Canvas renderingGPU hardware decode, low CPU usageCross-platformExcellent (Web/iOS/Android consistent)iOS/Android solid, Web requires custom implementationDynamic fusionSupported (avatar, nickname replacement)Supported (same capabilities)Use casesSmall/medium gifts, standard animationsBig gifts, particles/lighting/smokeProduction costMedium (requires layer standardization)High (video export + alpha processing)

Selection guide:

  • Small gifts ($1–10): SVGA — smaller files, faster load, Web-friendly

  • Medium gifts ($10–100): SVGA by default, VAP for complex effects

  • Big gifts ($100+): VAP — visual impact is the top priority

  • Web-first products: SVGA — VAP Web support is weak

In practice, many teams mix both: standard gifts use SVGA (saves bandwidth, Web compatibility), top-tier gifts use VAP (flashy, ceremonial).

7. Performance Optimization: What Matters Under Real Load

Complex VAP animation example

20260904161202_a18e42.png

The flashier the effect, the larger the file and the more critical performance optimization becomes

VAP files are large and decode-intensive. Performance problems tend to erupt on low-end devices and under high concurrency (gift combos, full-screen broadcasts). These techniques pay off in practice.

7.1 Asset-Level Optimization (Highest ROI)

Covered in the export section — worth repeating: control resolution, frame rate, duration, keep files under 2MB. Every KB saved at export is real decode overhead and memory savings at runtime. Get this right and many code-level issues never appear.

7.2 Preloading & Caching

Gifts in a live stream are predictable (the gift panel lists a few dozen options), so don’t wait until the user taps to download. Common pattern:

When entering a room, pre-download high-frequency gifts to local cache. At playback time, check cache first, fall back to network. Android can use OkHttp caching or a custom file cache; iOS the same. This eliminates the “gift lags for a second before appearing” delay.

Note: VAP files are larger than SVGA — preloading everything isn’t realistic. Tier by popularity: always preload high-frequency gifts, fetch low-frequency ones on demand.

7.3 Hardware Decoding Is the Performance Key

VAP’s performance advantage comes from GPU hardware decoding. But if the encoding format is wrong (e.g., H.265 or a non-mainstream profile), some low-end devices fall back to software decoding and performance collapses.

Safe defaults: — Use H.264 Baseline Profile (best compatibility) — Don’t exceed device capability ceilings (1080p 60fps stresses hardware decode even on decent phones)

7.4 Playback Queues & Throttling

A live stream might receive multiple gifts simultaneously (combos, multiple senders). Playing all of them at once creates visual chaos and tanks performance. Common strategies:

  • Queue mechanism: Gifts enter a queue, play sequentially

  • Merge combos: Same user sends multiple copies of the same gift in quick succession → play once, display «×N»

  • Priority: High-value gifts jump the queue, low-value gifts can be delayed or skipped

Pseudocode:

val giftQueue = LinkedList<GiftItem>()
fun onGiftReceived(gift: GiftItem) {
    giftQueue.add(gift)
    if (!isPlaying) {
        playNext()
    }
}fun playNext() {
    if (giftQueue.isEmpty()) {
        isPlaying = false
        return
    }
    val gift = giftQueue.poll()
    vapView.startPlay(gift.file)
    vapView.setAnimListener(object : IAnimListener {
        override fun onVideoComplete() {
            playNext()
        }
    })
    isPlaying = true
}

7.5 Memory Management: Release Immediately After Playback

VAP decodes video frames into memory. If you don’t release after playback, memory blows up after a few big gifts.

Android:

vapView.stopPlay()

iOS:

vapView.stopPlay()
vapView.removeFromSuperview()

Trigger points: Gift finishes, user leaves the room, app backgrounds — all should trigger VAP resource cleanup.

8. Common Issues & Quick Fixes

ProblemCauseSolutionTransparency lost / opaque backgroundAlpha channel not properly packaged, or player parsing misalignedCheck alpha channel layout in export config; validate file with VapToolAndroid white screen / crashWrong file format, or low-end device doesn’t support hardware decodeConfirm H.264 Baseline encoding; check if resolution exceeds device capabilityDynamic replacement not workingLayer tag mismatchConfirm AE layer naming with designer; tags must match code exactlyiOS playback stuttersFile too large or frame rate too highReduce resolution / frame rate; enable preloadingWeb playback failsNo official Web SDKUse SVGA or Lottie instead, or implement vap-web custom solutionMemory keeps climbingResources not released after playbackVerify stopPlay is called; ensure cleanup on scene exitFile size too largeResolution / frame rate / duration unconstrainedFollow export guidelines in Section 3, compress to under 2MB

Closing Thoughts

Integrating VAP isn’t hard — Tencent’s Android and iOS SDKs are mature and well-documented. What really decides whether a gift animation is stunning and performant is the stretch from design to export: resolution, frame rate, duration, encoding format. Those choices set the performance ceiling before a single line of code is written.

My team builds virtual gift animations for live-streaming and voice-chat products full time — from AE design and VAP/SVGA export standards to cross-platform integration, we’ve hit most of the potholes and distilled them into an asset spec and a library of reusable animation templates. If you’re working in this space and want to trade notes, drop a comment or reach out via our shop.

If this saved you a headache, a clap or a follow means a lot. I’ll be breaking down PAG (ByteDance’s open-source format) next, plus a side-by-side comparison of SVGA / VAP / PAG for different use cases.

Last updated: