MayScreen is a WeChat Mini Program teleprompter. It turns one phone into a landscape lyric screen and another nearby phone into a BLE remote control, so a performer or crew member can switch songs, move through lyrics, and keep playback state synchronized without a network connection between the two devices.
- Screen mode: displays lyrics in a fullscreen landscape view, keeps the device awake, and receives remote commands over BLE.
- Remote mode: provides a control panel for selecting songs, changing lyric lines, toggling autoplay, and controlling a nearby screen.
- BLE device pairing: the screen advertises itself as a MayScreen peripheral, while the remote scans, selects, connects, authorizes, and shows the connected screen state.
- Short-session identity: each screen and remote generates a short session nickname such as
S-1A2BorR-8F3Afor connection feedback. - Command protocol: short BLE packets carry realtime commands, while large song or lyric payloads are compressed, chunked, transmitted, and reassembled.
- Song library and search: the control panel supports local song data and web lyric search through the MayScreen API.
- Synchronized playback state: the screen and remote share current song, lyric index, autoplay state, RSSI, and transfer progress through the app stores.
- Mini Program runtime:
weapp-vitewith thewevuruntime layer - State management: Pinia-style stores from
wevu/store - Styling: Tailwind CSS v4 through
weapp-tailwindcss, with scoped SCSS where needed - BLE payload tools: custom packet helpers with
pakocompression and text encoder/decoder polyfills
MayScreen uses two BLE roles:
- Screen (
BleScreen) opens the Bluetooth adapter in peripheral mode, creates a BLE peripheral server, advertises a MayScreen service UUID, receives commands, and publishes heartbeat/status notifications. - Remote (
BleRemote) opens the Bluetooth adapter in central mode, scans for advertised service UUIDs that start with19970329-, connects to a selected screen, subscribes to characteristics, and sends commands.
The protocol uses:
statuscharacteristic for heartbeat and liveness.read/writecharacteristics for short realtime command packets.readLarge/writeLargecharacteristics for chunked song and lyric payloads.Command.AuthorizeandCommand.ReplyAuthorizeas the connection handshake before the UI enters the connected state.
Install dependencies:
bun installStart the mini-program development build:
bun devBuild for production:
bun buildRun static checks:
bun typecheck
bun lintOpen the project in WeChat DevTools:
bun open