View Source Specter.PeerConnection (specter v0.4.1)

Represents an RTCPeerConnection managed in the NIF. A running Specter instance may have 0 or more peer connections at any time.

Users of Specter might choose between different topologies based on their use cases: a Specter might be initialized per connection, and signaling messages passed between different instances of the NIF; a Specter may be initialized per "room," and all peer connections for that room created within the single NIF instance; a "room" may be split across Erlang nodes, with tracks forwarded between the nodes.

Link to this section Summary

Types

Options for creating a webrtc answer. Values default to false.

Message sent as a result of a call to connection_state/2.

Possible states of peer connection.

An ICE candidate as JSON.

Message sent as a result of a call to ice_connection_state/2.

Possible states of ICE connection.

Message sent as a result of a call to ice_gathering_state/2.

Possible states of ICE gathering process.

Options for creating a webrtc offer. Values default to false.

Message sent as a result of a call to add_track/3.

A UTF-8 encoded string encapsulating either an offer or an answer.

The type of an SDP message, either an :offer or an :answer.

A UTF-8 encoded string encapsulating an Offer or an Answer in JSON. The keys are as follows

Message sent as a result of a call to signaling_state/2.

Possible states of session parameters negotiation.

t()

Specter.PeerConnection.t/0 represents an instantiated RTCPeerConnection managed in the NIF.

Functions

Given an ICE candidate, add it to the given peer connection. Assumes trickle ICE. Candidates must be JSON, with the keys candidate, sdp_mid, sdp_mline_index, and username_fragment.

Adds track to peer connection.

Closes an open instance of an RTCPeerConnection.

Sends back state of peer connection. This will send message connection_state_msg_t/0.

Given an RTCPeerConnection where the remote description has been assigned via set_remote_description/4, create an answer that can be passed to another connection.

Creates a data channel on an RTCPeerConnection.

Given an RTCPeerConnection, create an offer that can be passed to another connection.

Sends back the value of the current session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_local_description/3 called and has successfully negotiated ICE. In all other cases, nil will be sent.

Sends back the value of the current remote session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_remote_description/3 called and has successfully negotiated ICE. In all other cases, nil will be sent.

Returns true or false, depending on whether the RTCPeerConnection is initialized.

Sends back a JSON encoded string representing the current stats of a peer connection.

Sends back state of ICE connection for given peer connection. This will send message ice_connection_state_msg_t/0

Sends back state of ICE gathering process. This will send message ice_gathering_state_t/0.

Sends back the value of the local session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_local_description/3 called. If ICE has been successfully negotated, the current local description will be sent back, otherwise the caller will receive the pending local description.

Creates a new RTCPeerConnection, using an API reference created with new_api/3. The functionality wrapped by this function is async, so :ok is returned immediately. Callers should listen for the {:peer_connection_ready, peer_connection_t()} message to receive the results of this function.

Sends back the value of the session description on a peer connection that is pending connection, or nil.

Sends back the value of the remote session description on a peer connection on a peer that is pending connection, or nil.

Sends back the value of the remote session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_remote_description/3 called. If ICE has been successfully negotated, the current remote description will be sent back, otherwise the caller will receive the pending remote description.

Given an offer or an answer session description, sets the local description on a peer connection. The description should be in the form of JSON with the keys type and sdp.

Given an offer or an answer in the form of SDP generated by a remote party, sets the remote description on a peer connection. Expects a session description in the form of JSON with the keys type and sdp.

Sends back state of session parameters negotiation. This will send message signaling_state_msg_t/0.

Link to this section Types

@type answer_options_t() :: [] | [{:voice_activity_detection, bool()}]

Options for creating a webrtc answer. Values default to false.

Link to this type

connection_state_msg_t()

View Source
@type connection_state_msg_t() :: {:connection_state, t(), connection_state_t()}

Message sent as a result of a call to connection_state/2.

@type connection_state_t() ::
  :closed
  | :connected
  | :connecting
  | :disconnected
  | :failed
  | :new
  | :unspecified

Possible states of peer connection.

@type ice_candidate_t() :: String.t()

An ICE candidate as JSON.

Link to this type

ice_connection_state_msg_t()

View Source
@type ice_connection_state_msg_t() ::
  {:ice_connection_state, t(), ice_connection_state_t()}

Message sent as a result of a call to ice_connection_state/2.

Link to this type

ice_connection_state_t()

View Source
@type ice_connection_state_t() ::
  :unspecified
  | :new
  | :checking
  | :connected
  | :completed
  | :disconnected
  | :failed
  | :closed

