Send photos & videos to a wireless projector over Wi‑Fi — open source.
A free, modern replacement for the discontinued projector‑casting apps (VueMagic, MirrorOp, and other Pixelworks pwLink / PrioRFB models). If your Wi‑Fi projector only shows a blue "Network mode" screen because its app died, Projecast brings it back — no vendor app required.
Pictures and video go to the projector at its native resolution, with no laggy screen‑mirroring and no fan spinning up. Use it as an app command, a Python library, or a tiny local service any app can call.
pip install projecast
projecast test --host 192.168.1.50 # show a test card on the projector
projecast image photo.jpg --host 192.168.1.50Verified on a Sony VPL‑EX255. Other pwLink/MirrorOp projectors are likely compatible — please report yours.
A lot of wireless projectors (Sony VPL‑EX/EW and other brands that used Pixelworks pwLink / MirrorOp) can only receive wireless display through a proprietary app that has since been discontinued or moved to enterprise‑only products. The projector still works — the software just disappeared. Projecast re‑implements the protocol from scratch (clean‑room, for interoperability with hardware you own) so these projectors are useful again.
- 🖼️ Photos at full native quality (correct 4:2:0 JPEG the projector actually accepts)
- 🎞️ Video playback (ffmpeg‑decoded, streamed at the projector's frame rate)
- 🗂️ Slideshows with auto‑advance and looping
- 🧩 Three ways to use it: Python API, command line, or local HTTP API (any language)
- 🔌 Always‑on service so any app casts by calling
localhost:8770 - 🪶 Low CPU — a still image is encoded once and held; nothing re‑renders while it's on screen
pip install projecast # from PyPI (once published)
# or from source:
git clone https://github.com/rekarbotany/projecast && cd projecast && pip install -e .Python 3.9+. Pillow is installed automatically (images). ffmpeg on your PATH is needed only for video.
projecast test --host 192.168.1.50
projecast image sunset.jpg --host 192.168.1.50 --fit contain --quality 95
projecast video clip.mp4 --host 192.168.1.50 --fps 15 --loop
projecast slideshow a.jpg b.jpg c.jpg --interval 6
projecast serve 8770 # start the HTTP API(pwcast is kept as an alias command for people who found this by the protocol name.)
from projecast import Projector
pj = Projector("192.168.1.50")
pj.connect()
pj.show_image("photo.jpg", fit="contain", quality=95) # held until you change it
pj.slideshow(["a.jpg", "b.jpg"], interval=5)
pj.play_video("clip.mp4", fps=15)
pj.clear()
pj.stop()Start it once (projecast serve or the service), then:
curl -X POST localhost:8770/image \
-H 'Content-Type: application/json' \
-d '{"path":"/abs/photo.jpg","fit":"contain","quality":95}'
# or upload raw bytes from a remote app:
curl -X POST --data-binary @photo.jpg -H 'Content-Type: image/jpeg' \
'localhost:8770/image?quality=95&fit=cover'| Method | Path | Body |
|---|---|---|
| GET | /status |
→ {connected, playing, stats, panel:[1024,768]} |
| POST | /image |
JSON {path, fit, quality} or raw image bytes + ?fit=&quality= |
| POST | /slideshow |
JSON {paths:[...], interval, fit, quality, loop} |
| POST | /video |
JSON {path, fps, quality, fit, loop} or raw video bytes |
| POST | /clear |
— |
| POST | /stop |
— |
fit: contain (letterbox, no crop) · cover (fill + crop) · stretch.
Image quality: 1–95 (higher = sharper). Video quality: ffmpeg -q:v (2 best … 31 worst).
macOS (launchd): make http://localhost:8770 always available and self‑restarting:
cd service && ./install_service.sh 192.168.1.50 8770See service/ (Linux systemd --user contributions welcome).
| Projector | Protocol | Status | Notes |
|---|---|---|---|
| Sony VPL‑EX255 | pwLink / PrioRFB | ✅ verified | 1024×768, Ethernet & Wi‑Fi |
| Other Sony VPL‑EX/EW | pwLink (likely) | ❓ untested | please report |
| Other MirrorOp/pwLink projectors | pwLink | ❓ untested | please report |
Have one of these projectors? Open a device report — the single most useful contribution; it builds the matrix for everyone.
Projecast acts as an RFB (VNC‑variant) server; the projector dials back and pulls frames. Casting a photo = hold one correctly‑framed JPEG and answer each pull with it. The full protocol (auth handshake, the 4:2:0 requirement, strict pull‑sync, frame format) is in docs/PROTOCOL.md.
- ✅ Incremental/tiled updates — available (experimental):
projecast video clip.mp4 --incremental(orplay_video(..., incremental=True)); needspip install projecast[incremental]. Sends only changed 128px tiles. - Optional 4:4:4 JPEG for even sharper text (device‑dependent)
- Audio for video · PJLink auto power‑on · projector auto‑discovery · native menu‑bar / iOS app
Issues and PRs welcome — especially device reports and non‑1024×768 panels. See CONTRIBUTING.md.
Projecast is a clean‑room reimplementation for interoperability with hardware you own. "Sony", "VPL", "Pixelworks", "pwLink", "VueMagic", "MirrorOp" are trademarks of their respective owners; this project is not affiliated with or endorsed by any of them. See NOTICE and SECURITY.md.
MIT © contributors.
