AirPlay 2 stream setup over the encrypted RTSP channel, porting
SetupAirPlay2Session / SetupAirPlay2Stream:
- SETUP #1 (session): bplist
{"timingProtocol":"NTP"}→ device returnstimingPort+eventPort(the controller opens a TCP event channel). - SETUP #2 (stream): bplist
{"streams":[{audioFormat,ct,shk,spf,sr,type, controlPort}]}→ device returns the audiodataPort(+ control port).
shk is the first 32 bytes of the SRP session key and also the per-packet
ChaCha20-Poly1305 audio key. Audio: ALAC (ct:2), 44100/16/2, 352 spf, RTP
payload type 96.
Summary
Functions
RECORD — RTP-Info: seq;rtptime + Range: npt=0-.
SETUP #1 — returns {:ok, %{event_port, timing_peer_info}, rtsp2}.
SETUP #2 (stream). shk = the 32-byte audio key, control_port = our local
RTCP/control UDP port. Returns {:ok, %{data_port, control_port}, rtsp2}.
Functions
@spec record( AirPlay.V2.Rtsp2.t(), String.t(), String.t() | integer(), non_neg_integer(), non_neg_integer() ) :: {:ok, AirPlay.V2.Rtsp2.t()} | {:error, term()}
RECORD — RTP-Info: seq;rtptime + Range: npt=0-.
@spec session(AirPlay.V2.Rtsp2.t(), String.t(), String.t() | integer()) :: {:ok, map(), AirPlay.V2.Rtsp2.t()} | {:error, term()}
SETUP #1 — returns {:ok, %{event_port, timing_peer_info}, rtsp2}.
@spec stream( AirPlay.V2.Rtsp2.t(), String.t(), String.t() | integer(), binary(), non_neg_integer() ) :: {:ok, map(), AirPlay.V2.Rtsp2.t()} | {:error, term()}
SETUP #2 (stream). shk = the 32-byte audio key, control_port = our local
RTCP/control UDP port. Returns {:ok, %{data_port, control_port}, rtsp2}.