diff --git a/lib/ex_webrtc/peer_connection.ex b/lib/ex_webrtc/peer_connection.ex index 1c6c6f7b..f31bee9a 100644 --- a/lib/ex_webrtc/peer_connection.ex +++ b/lib/ex_webrtc/peer_connection.ex @@ -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}} + + # media = Enum.map(state.transceivers, fn transceiver -> to_sdp_media(transceiver, state) end) + sdp = ExSDP.parse!(@dummy_sdp) media = hd(sdp.media) @@ -180,6 +184,12 @@ defmodule ExWebRTC.PeerConnection do {:reply, {:ok, desc}, state} end + defp to_sdp_media(transceiver, state) do + # %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 diff --git a/lib/ex_webrtc/rtp_codec_parameters.ex b/lib/ex_webrtc/rtp_codec_parameters.ex new file mode 100644 index 00000000..d240f6b2 --- /dev/null +++ b/lib/ex_webrtc/rtp_codec_parameters.ex @@ -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 diff --git a/lib/ex_webrtc/rtp_receiver.ex b/lib/ex_webrtc/rtp_receiver.ex new file mode 100644 index 00000000..e2c65c67 --- /dev/null +++ b/lib/ex_webrtc/rtp_receiver.ex @@ -0,0 +1,5 @@ +defmodule ExWebRTC.RTPReceiver do + + defstruct [:ssrc] + +end \ No newline at end of file diff --git a/lib/ex_webrtc/rtp_transceiver.ex b/lib/ex_webrtc/rtp_transceiver.ex index bf5d0375..5de592fb 100644 --- a/lib/ex_webrtc/rtp_transceiver.ex +++ b/lib/ex_webrtc/rtp_transceiver.ex @@ -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 @@ -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 diff --git a/test/peer_connection_test.exs b/test/peer_connection_test.exs index 2c424b0a..0d5aef20 100644 --- a/test/peer_connection_test.exs +++ b/test/peer_connection_test.exs @@ -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} @@ -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)) + assert_receive {:ex_webrtc, ^pc, {:track, %MediaStreamTrack{mid: "1", kind: :video}}} refute_receive {:ex_webrtc, ^pc, {:track, %MediaStreamTrack{}}} end