Metadata-Version: 2.4
Name: projecast
Version: 0.1.1
Summary: Projecast — send photos & videos to a wireless projector over Wi-Fi. Open-source, for projectors abandoned by their casting app (VueMagic / MirrorOp / pwLink).
Author: pwcast contributors
License: MIT
Project-URL: Homepage, https://github.com/rekarbotany/projecast
Project-URL: Repository, https://github.com/rekarbotany/projecast
Project-URL: Issues, https://github.com/rekarbotany/projecast/issues
Project-URL: Documentation, https://github.com/rekarbotany/projecast/blob/main/docs/PROTOCOL.md
Keywords: projector,wireless-display,casting,screen-mirroring,pwlink,priorfb,vuemagic,mirrorop,sony-vpl,pixelworks,rfb
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Graphics :: Presentation
Classifier: Topic :: Multimedia :: Video :: Display
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: Pillow>=9.0
Provides-Extra: dev
Requires-Dist: ruff; extra == "dev"
Requires-Dist: build; extra == "dev"
Provides-Extra: incremental
Requires-Dist: numpy>=1.20; extra == "incremental"
Dynamic: license-file

<p align="center"><img src="assets/social-preview.png" alt="Projecast" width="720"></p>

<!--
Keywords (search): cast photos to projector, send video to projector wifi, wireless projector app,
VueMagic alternative, VueMagic replacement, MirrorOp alternative, MirrorOp discontinued,
Sony VPL wireless cast, pwLink, PrioRFB, Pixelworks, projector casting macOS.
-->

# 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.

```bash
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](#compatibility).

---

## 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

```bash
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
```bash
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
```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](#run-as-an-always-on-service)), then:
```bash
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:
```bash
cd service && ./install_service.sh 192.168.1.50 8770
```
See [`service/`](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](../../issues/new?template=device-report.md) — 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](docs/PROTOCOL.md)**.

## Roadmap

- ✅ Incremental/tiled updates — **available (experimental)**: `projecast video clip.mp4 --incremental` (or `play_video(..., incremental=True)`); needs `pip 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](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](NOTICE) and [SECURITY.md](SECURITY.md).

## License

[MIT](LICENSE) © contributors.
