1
1
defmodule ExWebRTC.SDPUtils do
2
2
@ moduledoc false
3
3
4
+ alias ExWebRTC.SDPUtils
4
5
alias ExRTP.Packet.Extension
5
6
alias ExSDP.Attribute.Extmap
6
7
7
8
alias ExWebRTC.RTPCodecParameters
8
9
9
10
@ type extension ( ) :: { Extension.SourceDescription , atom ( ) }
10
11
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
12
@ spec ensure_mid ( ExSDP . t ( ) ) :: :ok | { :error , :missing_mid | :duplicated_mid }
20
13
def ensure_mid ( sdp ) do
21
14
sdp . media
@@ -42,11 +35,7 @@ defmodule ExWebRTC.SDPUtils do
42
35
def ensure_bundle ( sdp ) do
43
36
groups = ExSDP . get_attributes ( sdp , ExSDP.Attribute.Group )
44
37
45
- mline_mids =
46
- Enum . map ( sdp . media , fn media ->
47
- { :mid , mid } = ExSDP . get_attribute ( media , :mid )
48
- mid
49
- end )
38
+ mline_mids = get_bundle_mids ( sdp . media )
50
39
51
40
case filter_groups ( groups , "BUNDLE" ) do
52
41
[ % ExSDP.Attribute.Group { semantics: "BUNDLE" , mids: group_mids } ] ->
@@ -78,6 +67,26 @@ defmodule ExWebRTC.SDPUtils do
78
67
end
79
68
end
80
69
70
+ @ spec get_media_direction ( ExSDP.Media . t ( ) ) ::
71
+ :sendrecv | :sendonly | :recvonly | :inactive | nil
72
+ def get_media_direction ( media ) do
73
+ Enum . find ( media . attributes , fn attr ->
74
+ attr in [ :sendrecv , :sendonly , :recvonly , :inactive ]
75
+ end )
76
+ end
77
+
78
+ @ spec get_bundle_mids ( [ ExSDP.Media . t ( ) ] ) :: [ String . t ( ) ]
79
+ def get_bundle_mids ( mlines ) do
80
+ # rejected m-lines are not included in the BUNDLE group
81
+ Enum . map ( mlines , fn mline ->
82
+ unless SDPUtils . rejected? ( mline ) do
83
+ { :mid , mid } = ExSDP . get_attribute ( mline , :mid )
84
+ mid
85
+ end
86
+ end )
87
+ |> Enum . reject ( & ( & 1 == nil ) )
88
+ end
89
+
81
90
@ spec get_ice_credentials ( ExSDP . t ( ) ) ::
82
91
{ :ok , { binary ( ) , binary ( ) } }
83
92
| { :error ,
@@ -129,9 +138,21 @@ defmodule ExWebRTC.SDPUtils do
129
138
130
139
@ spec add_ice_candidates ( ExSDP . t ( ) , [ String . t ( ) ] ) :: ExSDP . t ( )
131
140
def add_ice_candidates ( sdp , candidates ) do
141
+ # we only add candidates to the first mline
142
+ # as we don't support bundle-policies other than "max-bundle"
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