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.50
Verified 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 8770
See service/ (Linux systemd --user contributions welcome).
| Projector | Protocol | Status | Notes |
|---|---|---|---|
| Sony VPL‐EX255 | pwLink / PrioRFB | ✅ verified | ×ばつ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×ばつ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.