Skip to content

pashza/win2airplay2

Repository files navigation

WinAir

Stream Windows system audio to AirPlay and Google Cast speakers — pick rooms, hit Play.

WinAir is a small open-source desktop app for Windows. It captures whatever is playing on your PC (Spotify, YouTube, games…) and sends it live to speakers on your network.

  Windows audio  →  WinAir  →  Living room / Bedroom / Apple TV / …

Download (easiest)

  1. Open the latest Release
  2. Download WinAir-windows-*.zip (not a raw .exe — GitHub often rejects those)
  3. Unzip, then (recommended for Cast speakers) run setup_firewall.bat once as Administrator
  4. Double-click WinAir.exe

Logs: %USERPROFILE%\.winair\winair.log

Cutting a release (maintainers)

git push origin master
git tag v1.1.0
git push origin v1.1.0

See docs/RELEASING.md. Do not upload a bare PyInstaller .exe in the GitHub UI — use the CI zip.


Features

  • One-click multiroom — select one or more speakers, then Play / Stop
  • Live system capture — mirrors your Windows default playback device (WASAPI loopback)
  • AirPlay + Google Cast — RAOP via pyatv; Cast fallback for devices that need it (e.g. Arylic LP10)
  • Per-speaker volume — sliders that work while streaming
  • Add / remove speakers while playing — check another room mid-stream without Stop / Play
  • Mute PC while playing — cuts local echo so you only hear the rooms
  • System tray — minimize or close to the notification area; Show / Exit from the tray menu
  • Start with Windows — optional login launch (starts minimized to tray)
  • Pairing memory — AirPlay PINs saved under %USERPROFILE%\.winair\

Requirements

OS Windows 10 or 11
Network PC and speakers on the same LAN (avoid VPN when possible)
Speakers AirPlay / RAOP and/or Google Cast receivers
Dev install Python 3.10+ (only if running from source)

Run from source

git clone https://github.com/pashza/win2airplay2.git
cd win2airplay2

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt

python -m app
# or:  .\run.bat

run.bat prefers the project .venv when present (so local edits are used). In a release zip (no venv) it launches WinAir.exe.

Firewall (Cast speakers)

Devices like Arylic LP10 pull audio from a small HTTP stream on your PC (TCP 8765). Allow that once:

  1. Right-click setup_firewall.batRun as administrator
  2. Accept the UAC prompt

Works for both WinAir.exe and the venv Python interpreter.


Use

  1. Wait for speakers to appear (or click Refresh)
  2. Check the rooms you want
  3. Adjust volume sliders if needed
  4. Leave Mute PC while playing on (recommended)
  5. Click Play — enter a PIN if an Apple device asks
  6. While playing you can check/uncheck more rooms, or Refresh to discover new ones
  7. Minimize / close to tray (optional settings), or click Stop when done

How routing works

Device type Transport Notes
Shairport Sync, many AirPlay speakers AirPlay (RAOP) Direct stream from WinAir
Apple TV / HomePod AirPlay (RAOP) Usually needs a one-time PIN
Arylic LP10 and similar Google Cast Used when AirPlay 2 SETUP fails with open-source RAOP

Latency & sync

WinAir is for whole-home listening, not bit-perfect monitoring.

  • Mute PC while playing removes the “PC is ahead of the rooms” echo
  • Cast buffers more than AirPlay (often ~1–2+ seconds)
  • Multiroom sync is best-effort — true AirPlay 2 PTP sync isn’t available open-source yet

Build the exe locally

powershell -ExecutionPolicy Bypass -File .\scripts\build_exe.ps1

Output: dist\WinAir.exe
Test the frozen build with dist\WinAir.exe directly (run.bat keeps using .venv while it exists).

GitHub Releases (CI)

git tag v1.1.0
git push origin v1.1.0

The Release workflow builds on windows-latest and uploads WinAir-windows-v1.1.0.zip.


Project layout

win2airplay2/
├── app/                 # application package
│   ├── main.py          # entry
│   ├── ui.py            # UI + tray bindings
│   ├── tray.py          # native Win32 tray icon
│   ├── startup.py       # Start with Windows shortcut
│   ├── settings.py      # persisted preferences
│   ├── discovery.py     # speaker scan
│   ├── streamer.py      # play session (add/remove speakers)
│   ├── capture.py       # WASAPI → MP3
│   ├── cast_backend.py  # Google Cast
│   ├── config.py        # constants / paths
│   └── models.py        # Speaker model
├── scripts/build_exe.ps1
├── WinAir.spec          # PyInstaller
├── .github/workflows/release.yml
├── run.bat              # venv first, else WinAir.exe
├── setup_firewall.bat
├── pyproject.toml
└── requirements.txt

Stack


Contributing

Issues and PRs welcome — especially AirPlay 2 sender improvements, sync, packaging, and UI polish. Include OS version, speaker model, and %USERPROFILE%\.winair\winair.log when filing bugs.


License

MIT — see LICENSE.


Acknowledgments

Built on the work of the pyatv, PyChromecast, and PyAudioWPatch communities. WinAir is not affiliated with Apple, Google, or Arylic.

About

Win2Airplay2 - Simple single exe airplay 2 multiroom streamer

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages