Skip to content

Commit

Permalink
Create transceivers on set_remote_description
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 committed Oct 17, 2023
1 parent 3c4fbfa commit 0e615c5
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
47 changes: 44 additions & 3 deletions lib/ex_webrtc/peer_connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule ExWebRTC.PeerConnection do

alias __MODULE__.Configuration
alias ExICE.ICEAgent
alias ExWebRTC.{IceCandidate, SessionDescription}
alias ExWebRTC.{IceCandidate, RTPTransceiver, SessionDescription}

import ExWebRTC.Utils

Expand All @@ -28,7 +28,7 @@ defmodule ExWebRTC.PeerConnection do
:dtls_client,
:dtls_buffered_packets,
dtls_finished: false,
transceivers: [],
transceivers: %{},
signaling_state: :stable
]

Expand Down Expand Up @@ -299,7 +299,48 @@ defmodule ExWebRTC.PeerConnection do
:ok = ICEAgent.set_remote_credentials(state.ice_agent, ufrag, pwd)
:ok = ICEAgent.gather_candidates(state.ice_agent)

{:ok, %{state | current_remote_desc: sdp}}
transceivers =
sdp.media
|> Enum.reduce(%{}, fn media ->
{:mid, mid} = ExSDP.Media.get_attribute(media, :mid)
# if there is no direction, the default is sendrecv
# see RFC 3264, sec. 6.1
direction = get_media_direction(media) || :sendrecv

if mid == nil or direction == :inactive do
# FIXME instead of raising return an error;
# FIXME what about inactive mlines?
# Should we create transceivers for them too?;
raise "Invalid remote description: missing or invalid mid or direction"
end

tr =
Map.get(state.transceivers, mid) ||
find_or_create_transceiver(mid, direction, state.transceivers)

{tr.mid, tr}
end)
|> Map.merge(state.transceivers)

{:ok, %{state | current_remote_desc: sdp, transceivers: transceivers}}
end

defp find_or_create_transceiver(mid, direction, transceivers)
when direction in [:sendrecv, :recvonly] do
Enum.find(transceivers, %RTPTransceiver{mid: mid, direction: :recvonly}, fn
{nil, tr} when tr.direction == direction -> tr
_other -> nil
end)
end

defp find_or_create_transceiver(mid, :sendonly, _transceivers) do
%RTPTransceiver{mid: mid, direction: :recvonly}
end

defp get_media_direction(media) do
Enum.find(media.attributes, fn attr ->
attr in [:sendrecv, :sendonly, :recvonly, :inactive]
end)
end

# Signaling state machine, RFC 8829 3.2
Expand Down
9 changes: 9 additions & 0 deletions lib/ex_webrtc/rtp_transceiver.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule ExWebRTC.RTPTransceiver do

Check warning on line 1 in lib/ex_webrtc/rtp_transceiver.ex

View workflow job for this annotation

GitHub Actions / Lint (OTP 26 / Elixir 1.15)

Modules should have a @moduledoc tag.
@type t() :: %__MODULE__{
mid: String.t(),
direction: :sendonly | :recvonly | :sendrecv | :inactive | :stopped
}

@enforce_keys [:mid, :direction]
defstruct @enforce_keys
end

0 comments on commit 0e615c5

Please sign in to comment.