@@ -8,14 +8,6 @@ defmodule ExWebRTC.SDPUtils do
8
8
9
9
@ type extension ( ) :: { Extension.SourceDescription , atom ( ) }
10
10
11
- @ spec get_media_direction ( ExSDP.Media . t ( ) ) ::
12
- :sendrecv | :sendonly | :recvonly | :inactive | nil
13
- def get_media_direction ( media ) do
14
- Enum . find ( media . attributes , fn attr ->
15
- attr in [ :sendrecv , :sendonly , :recvonly , :inactive ]
16
- end )
17
- end
18
-
19
11
@ spec ensure_mid ( ExSDP . t ( ) ) :: :ok | { :error , :missing_mid | :duplicated_mid }
20
12
def ensure_mid ( sdp ) do
21
13
sdp . media
@@ -42,11 +34,7 @@ defmodule ExWebRTC.SDPUtils do
42
34
def ensure_bundle ( sdp ) do
43
35
groups = ExSDP . get_attributes ( sdp , ExSDP.Attribute.Group )
44
36
45
- mline_mids =
46
- Enum . map ( sdp . media , fn media ->
47
- { :mid , mid } = ExSDP . get_attribute ( media , :mid )
48
- mid
49
- end )
37
+ mline_mids = get_bundle_mids ( sdp . media )
50
38
51
39
case filter_groups ( groups , "BUNDLE" ) do
52
40
[ % ExSDP.Attribute.Group { semantics: "BUNDLE" , mids: group_mids } ] ->
@@ -78,6 +66,26 @@ defmodule ExWebRTC.SDPUtils do
78
66
end
79
67
end
80
68
69
+ @ spec get_media_direction ( ExSDP.Media . t ( ) ) ::
70
+ :sendrecv | :sendonly | :recvonly | :inactive | nil
71
+ def get_media_direction ( media ) do
72
+ Enum . find ( media . attributes , fn attr ->
73
+ attr in [ :sendrecv , :sendonly , :recvonly , :inactive ]
74
+ end )
75
+ end
76
+
77
+ @ spec get_bundle_mids ( [ ExSDP.Media . t ( ) ] ) :: [ String . t ( ) ]
78
+ def get_bundle_mids ( mlines ) do
79
+ # rejected m-lines are not included in the BUNDLE group
80
+ Enum . map ( mlines , fn mline ->
81
+ unless rejected? ( mline ) do
82
+ { :mid , mid } = ExSDP . get_attribute ( mline , :mid )
83
+ mid
84
+ end
85
+ end )
86
+ |> Enum . reject ( & ( & 1 == nil ) )
87
+ end
88
+
81
89
@ spec get_ice_credentials ( ExSDP . t ( ) ) ::
82
90
{ :ok , { binary ( ) , binary ( ) } }
83
91
| { :error ,
@@ -129,9 +137,22 @@ defmodule ExWebRTC.SDPUtils do
129
137
130
138
@ spec add_ice_candidates ( ExSDP . t ( ) , [ String . t ( ) ] ) :: ExSDP . t ( )
131
139
def add_ice_candidates ( sdp , candidates ) do
140
+ # We only add candidates to the first mline
141
+ # as we don't support bundle-policies other than "max-bundle".
142
+ # See RFC 8829, sec. 4.1.1.
132
143
candidates = Enum . map ( candidates , & { "candidate" , & 1 } )
133
- media = Enum . map ( sdp . media , & ExSDP . add_attributes ( & 1 , candidates ) )
134
- % ExSDP { sdp | media: media }
144
+
145
+ if sdp . media != [ ] do
146
+ mline =
147
+ sdp . media
148
+ |> List . first ( )
149
+ |> ExSDP . add_attributes ( candidates )
150
+
151
+ media = List . replace_at ( sdp . media , 0 , mline )
152
+ % ExSDP { sdp | media: media }
153
+ else
154
+ sdp
155
+ end
135
156
end
136
157
137
158
@ spec get_dtls_role ( ExSDP . t ( ) ) ::
@@ -284,7 +305,13 @@ defmodule ExWebRTC.SDPUtils do
284
305
end
285
306
286
307
@ spec rejected? ( ExSDP.Media . t ( ) ) :: boolean ( )
287
- def rejected? ( % ExSDP.Media { port: 0 } ) , do: true
308
+ def rejected? ( % ExSDP.Media { port: 0 } = media ) do
309
+ # An m-line is only rejected when its port is set to 0,
310
+ # and there is no `bundle-only` attribute.
311
+ # See RFC 8843, sec. 6.
312
+ "bundle-only" not in media . attributes
313
+ end
314
+
288
315
def rejected? ( % ExSDP.Media { } ) , do: false
289
316
290
317
defp do_get_ice_credentials ( sdp_or_mline ) do
0 commit comments