A pure-Elixir AirPlay (RAOP) audio sender. Discover receivers on your network and stream lossless audio to them — no native dependencies, just the Erlang/OTP. :crypto, :gen_udp and :gen_tcp.

It speaks classic AirPlay 1 / RAOP: unencrypted ALAC over RTP with the NTP-style timing/sync receivers require. Verified streaming real audio to shairport-sync, AirPort Express, and Apple HomePods.

Experimental AirPlay 2 building blocks (transient SRP pairing, ChaCha20-Poly1305 encrypted control channel, binary plist, SETUP) live under AirPlay.V2. The control plane is verified against real HomePods, but audio rendering (PTP clock-slaving) is not complete yet — use the AirPlay 1 API below for playback.

This is still WIP, created to scratch an itch.

Installation

def deps do
  [{:airplay, "~> 0.1.0"}]
end

Usage

# Discover receivers (mDNS browse of _raop._tcp.local)
AirPlay.discover()
#=> [%{name: "Office", host: "172.16.42.35", port: 7000}, ...]

# Stream a file (decoded to PCM via ffmpeg) at 40% volume
{:ok, session} = AirPlay.play("172.16.42.35", "/music/track.flac", volume: 40)
AirPlay.set_volume(session, 25)
AirPlay.stop(session)

# Or stream raw PCM you already have (44.1 kHz, signed 16-bit LE, stereo, interleaved)
{:ok, session} = AirPlay.play_pcm("172.16.42.35", pcm, volume: 40)

A session is a lightweight GenServer that streams in the background and stops itself when the track ends; pass it to set_volume/2 and stop/1.

Requirements

How it works

play/3 opens an RTSP control connection (OPTIONS → ANNOUNCE → SETUP → RECORD), binds the UDP timing/control ports and answers the receiver's NTP timing probe before SETUP (HomePods return 520 Origin Error otherwise), then paces ALAC RTP packets to the receiver against a wall-clock with periodic sync packets.

ModuleRole
AirPlay.DiscoverymDNS _raop._tcp browse
AirPlay.Rtsp / AirPlay.SessionRTSP control plane + handshake
AirPlay.PlayerRTP audio streaming + timing/sync
AirPlay.Rtp / AirPlay.Alac / AirPlay.Ntppacket builders + codecs
AirPlay.Sourcefile → PCM (ffmpeg) + framing
AirPlay.Castplay/stop/volume session GenServer

License

BSD-3-Clause. See LICENSE.