AirPlay.V2.Setup (AirPlay v0.2.0)

Copy Markdown View Source

AirPlay 2 stream setup over the encrypted RTSP channel, porting SetupAirPlay2Session / SetupAirPlay2Stream:

  • SETUP #1 (session): bplist {"timingProtocol":"NTP"} → device returns timingPort + eventPort (the controller opens a TCP event channel).
  • SETUP #2 (stream): bplist {"streams":[{audioFormat,ct,shk,spf,sr,type, controlPort}]} → device returns the audio dataPort (+ 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

record(rtsp2, ip, session_id, seq, rtptime)

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

session(rtsp2, ip, session_id)

@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}.

stream(rtsp2, ip, session_id, shk, control_port)

@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}.