Skip to content

Commit

Permalink
Parse RTPCodecParameters
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 committed Oct 23, 2023
1 parent d19d6c9 commit 78457a0
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 4 deletions.
10 changes: 10 additions & 0 deletions lib/ex_webrtc/peer_connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ defmodule ExWebRTC.PeerConnection do

{:ok, dtls_fingerprint} = ExDTLS.get_cert_fingerprint(state.dtls_client)

%ExSDP{ExSDP.new() | timing: %ExSDP.Timing{start_time: 0, stop_time: 0}}

Check warning on line 154 in lib/ex_webrtc/peer_connection.ex

View check run for this annotation

Codecov / codecov/patch

lib/ex_webrtc/peer_connection.ex#L154

Added line #L154 was not covered by tests

# media = Enum.map(state.transceivers, fn transceiver -> to_sdp_media(transceiver, state) end)

sdp = ExSDP.parse!(@dummy_sdp)
media = hd(sdp.media)

Expand Down Expand Up @@ -180,6 +184,12 @@ defmodule ExWebRTC.PeerConnection do
{:reply, {:ok, desc}, state}
end

defp to_sdp_media(transceiver, state) do

Check warning on line 187 in lib/ex_webrtc/peer_connection.ex

View workflow job for this annotation

GitHub Actions / Test (OTP 26 / Elixir 1.15)

variable "state" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 187 in lib/ex_webrtc/peer_connection.ex

View workflow job for this annotation

GitHub Actions / Test (OTP 26 / Elixir 1.15)

variable "transceiver" is unused (if the variable is not meant to be used, prefix it with an underscore)
# %ExSDP.Media{
# Media.new(transceiver.kind, 9, "UDP/TLS/RTP/SAVPF")
# }
end

def handle_call({:create_answer, _options}, _from, state) do
{:reply, {:error, :invalid_state}, state}
end
Expand Down
18 changes: 18 additions & 0 deletions lib/ex_webrtc/rtp_codec_parameters.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule ExWebRTC.RTPCodecParameters do
@moduledoc """
RTPCodecParameters
"""

defstruct [:payload_type, :mime_type, :clock_rate, :channels, :sdp_fmtp_line, :rtcp_fbs]

def new(type, rtp_mapping, fmtp, rtcp_fbs) do
%__MODULE__{
payload_type: rtp_mapping.payload_type,
mime_type: "#{type}/#{rtp_mapping.encoding}",
clock_rate: rtp_mapping.clock_rate,
channels: rtp_mapping.params,
sdp_fmtp_line: fmtp,
rtcp_fbs: rtcp_fbs
}
end
end
3 changes: 3 additions & 0 deletions lib/ex_webrtc/rtp_receiver.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
defmodule ExWebRTC.RTPReceiver do

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

View workflow job for this annotation

GitHub Actions / Lint (OTP 26 / Elixir 1.15)

Modules should have a @moduledoc tag.
defstruct [:ssrc]
end
45 changes: 41 additions & 4 deletions lib/ex_webrtc/rtp_transceiver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ defmodule ExWebRTC.RTPTransceiver do
RTPTransceiver
"""

alias ExWebRTC.{RTPCodecParameters, RTPReceiver}

@type t() :: %__MODULE__{
mid: String.t(),
direction: :sendonly | :recvonly | :sendrecv | :inactive | :stopped,
kind: :audio | :video
kind: :audio | :video,
hdr_exts: [],
codecs: [],
rtp_receiver: nil
}

@enforce_keys [:mid, :direction, :kind]
defstruct @enforce_keys
defstruct @enforce_keys ++ [codecs: [], hdr_exts: [], rtp_receiver: %RTPReceiver{}]

@doc false
def find_by_mid(transceivers, mid) do
Expand All @@ -30,9 +35,41 @@ defmodule ExWebRTC.RTPTransceiver do
List.replace_at(transceivers, idx, update(tr, mline))

nil ->
transceivers ++ [%__MODULE__{mid: mid, direction: :recvonly, kind: mline.type}]
codecs = get_codecs(mline)
hdr_exts = ExSDP.Media.get_attributes(mline, ExSDP.Attribute.Extmap)
ssrc = ExSDP.Media.get_attribute(mline, ExSDP.Attribute.SSRC)

tr = %__MODULE__{
mid: mid,
direction: :recvonly,
kind: mline.type,
codecs: codecs,
hdr_exts: hdr_exts,
rtp_receiver: %RTPReceiver{ssrc: ssrc}
}

transceivers ++ [tr]
end
end

defp update(transceiver, _mline), do: transceiver
defp update(transceiver, mline) do
codecs = get_codecs(mline)
hdr_exts = ExSDP.Media.get_attributes(mline, ExSDP.Attribute.Extmap)
%__MODULE__{transceiver | codecs: codecs, hdr_exts: hdr_exts}
end

defp get_codecs(mline) do
rtp_mappings = ExSDP.Media.get_attributes(mline, ExSDP.Attribute.RTPMapping)
fmtps = ExSDP.Media.get_attributes(mline, ExSDP.Attribute.FMTP)
all_rtcp_fbs = ExSDP.Media.get_attributes(mline, ExSDP.Attribute.RTCPFeedback)

for rtp_mapping <- rtp_mappings do
fmtp = Enum.find(fmtps, fn fmtp -> fmtp.pt == rtp_mapping.payload_type end)

rtcp_fbs =
Enum.filter(all_rtcp_fbs, fn rtcp_fb -> rtcp_fb.pt == rtp_mapping.payload_type end)

RTPCodecParameters.new(mline.type, rtp_mapping, fmtp, rtcp_fbs)
end
end
end
3 changes: 3 additions & 0 deletions test/peer_connection_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ defmodule ExWebRTC.PeerConnectionTest do
"""

test "transceivers" do
IO.inspect(ExSDP.parse(@audio_video_offer))
{:ok, pc} = PeerConnection.start_link()

offer = %SessionDescription{type: :offer, sdp: @single_audio_offer}
Expand All @@ -92,6 +93,8 @@ defmodule ExWebRTC.PeerConnectionTest do
offer = %SessionDescription{type: :offer, sdp: @audio_video_offer}
:ok = PeerConnection.set_remote_description(pc, offer)

IO.inspect(PeerConnection.get_transceivers(pc))

Check warning on line 96 in test/peer_connection_test.exs

View workflow job for this annotation

GitHub Actions / Lint (OTP 26 / Elixir 1.15)

There should be no calls to IO.inspect/1.

assert_receive {:ex_webrtc, ^pc, {:track, %MediaStreamTrack{mid: "1", kind: :video}}}
refute_receive {:ex_webrtc, ^pc, {:track, %MediaStreamTrack{}}}
end
Expand Down

0 comments on commit 78457a0

Please sign in to comment.