Projecast
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.
Why this exists
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.
Features
- 🖼️ 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
Install
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.
Quick start
Command line
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.)
Python
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()
HTTP API (any app, any language)
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).
Run as an always-on service
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).
Compatibility
| 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.
How it works
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.
Roadmap
- ✅ 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
Contributing
Issues and PRs welcome — especially device reports and non‑1024×768 panels. See CONTRIBUTING.md.
Legal
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.
License
MIT © contributors.
Metadata
Release files for projecast 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| projecast-0.1.1.tar.gz | 18.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| projecast-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.6 kB
Release files / projecast-0.1.1.tar.gz
| Download URL | projecast-0.1.1.tar.gz |
|---|---|
| Size | 18.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
56a00cf9b18bcea3b606e98761b96e6e305d84aa571cbd963bfddb3b3f62e063
|
|
BLAKE2b-256 checksum How to use checksums |
acfe44572733418cab95fa935d14e5cc6b088c8517b4432ad9f3881f9e84280c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / projecast-0.1.1-py3-none-any.whl
| Download URL | projecast-0.1.1-py3-none-any.whl |
|---|---|
| Size | 17.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
319a270377fd9d060ef8fa3f412f842f13294e1a0dcfab59e260a90c3dd6c6ef
|
|
BLAKE2b-256 checksum How to use checksums |
a26b58171adcfd81edde892e5916dd8daf90d3baa48306d3d32ec8177e33acb7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|