跪拜 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 ↗