Possible states of ICE connection.

Link to this type

ice_gathering_state_msg_t()

View Source
@type ice_gathering_state_msg_t() ::
  {:ice_gathering_state, t(), ice_connection_state_t()}

Message sent as a result of a call to ice_gathering_state/2.

Link to this type

ice_gathering_state_t()

View Source
@type ice_gathering_state_t() :: :complete | :gathering | :new | :unspecified

Possible states of ICE gathering process.

@type offer_options_t() ::
  [] | [voice_activity_detection: bool(), ice_restart: bool()]

Options for creating a webrtc offer. Values default to false.

@type rtp_sender_t() ::
  {:rtp_sender, t(), Specter.TrackLocalStaticSample.t(), String.t()}

Message sent as a result of a call to add_track/3.

@type sdp_t() :: String.t()

A UTF-8 encoded string encapsulating either an offer or an answer.

@type sdp_type_t() :: :offer | :answer

The type of an SDP message, either an :offer or an :answer.

Link to this type

session_description_t()

View Source
@type session_description_t() :: String.t()

A UTF-8 encoded string encapsulating an Offer or an Answer in JSON. The keys are as follows:

keytype
typeoffer, answer
sdp`sdp_t()
Link to this type

signaling_state_msg_t()

View Source
@type signaling_state_msg_t() :: {:signaling_state, t(), signaling_state_t()}

Message sent as a result of a call to signaling_state/2.

@type signaling_state_t() ::
  :closed
  | :have_local_offer
  | :have_local_pranswer
  | :have_remote_offer
  | :have_remote_pranswer
  | :stable
  | :unspecified

Possible states of session parameters negotiation.

@opaque t()

Specter.PeerConnection.t/0 represents an instantiated RTCPeerConnection managed in the NIF.

Link to this section Functions

Link to this function

add_ice_candidate(specter, pc, candidate)

View Source
@spec add_ice_candidate(Specter.t(), t(), ice_candidate_t()) :: :ok | {:error, term()}

Given an ICE candidate, add it to the given peer connection. Assumes trickle ICE. Candidates must be JSON, with the keys candidate, sdp_mid, sdp_mline_index, and username_fragment.

Link to this function

add_track(specter, pc, track)

View Source
@spec add_track(Specter.t(), t(), Specter.TrackLocalStaticSample.t()) ::
  :ok | {:error | term()}

Adds track to peer connection.

Sends back uuid of newly created rtp sender. This will send message t:rtp_sender_msg_t/0.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
iex> codec = %Specter.RtpCodecCapability{mime_type: "audio"}
iex> {:ok, track} = Specter.TrackLocalStaticSample.new(specter, codec, "audio", "specter")
iex> :ok = Specter.PeerConnection.add_track(specter, pc, track)
iex> assert_receive {:rtp_sender, ^pc, ^track, _rtp_sender}
...>
iex> {:error, :invalid_track} = Specter.PeerConnection.add_track(specter, pc, "invalid_track")
@spec close(Specter.t(), t()) :: :ok | {:error, term()}

Closes an open instance of an RTCPeerConnection.

usage

Usage

iex> {:ok, specter} = Specter.init(ice_servers: ["stun:stun.l.google.com:19302"])
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
...>
iex> Specter.PeerConnection.close(specter, pc)
:ok
iex> {:ok, _pc} =
...>     receive do
...>       {:peer_connection_closed, ^pc} -> {:ok, pc}
...>     after
...>       500 -> {:error, :timeout}
...>     end
...>
iex> Specter.PeerConnection.exists?(specter, pc)
false
Link to this function

connection_state(specter, pc)

View Source
@spec connection_state(Specter.t(), t()) :: :ok | {:error, term()}

Sends back state of peer connection. This will send message connection_state_msg_t/0.

Link to this function

create_answer(specter, pc, opts \\ [])

View Source
@spec create_answer(Specter.t(), t(), answer_options_t()) :: :ok | {:error, term()}

Given an RTCPeerConnection where the remote description has been assigned via set_remote_description/4, create an answer that can be passed to another connection.

paramtypedefault
spectert()
peer_connectionopaque
optionsanswer_options_t()voice_activity_detection: false
Link to this function

create_data_channel(specter, pc, label)

View Source
@spec create_data_channel(Specter.t(), t(), String.t()) :: :ok | {:error, term()}

Creates a data channel on an RTCPeerConnection.

Note: this can be useful when attempting to generate a valid offer, but where no media tracks are expected to be sent or received. Callbacks from data channels have not yet been implemented.

Link to this function

create_offer(specter, pc, opts \\ [])

View Source
@spec create_offer(Specter.t(), t(), offer_options_t()) :: :ok | {:error, term()}

Given an RTCPeerConnection, create an offer that can be passed to another connection.

paramtypedefault
spectert()
peer_connectionopaque
optionsoffer_options_t()voice_activity_detection: false
ice_restart: false
Link to this function

current_local_description(specter, pc)

View Source
@spec current_local_description(Specter.t(), t()) :: :ok | {:error, term()}

Sends back the value of the current session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_local_description/3 called and has successfully negotiated ICE. In all other cases, nil will be sent.

See pending_local_description/2 and local_description/2.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
iex> Specter.PeerConnection.current_local_description(specter, pc)
:ok
iex> assert_receive {:current_local_description, ^pc, nil}
Link to this function

current_remote_description(specter, pc)

View Source
@spec current_remote_description(Specter.t(), t()) :: :ok | {:error, term()}

Sends back the value of the current remote session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_remote_description/3 called and has successfully negotiated ICE. In all other cases, nil will be sent.

See current_remote_description/2 and remote_description/2.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
iex> Specter.PeerConnection.current_remote_description(specter, pc)
:ok
iex> assert_receive {:current_remote_description, ^pc, nil}
Link to this function

exists?(specter, peer_connection)

View Source
@spec exists?(Specter.t(), t()) :: boolean() | no_return()

Returns true or false, depending on whether the RTCPeerConnection is initialized.

usage

Usage

iex> {:ok, specter} = Specter.init(ice_servers: ["stun:stun.l.google.com:19302"])
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
iex> Specter.PeerConnection.exists?(specter, pc)
true

iex> {:ok, specter} = Specter.init(ice_servers: ["stun:stun.l.google.com:19302"])
iex> Specter.PeerConnection.exists?(specter, UUID.uuid4())
false
@spec get_stats(Specter.t(), t()) :: :ok | {:error, term()}

Sends back a JSON encoded string representing the current stats of a peer connection.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
...>
iex> Specter.PeerConnection.get_stats(specter, pc)
:ok
iex> assert_receive {:stats, ^pc, json}
iex> {:ok, _stats} = Jason.decode(json)
Link to this function

ice_connection_state(specter, pc)

View Source
@spec ice_connection_state(Specter.t(), t()) :: :ok | {:error, term()}

Sends back state of ICE connection for given peer connection. This will send message ice_connection_state_msg_t/0

Link to this function

ice_gathering_state(specter, pc)

View Source
@spec ice_gathering_state(Specter.t(), t()) :: :ok | {:error, term()}

Sends back state of ICE gathering process. This will send message ice_gathering_state_t/0.

Link to this function

local_description(specter, pc)

View Source
@spec local_description(Specter.t(), t()) :: :ok | {:error, term()}

Sends back the value of the local session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_local_description/3 called. If ICE has been successfully negotated, the current local description will be sent back, otherwise the caller will receive the pending local description.

See current_local_description/2 and pending_local_description/2.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
...>
iex> Specter.PeerConnection.local_description(specter, pc)
:ok
iex> assert_receive {:local_description, ^pc, nil}
...>
iex> :ok = Specter.PeerConnection.create_offer(specter, pc)
iex> assert_receive {:offer, ^pc, offer}
iex> :ok = Specter.PeerConnection.set_local_description(specter, pc, offer)
iex> assert_receive {:ok, ^pc, :set_local_description}
...>
iex> Specter.PeerConnection.local_description(specter, pc)
:ok
iex> assert_receive {:local_description, ^pc, ^offer}
@spec new(Specter.t(), Specter.api_t()) :: {:ok, t()} | {:error, term()}

Creates a new RTCPeerConnection, using an API reference created with new_api/3. The functionality wrapped by this function is async, so :ok is returned immediately. Callers should listen for the {:peer_connection_ready, peer_connection_t()} message to receive the results of this function.

paramtypedefault
spectert()
apiopaque

usage

Usage

iex> {:ok, specter} = Specter.init(ice_servers: ["stun:stun.l.google.com:19302"])
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
...>
iex> {:ok, _pc} =
...>     receive do
...>       {:peer_connection_ready, ^pc} -> {:ok, pc}
...>     after
...>       500 -> {:error, :timeout}
...>     end
Link to this function

pending_local_description(specter, pc)

View Source
@spec pending_local_description(Specter.t(), t()) :: :ok | {:error, term()}

Sends back the value of the session description on a peer connection that is pending connection, or nil.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc}
...>
iex> Specter.PeerConnection.pending_local_description(specter, pc)
:ok
iex> assert_receive {:pending_local_description, ^pc, nil}
...>
iex> :ok = Specter.PeerConnection.create_offer(specter, pc)
iex> assert_receive {:offer, ^pc, offer}
iex> :ok = Specter.PeerConnection.set_local_description(specter, pc, offer)
iex> assert_receive {:ok, ^pc, :set_local_description}
...>
iex> Specter.PeerConnection.pending_local_description(specter, pc)
:ok
iex> assert_receive {:pending_local_description, ^pc, ^offer}
Link to this function

pending_remote_description(specter, pc)

View Source
@spec pending_remote_description(Specter.t(), t()) :: :ok | {:error, term()}

Sends back the value of the remote session description on a peer connection on a peer that is pending connection, or nil.

See current_remote_description/2 and pending_remote_description/2.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc_offer} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc_offer}
iex> :ok = Specter.PeerConnection.create_data_channel(specter, pc_offer, "foo")
iex> assert_receive {:data_channel_created, ^pc_offer}
iex> :ok = Specter.PeerConnection.create_offer(specter, pc_offer)
iex> assert_receive {:offer, ^pc_offer, offer}
...>
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc_answer} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc_answer}
...>
iex> Specter.PeerConnection.pending_remote_description(specter, pc_answer)
:ok
iex> assert_receive {:pending_remote_description, ^pc_answer, nil}
...>
iex> :ok = Specter.PeerConnection.set_remote_description(specter, pc_answer, offer)
iex> assert_receive {:ok, ^pc_answer, :set_remote_description}
...>
iex> Specter.PeerConnection.pending_remote_description(specter, pc_answer)
:ok
iex> assert_receive {:pending_remote_description, ^pc_answer, ^offer}
Link to this function

remote_description(specter, pc)

View Source
@spec remote_description(Specter.t(), t()) :: :ok | {:error, term()}

Sends back the value of the remote session description on a peer connection. This will send back JSON representing an offer or an answer when the peer connection has had set_remote_description/3 called. If ICE has been successfully negotated, the current remote description will be sent back, otherwise the caller will receive the pending remote description.

See current_remote_description/2 and remote_description/2.

usage

Usage

iex> {:ok, specter} = Specter.init()
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc_offer} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc_offer}
iex> :ok = Specter.PeerConnection.create_data_channel(specter, pc_offer, "foo")
iex> assert_receive {:data_channel_created, ^pc_offer}
iex> :ok = Specter.PeerConnection.create_offer(specter, pc_offer)
iex> assert_receive {:offer, ^pc_offer, offer}
...>
iex> {:ok, media_engine} = Specter.new_media_engine(specter)
iex> {:ok, registry} = Specter.new_registry(specter, media_engine)
iex> {:ok, api} = Specter.new_api(specter, media_engine, registry)
iex> {:ok, pc_answer} = Specter.PeerConnection.new(specter, api)
iex> assert_receive {:peer_connection_ready, ^pc_answer}
...>
iex> Specter.PeerConnection.remote_description(specter, pc_answer)
:ok
iex> assert_receive {:remote_description, ^pc_answer, nil}
...>
iex> :ok = Specter.PeerConnection.set_remote_description(specter, pc_answer, offer)
iex> assert_receive {:ok, ^pc_answer, :set_remote_description}
...>
iex> Specter.PeerConnection.remote_description(specter, pc_answer)
:ok
iex> assert_receive {:remote_description, ^pc_answer, ^offer}
Link to this function

set_local_description(specter, pc, description)

View Source
@spec set_local_description(Specter.t(), t(), session_description_t()) ::
  :ok | {:error, term()}

Given an offer or an answer session description, sets the local description on a peer connection. The description should be in the form of JSON with the keys type and sdp.

paramtypedefault
spectert/0
peer_connectionopaque
descriptiont:session_description_t()
Link to this function

set_remote_description(specter, pc, description)

View Source
@spec set_remote_description(Specter.t(), t(), session_description_t()) ::
  :ok | {:error, term()}

Given an offer or an answer in the form of SDP generated by a remote party, sets the remote description on a peer connection. Expects a session description in the form of JSON with the keys type and sdp.

paramtypedefault
spectert/0
peer_connectionopaque
descriptionsession_description_t/0
Link to this function

signaling_state(specter, pc)

View Source
@spec signaling_state(Specter.t(), t()) :: :ok | {:error, term()}

Sends back state of session parameters negotiation. This will send message signaling_state_msg_t/0.