Skip to content

Commit

Permalink
Add ExSDP.get_attribute(s)/2 (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 authored Oct 24, 2023
1 parent 2584ad1 commit 42e78f9
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 48 deletions.
9 changes: 8 additions & 1 deletion lib/ex_sdp.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ defmodule ExSDP do
RepeatTimes,
Serializer,
Timezone,
Timing
Timing,
Utils
}

@enforce_keys [:origin]
Expand Down Expand Up @@ -101,6 +102,12 @@ defmodule ExSDP do
@spec add_attributes(sdp :: t(), attributes :: [Attribute.t()]) :: t()
def add_attributes(sdp, attributes) when is_list(attributes),
do: Map.update!(sdp, :attributes, &(&1 ++ attributes))

@spec get_attribute(sdp :: t(), key :: module() | atom() | binary()) :: Attribute.t() | nil
def get_attribute(sdp, key), do: Utils.get_attribute(sdp, key)

@spec get_attributes(sdp :: t(), key :: module() | atom() | binary()) :: [Attribute.t()]
def get_attributes(sdp, key), do: Utils.get_attributes(sdp, key)
end

defimpl String.Chars, for: ExSDP do
Expand Down
50 changes: 4 additions & 46 deletions lib/ex_sdp/media.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,8 @@ defmodule ExSDP.Media do
Attribute,
Bandwidth,
ConnectionData,
Encryption
}

alias ExSDP.Attribute.{
Extmap,
FMTP,
Group,
MSID,
RTCPFeedback,
RTPMapping,
SSRC,
SSRCGroup
Encryption,
Utils
}

@enforce_keys [:type, :port, :protocol, :fmt]
Expand Down Expand Up @@ -57,18 +47,6 @@ defmodule ExSDP.Media do
"""
@type type :: :audio | :video | :text | :application | :message | binary()

# For searching struct attributes by atoms
@struct_attr_keys %{
:rtpmap => RTPMapping,
:msid => MSID,
:fmtp => FMTP,
:ssrc => SSRC,
:ssrc_group => SSRCGroup,
:rtcp_feedback => RTCPFeedback,
:group => Group,
:extmap => Extmap
}

@spec new(
type :: type(),
port :: :inet.port_number(),
Expand All @@ -94,30 +72,10 @@ defmodule ExSDP.Media do
do: Map.update!(media, :attributes, &(&1 ++ attributes))

@spec get_attribute(media :: t(), key :: module() | atom() | binary()) :: Attribute.t() | nil
def get_attribute(media, key) do
key = Map.get(@struct_attr_keys, key, key)

media.attributes
|> Enum.find(fn
%module{} -> module == key
{k, _v} -> k == key
# for flag attributes
k -> k == key
end)
end
def get_attribute(media, key), do: Utils.get_attribute(media, key)

@spec get_attributes(media :: t(), key :: module() | atom() | binary()) :: [Attribute.t()]
def get_attributes(media, key) do
key = Map.get(@struct_attr_keys, key, key)

media.attributes
|> Enum.filter(fn
%module{} -> module == key
{k, _v} -> k == key
# for flag attributes
k -> k == key
end)
end
def get_attributes(media, key), do: Utils.get_attributes(media, key)

@spec parse(binary()) :: {:ok, t()} | {:error, :invalid_media_spec | :malformed_port_number}
def parse(media) do
Expand Down
53 changes: 53 additions & 0 deletions lib/ex_sdp/utils.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,59 @@
defmodule ExSDP.Utils do
@moduledoc false

alias ExSDP.{Attribute, Media}

alias ExSDP.Attribute.{
Extmap,
FMTP,
Group,
MSID,
RTCPFeedback,
RTPMapping,
SSRC,
SSRCGroup
}

# For searching struct attributes by atoms
@struct_attr_keys %{
:extmap => Extmap,
:fmtp => FMTP,
:group => Group,
:msid => MSID,
:rtcp_feedback => RTCPFeedback,
:rtpmap => RTPMapping,
:ssrc => SSRC,
:ssrc_group => SSRCGroup
}

@spec get_attribute(sdp_or_media :: ExSDP.t() | Media.t(), key :: module() | atom() | binary()) ::
Attribute.t() | nil
def get_attribute(sdp_or_media, key) do
key = Map.get(@struct_attr_keys, key, key)

sdp_or_media.attributes
|> Enum.find(fn
%module{} -> module == key
{k, _v} -> k == key
# for flag attributes
k -> k == key
end)
end

@spec get_attributes(sdp_or_media :: ExSDP.t() | Media.t(), key :: module() | atom() | binary()) ::
[Attribute.t()]
def get_attributes(sdp_or_media, key) do
key = Map.get(@struct_attr_keys, key, key)

sdp_or_media.attributes
|> Enum.filter(fn
%module{} -> module == key
{k, _v} -> k == key
# for flag attributes
k -> k == key
end)
end

@spec split(String.t(), String.t() | [String.t()] | :binary.cp() | Regex.t(), any) ::
{:error, :too_few_fields} | {:ok, [String.t()]}
def split(origin, delim, expected_len) do
Expand Down
2 changes: 1 addition & 1 deletion test/ex_sdp/media_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ defmodule ExSDP.MediaTest do
end

describe "Utils functions" do
test "gets attribute by module" do
test "gets attribute by atom or module" do
rtpmap = %RTPMapping{clock_rate: 8000, encoding: "L8", params: 1, payload_type: 96}

ssrc = %SSRC{id: 12_345, attribute: "cname", value: "HPd3XfRHXYUxzfsJ"}
Expand Down
38 changes: 38 additions & 0 deletions test/sdp_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,42 @@ defmodule ExSDPTest do
end
end
end

describe "get_attribute/2" do
test "gets attribute by atom, binary or module" do
sdp =
ExSDP.new()
|> ExSDP.add_attribute({"key", "value"})
|> ExSDP.add_attribute(:recvonly)
|> ExSDP.add_attribute(%ExSDP.Attribute.Group{semantics: "BUNDLE", mids: [0, 1, 2]})

assert :recvonly == ExSDP.get_attribute(sdp, :recvonly)
assert {"key", "value"} == ExSDP.get_attribute(sdp, "key")

assert %ExSDP.Attribute.Group{semantics: "BUNDLE", mids: [0, 1, 2]} ==
ExSDP.get_attribute(sdp, ExSDP.Attribute.Group)

assert %ExSDP.Attribute.Group{semantics: "BUNDLE", mids: [0, 1, 2]} ==
ExSDP.get_attribute(sdp, :group)

assert nil == ExSDP.get_attribute(sdp, :non_existing_atom)
assert nil == ExSDP.get_attribute(sdp, ExSDP.Attribute.NonExistingModule)
assert nil == ExSDP.get_attribute(sdp, "non_existing_string")
end
end

describe "get_attributes/2" do
test "gets multiple attributes by module" do
sdp =
ExSDP.new()
|> ExSDP.add_attribute(%ExSDP.Attribute.Group{semantics: "BUNDLE", mids: [0, 1, 2]})
|> ExSDP.add_attribute(%ExSDP.Attribute.Group{semantics: "BUNDLE", mids: [3, 4, 5]})

assert [
%ExSDP.Attribute.Group{semantics: "BUNDLE", mids: [0, 1, 2]},
%ExSDP.Attribute.Group{semantics: "BUNDLE", mids: [3, 4, 5]}
] ==
ExSDP.get_attributes(sdp, ExSDP.Attribute.Group)
end
end
end

0 comments on commit 42e78f9

Please sign in to comment.