跪拜 Guibai
← All articles
Frontend

Cocos Video Puzzle Now Runs on WeChat Mini Games with a Single Codebase

By 亿元程序员 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

WeChat Mini Games are a massive distribution channel, but video texture access has been a persistent gap because the platform lacks standard DOM APIs and custom native bindings. This approach closes that gap with an official WeChat API, letting a single Cocos project target Web, Android, and WeChat without forking the game logic.

Summary

A video-based puzzle game built in Cocos Creator now runs across Web, Android native, and WeChat Mini Games from a single codebase. The puzzle logic, Board, Piece, and Shader slicing remain untouched across platforms; only the video-to-texture pipeline changes. For WeChat, the approach replaces the browser's video element and Android's custom gfx.Video with wx.createVideoDecoder, which exposes raw RGBA frame data via getFrameData().

The core flow creates a decoder, listens for the start event to get video dimensions and build a Texture2D, then calls uploadData in the update loop. The trickiest part was looping: the decoder fires ended, not stop, when playback finishes, and a bare seek(0) freezes the frame. The fix listens for ended, calls stop() then start() to restart decoding, and uses flags to prevent re-entry and destruction race conditions.

The VideoTexturePlayer component encapsulates all three platform paths behind a single load() API, so GameManager and the puzzle board need no platform-specific code. The complete source is bundled into the author's paid Cocos mini-game collection.

Takeaways
— wx.createVideoDecoder provides getFrameData() to retrieve RGBA pixel data from a video, which can be uploaded directly to a Cocos Texture2D.
— Platform branching uses the MINIGAME macro with higher priority than JSB, so the same VideoTexturePlayer component works across Web, Android native, and WeChat.
— The decoder fires an ended event when playback finishes, not stop; listening for stop and calling seek(0) freezes the video.
— Correct looping requires calling decoder.stop() then decoder.start({ source }) inside the ended handler, with guard flags to prevent re-entry and destruction race conditions.
— The puzzle gameplay code (Board, Piece, Shader) requires zero changes across platforms; only the texture source differs.
— No native plugin is needed for WeChat — just the VideoTexturePlayer script and a wx.d.ts type declaration file.
Conclusions

The ended-vs-stop event mismatch is a sharp API design trap: the decoder's natural completion fires ended, but the intuitive loop point is stop, so a developer following the docs naively writes broken loop logic.

Reusing the same puzzle Shader across three platforms by swapping only the texture source is a clean separation of concerns that many Cocos projects could adopt for any video-driven gameplay, not just puzzles.

The fallback strategy — try stop-then-start first, fall back to seek(0) only on failure — is a defensive pattern worth copying for any stateful media API where restart semantics are unclear.

Concepts & terms
wx.createVideoDecoder
A WeChat Mini Game API that creates a low-level video decoder. It decodes a video file and exposes raw RGBA frame data through getFrameData(), bypassing the limitations of the higher-level VideoPlayer component which cannot provide pixel access.
Texture2D.uploadData
A Cocos Creator method that uploads raw pixel data (such as an ArrayBuffer of RGBA bytes) into a GPU texture, making it available for rendering and Shader sampling.
MINIGAME macro
A Cocos Creator preprocessor macro that evaluates to true when the project is built for a mini-game platform such as WeChat. It is used for compile-time platform branching alongside JSB (native) and standard Web checks.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