@irbisadm/simple-sdp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Igor Sheko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ const e=(e,t)=>e.replace(`${t}=`,"").split(" "),t=/^\d+$/,r=e=>{if(!t.test(e))throw new Error(`"${e}" is not an integer.`);return parseInt(e)},s=e=>{const t={d:86400,h:86400,m:60,s:1};if(Object.keys(t).includes(e.slice(-1))){const s=e.slice(-1),n=e.slice(0,e.length-1),a=r(n);return t[s]*a}return r(e)},n=e=>e.split("/").map((e=>parseInt(e))),a=t=>{const r=e(t,"m");switch(r[0]){case"audio":return(e=>{const t={type:e[0],ports:n(e[1]),proto:e[2]};if(e.length>3){t.fmtp=[];for(let r=3;r<e.length;r++)t.fmtp.push(parseInt(e[r]))}return t})(r);case"application":return(e=>({type:"application",ports:n(e[1]),proto:e[2],description:e[3]}))(r);default:return(e=>{const t={type:e[0],ports:n(e[1]),proto:e[2]};if(e.length>3){t.fmtp=[];for(let r=3;r<e.length;r++)t.fmtp.push(e[r])}return t})(r)}},i=e=>{const t=e.replace("k=",""),[s,n]=t.split(":");return{bwtype:s,bandwidth:r(n)}},o=t=>{const r=e(t,"c");return{netType:"IN"===r[0]?"IN":void 0,addrType:["IP4","IP6"].includes(r[1])?r[1]:void 0,connectionAddress:r[2]}},c=(e,t,r)=>{e.ice||(e.ice={ufrag:"",pwd:"",options:[]}),e.ice[t]=r},p=(e,t,r)=>{e.dtls||(e.dtls={algorithm:"",fingerprint:"",setup:"actpass"}),e.dtls[t]=r},l=(e,t)=>{e.attributes||(e.attributes={});const r=t.replace("a=",""),[s,...n]=r.split(":"),a=n.join(":");switch(s){case"mid":e.mid=a;break;case"ice-ufrag":c(e,"ufrag",a);break;case"ice-pwd":c(e,"pwd",a);break;case"ice-options":c(e,"options",a.split(" "));break;case"fingerprint":{const[t,r]=a.split(" ");p(e,"algorithm",t),p(e,"fingerprint",r);break}case"setup":p(e,"setup",a);break;case"sendrecv":e.direction=s;break;default:if(e.attributes[s]){Array.isArray(e.attributes[s])||(e.attributes[s]=[e.attributes[s]]),e.attributes[s].push(a);break}e.attributes[s]=0===n.length||a}return e},u=t=>{const r=t.split("\r\n"),n={};let c=null;return r.forEach(((t,p)=>{if(0!==t.length){if("="!==t[1])throw new Error(`Invalid line structure in line "${t}"`);switch(t[0]){case"v":n.protocolVersion=(e=>parseInt(e.replace("v=","")))(t);break;case"o":n.origin=(t=>{const r=e(t,"o"),s=parseInt(r[2]),n="IN"===r[3]?"IN":void 0,a=["IP4","IP6"].includes(r[4])?r[4]:void 0;return{username:r[0],sessId:r[1],sessVersion:s,netType:n,addrType:a,unicastAddress:r[5]}})(t);break;case"s":n.sessionName=(e=>e.replace("s=",""))(t);break;case"t":n.timing||(n.timing=[]),n.timing.push((t=>{const r=e(t,"t"),s=parseInt(r[0]),n=isNaN(s)?0:s,a=parseInt(r[1]);return{startTime:n,stopTime:isNaN(a)?0:a}})(t));break;case"r":n.repeat||(n.repeat=[]),n.repeat.push((t=>{const r=e(t,"r"),n={repeatInterval:s(r[0]),activeDuration:s(r[0])};if(r.length>3){n.offsets=[];for(let e=2;e<r.length;e++)n.offsets.push(s(r[e]))}return n})(t));break;case"i":n.sessionInformation=(e=>e.replace("i=",""))(t);break;case"u":n.sessionInformation=(e=>e.replace("u=",""))(t);break;case"e":n.emailAddress=(e=>e.replace("e=",""))(t);break;case"p":n.phoneNumber=(e=>e.replace("p=",""))(t);break;case"k":n.encryptionKeys||(n.encryptionKeys=[]),n.encryptionKeys.push((e=>{const t=e.replace("k=",""),[r,s]=t.split(":");if(!["clear","base64","uri","prompt"].includes(r))throw new Error(`Encryption method "${r}" is not supported by RFC-4566`);return{method:r,encryptionKey:s}})(t));break;case"m":const r=a(t);c=r,n.media||(n.media=[]),n.media.push(r);break;case"b":c?c.bandwidthInformation=i(t):n.bandwidthInformation=i(t);break;case"c":c?c.connectionInformation=o(t):n.connectionInformation=o(t);break;case"a":l(c||n,t);break;default:throw Error(`Unknown line type "${t[0]}"`)}}else if(p!==r.length-1)throw new Error(`Empty line at "${p}" after ${r[p-1]}`)})),n},d={parse:u,isValid:(e,t=!1)=>{try{return u(e),!0}catch(e){return t&&console.error(e),!1}}},b="0.1.0";export{d as sdpReader,b as version};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@irbisadm/simple-sdp",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "description": "WebRTC SDP parser and validator influenced by pjsip library.",
6
+ "author": {
7
+ "email": "i@irbisadm.dev",
8
+ "name": "Igor Sheko",
9
+ "url": "https://www.linkedin.com/in/irbisadm/"
10
+ },
11
+ "private": false,
12
+ "repository": "https://github.com/irbisadm/simple-sdp",
13
+ "bugs": "https://github.com/irbisadm/simple-sdp/issues",
14
+ "module": "./dist/index.mjs",
15
+ "main": "./dist/index.mjs",
16
+ "types": "./types/index.d.ts",
17
+ "files": [
18
+ "./dist/index.mjs",
19
+ "./types/index.d.ts",
20
+ "./readme.md"
21
+ ],
22
+ "devDependencies": {
23
+ "@rollup/plugin-replace": "^5.0.2",
24
+ "@rollup/plugin-terser": "^0.4.0",
25
+ "@rollup/plugin-typescript": "^11.0.0",
26
+ "@types/jest": "^29.5.0",
27
+ "@types/node": "^18.14.0",
28
+ "jest": "^29.5.0",
29
+ "rollup": "^3.17.1",
30
+ "rollup-plugin-dts": "^5.2.0",
31
+ "ts-jest": "^29.0.5",
32
+ "tslib": "^2.5.0",
33
+ "typescript": "^5.0.2"
34
+ },
35
+ "engines": {
36
+ "node": ">=17.0.0"
37
+ },
38
+ "scripts": {
39
+ "build": "rollup -c",
40
+ "test": "jest"
41
+ }
42
+ }
package/readme.md ADDED
@@ -0,0 +1,23 @@
1
+ ![license MIT](https://badgen.net/npm/license/@irbisadm/simple-sdp)
2
+ ![license MIT](https://badgen.net/npm/v/@irbisadm/simple-sdp)
3
+ ![license MIT](https://badgen.net/npm/types/@irbisadm/simple-sdp)
4
+ ![license MIT](https://badgen.net/bundlephobia/minzip/@irbisadm/simple-sdp)
5
+ ![license MIT](https://badgen.net/bundlephobia/dependency-count/@irbisadm/simple-sdp)
6
+ ![license MIT](https://badgen.net/bundlephobia/tree-shaking/@irbisadm/simple-sdp)
7
+ # Simple SDP tools
8
+ This project is a TypeScript library that provides a comprehensive set of tools for working with Session Description Protocol (SDP) messages in WebRTC applications. SDP is a text-based format that describes the multimedia communication sessions between peers.
9
+ With this library, you can:
10
+ - Parse and generate SDP messages from and to TypeScript objects
11
+ - Manipulate SDP data by adding, removing, or modifying media streams, codecs, candidates, and other attributes
12
+ - Validate SDP messages according to the [RFC 4566](https://www.rfc-editor.org/rfc/rfc8866) specification and WebRTC best practices
13
+ - Track and verify the SDP history for a single PeerConnection instance
14
+
15
+ This project aims to help WebRTC beginners learn the SDP format and its components, as well as provide a clear and easy-to-use TypeScript API for advanced users. This project was inspired by the [pjsip](https://github.com/pjsip/pjproject) library written in C++.
16
+
17
+ You can use the library with Node.js as well in any modern web browser.
18
+
19
+ ## SIP disclaimer
20
+ Probably this library can be used for parsing and creating SDP for SIP.
21
+ I can see a theoretical problems here because some SIP devices are complained only with older SDP RFC: [RFC 4566](https://www.rfc-editor.org/rfc/rfc4566.html) or [RFC 2327](https://www.rfc-editor.org/rfc/rfc2327).
22
+
23
+ I'm not an expert in SIP and have no test environment to check compatibility with that standards. If you can help with tests or expertise with SIP, please send me a message to [i@irbisadm.dev](mailto:i@irbisadm.dev)
@@ -0,0 +1,284 @@
1
+ interface SdpCommonAttributes {
2
+ attributes?: Record<string, SdpAttribute>;
3
+ ice?: SdpIceAttributes;
4
+ dtls?: SdpDtlsAttribute;
5
+ }
6
+ interface Sdp extends SdpCommonAttributes {
7
+ protocolVersion?: number;
8
+ /**
9
+ * The "o=" field gives the originator of the session (her username and the address of the user's host) plus a session
10
+ * identifier and version number:
11
+ */
12
+ origin?: SdpOrigin;
13
+ /**
14
+ * The "s=" field is the textual session name. There MUST be one and only one "s=" field per session description. The
15
+ * "s=" field MUST NOT be empty and SHOULD contain ISO 10646 characters (but see also the "a=charset" attribute).
16
+ * If a session has no meaningful name, the value "s= " SHOULD be used (i.e., a single space as the session name).
17
+ */
18
+ sessionName?: string;
19
+ /**
20
+ *
21
+ * The "i=" field provides textual information about the session. There MUST be at most one session-level "i="
22
+ * field per session description, and at most one "i=" field per media. If the "a=charset" attribute is present,
23
+ * it specifies the character set used in the "i=" field. If the "a=charset" attribute is not present, the "i="
24
+ * field MUST contain ISO 10646 characters in UTF-8 encoding.
25
+ * A single "i=" field MAY also be used for each media definition. In media definitions, "i=" fields are
26
+ * primarily intended for labelling media streams. As such, they are most likely to be useful when a single
27
+ * session has more than one distinct media stream of the same media type. An example would be two different
28
+ * whiteboards, one for slides and one for feedback and questions. The "i=" field is intended to provide a
29
+ * free-form human-readable description of the session or the purpose of a media stream. It is not suitable
30
+ * for parsing by automata.
31
+ */
32
+ sessionInformation?: string;
33
+ /**
34
+ * A URI is a Uniform Resource Identifier as used by WWW clients. The URI should be a pointer to additional
35
+ * information about the session. This field is OPTIONAL, but if it is present it MUST be specified before the
36
+ * first media field. No more than one URI field is allowed per session description.
37
+ */
38
+ uri?: string;
39
+ emailAddress?: string;
40
+ phoneNumber?: string;
41
+ encryptionKeys?: SdpEncryptionKey[];
42
+ /**
43
+ * The "t=" lines specify the start and stop times for a session. Multiple "t=" lines MAY be used if a session is
44
+ * active at multiple irregularly spaced times; each additional "t=" line specifies an additional period of time for
45
+ * which the session will be active. If the session is active at regular times, an "r=" line (see below) should be
46
+ * used in addition to, and following, a "t=" line -- in which case the "t=" line specifies the start and stop times
47
+ * of the repeat sequence.
48
+ */
49
+ timing?: SdpTiming[];
50
+ /**
51
+ * "r=" fields specify repeat times for a session. For example, if a session is active at 10am on Monday and 11am on
52
+ * Tuesday for one hour each week for three months, then the <start-time> in the corresponding "t=" field would be the
53
+ * NTP representation of 10am on the first Monday, the <repeat interval> would be 1 week, the <active duration> would
54
+ * be 1 hour, and the offsets would be zero and 25 hours. The corresponding "t=" field stop time would be the NTP
55
+ * representation of the end of the last session three months later.
56
+ */
57
+ repeat?: SdpRepeatTimes[];
58
+ media?: SdpMediaSection[];
59
+ bandwidthInformation?: SdpBandwidthInformation;
60
+ connectionInformation?: SdpConnectionInformation;
61
+ }
62
+ /**
63
+ * The "o=" field gives the originator of the session (her username and the address of the user's host) plus a session
64
+ * identifier and version number:
65
+ */
66
+ interface SdpOrigin {
67
+ /**
68
+ * <username> is the user's login on the originating host, or it is "-" if the originating host does not support
69
+ * the concept of user IDs. The <username> MUST NOT contain spaces.
70
+ */
71
+ username?: string;
72
+ /**
73
+ * <sess-id> is a numeric string such that the tuple of <username>, <sess-id>, <nettype>, <addrtype>, and
74
+ * <unicast-address> forms a globally unique identifier for the session. The method of <sess-id> allocation is up
75
+ * to the creating tool, but it has been suggested that a Network Time Protocol (NTP) format timestamp be used to
76
+ * ensure uniqueness
77
+ */
78
+ sessId?: string;
79
+ /**
80
+ * <sess-version> is a version number for this session description. Its usage is up to the creating tool, so long as
81
+ * <sess-version> is increased when a modification is made to the session data. Again, it is RECOMMENDED that an NTP
82
+ * format timestamp is used.
83
+ */
84
+ sessVersion?: number;
85
+ /**
86
+ * <nettype> is a text string giving the type of network. Initially "IN" is defined to have the meaning "Internet",
87
+ * but other values MAY be registered in the future.
88
+ */
89
+ netType?: 'IN';
90
+ /**
91
+ * <addrtype> is a text string giving the type of the address that follows. Initially "IP4" and "IP6" are defined,
92
+ * but other values MAY be registered in the future
93
+ */
94
+ addrType?: 'IP4' | 'IP6';
95
+ /**
96
+ * <unicast-address> is the address of the machine from which the session was created. For an address type of IP4,
97
+ * this is either the fully qualified domain name of the machine or the dotted-decimal representation of the
98
+ * IP version 4 address of the machine. For an address type of IP6, this is either the fully qualified domain name of
99
+ * the machine or the compressed textual representation of the IP version 6 address of the machine. For both IP4
100
+ * and IP6, the fully qualified domain name is the form that SHOULD be given unless this is unavailable, in which case
101
+ * the globally unique address MAY be substituted. A local IP address MUST NOT be used in any context where the SDP
102
+ * description might leave the scope in which the address is meaningful (for example, a local address MUST NOT be
103
+ * included in an application-level referral that might leave the scope).
104
+ */
105
+ unicastAddress: string;
106
+ }
107
+ /**
108
+ * The "t=" lines specify the start and stop times for a session. Multiple "t=" lines MAY be used if a session is
109
+ * active at multiple irregularly spaced times; each additional "t=" line specifies an additional period of time for
110
+ * which the session will be active. If the session is active at regular times, an "r=" line (see below) should be
111
+ * used in addition to, and following, a "t=" line -- in which case the "t=" line specifies the start and stop times
112
+ * of the repeat sequence.
113
+ */
114
+ interface SdpTiming {
115
+ startTime: number;
116
+ stopTime: number;
117
+ }
118
+ /**
119
+ * "r=" fields specify repeat times for a session. For example, if a session is active at 10am on Monday and 11am on
120
+ * Tuesday for one hour each week for three months, then the <start-time> in the corresponding "t=" field would be the
121
+ * NTP representation of 10am on the first Monday, the <repeat interval> would be 1 week, the <active duration> would
122
+ * be 1 hour, and the offsets would be zero and 25 hours. The corresponding "t=" field stop time would be the NTP
123
+ * representation of the end of the last session three months later.
124
+ */
125
+ interface SdpRepeatTimes {
126
+ repeatInterval: number;
127
+ activeDuration: number;
128
+ offsets?: number[];
129
+ }
130
+ /**
131
+ * If transported over a secure and trusted channel, the Session Description Protocol MAY be used to convey encryption
132
+ * keys. A simple mechanism for key exchange is provided by the key field ("k="), although this is primarily
133
+ * supported for compatibility with older implementations and its use is NOT RECOMMENDED. Work is in progress to define
134
+ * new key exchange mechanisms for use with SDP [27] [28], and it is expected that new applications will use
135
+ * those mechanisms.
136
+ *
137
+ * A key field is permitted before the first media entry (in which case it applies to all media in the session), or
138
+ * for each media entry as required. The format of keys and their usage are outside the scope of this document, and
139
+ * the key field provides no way to indicate the encryption algorithm to be used, key type, or other information about
140
+ * the key: this is assumed to be provided by the higher-level protocol using SDP. If there is a need to convey this
141
+ * information within SDP, the extensions mentioned previously SHOULD be used. Many security protocols require two
142
+ * keys: one for confidentiality, another for integrity. This specification does not support transfer of two keys.
143
+ */
144
+ interface SdpEncryptionKey {
145
+ /**
146
+ * The method indicates the mechanism to be used to obtain a usable key by external means, or from the encoded
147
+ * encryption key given. The following methods are defined:
148
+ *
149
+ * clear
150
+ * The encryption key is included untransformed in this key field. This method MUST NOT be used unless it can be
151
+ * guaranteed that the SDP is conveyed over a secure channel. The encryption key is interpreted as text according
152
+ * to the charset attribute; use the "k=base64:" method to convey characters that are otherwise prohibited in SDP.
153
+ *
154
+ * base64
155
+ * The encryption key is included in this key field but has been base64 encoded because it includes characters
156
+ * that are prohibited in SDP. This method MUST NOT be used unless it can be guaranteed that the SDP is
157
+ * conveyed over a secure channel.
158
+ *
159
+ * uri
160
+ * A Uniform Resource Identifier is included in the key field. The URI refers to the data containing the key,
161
+ * and may require additional authentication before the key can be returned. When a request is made to the given
162
+ * URI, the reply should specify the encoding for the key. The URI is often an Secure Socket Layer/Transport
163
+ * Layer Security (SSL/TLS)-protected HTTP URI ("https:"), although this is not required.
164
+ *
165
+ * prompt
166
+ * No key is included in this SDP description, but the session or media stream referred to by this key field
167
+ * is encrypted. The user should be prompted for the key when attempting to join the session, and this
168
+ * user-supplied key should then be used to decrypt the media streams. The use of user-specified keys is
169
+ * NOT RECOMMENDED, since such keys tend to have weak security properties.
170
+ */
171
+ method: 'clear' | 'base64' | 'uri' | 'prompt';
172
+ encryptionKey?: string;
173
+ }
174
+ /**
175
+ * The OPTIONAL "b=" line (bandwidth-field) denotes the proposed bandwidth to be used by the session or media
176
+ * description. The <bwtype> is an alphanumeric modifier that provides the meaning of the <bandwidth> number. Two
177
+ * values are defined in this specification, but other values MAY be registered in the future
178
+ * (see Section 8 and [RFC3556], [RFC3890]):
179
+ */
180
+ interface SdpBandwidthInformation {
181
+ /**
182
+ * CT
183
+ * If the bandwidth of a session is different from the bandwidth implicit from the scope, a "b=CT:" line SHOULD
184
+ * be supplied for the session giving the proposed upper limit to the bandwidth used
185
+ * (the "conference total" bandwidth). Similarly, if the bandwidth of bundled media streams [RFC8843] in
186
+ * an "m=" line is different from the implicit value from the scope, a "b=CT:" line SHOULD be supplied in the
187
+ * media level. The primary purpose of this is to give an approximate idea as to whether two or more sessions
188
+ * (or bundled media streams) can coexist simultaneously. Note that a "b=CT:" line gives a total bandwidth figure
189
+ * for all the media at all endpoints.
190
+ *
191
+ * The Mux Category for "b=CT:" is NORMAL. This is discussed in [RFC8859].
192
+ *
193
+ * AS
194
+ * The bandwidth is interpreted to be application specific (it will be the application's concept
195
+ * of maximum bandwidth). Normally, this will coincide with what is set on the application's "maximum bandwidth"
196
+ * control if applicable. For RTP-based applications, the "b=AS:" line gives the RTP "session bandwidth" as defined
197
+ * in Section 6.2 of [RFC3550]. Note that a "b=AS:" line gives a bandwidth figure for a single media at
198
+ * a single endpoint, although there may be many endpoints sending simultaneously.
199
+ *
200
+ * The Mux Category for "b=AS:" is SUM. This is discussed in [RFC8859].
201
+ *
202
+ * [RFC4566] defined an "X-" prefix for <bwtype> names. This was intended for experimental purposes only.
203
+ * Use of the "X-" prefix is NOT RECOMMENDED. Instead new (non "X-" prefix) <bwtype> names SHOULD be defined,
204
+ * and then MUST be registered with IANA in the standard namespace. SDP parsers MUST ignore bandwidth-fields with
205
+ * unknown <bwtype> names. The <bwtype> names MUST be alphanumeric and, although no length limit is given,
206
+ * it is recommended that they be short.
207
+ */
208
+ bwtype: string;
209
+ /**
210
+ * The <bandwidth> is interpreted as kilobits per second by default (including the transport and network-layer,
211
+ * but not the link-layer, overhead). The definition of a new <bwtype> modifier MAY specify that the bandwidth is
212
+ * to be interpreted in some alternative unit (the "CT" and "AS" modifiers defined in this memo use the default
213
+ * units).
214
+ */
215
+ bandwidth: number;
216
+ }
217
+ /**
218
+ * The "c=" line (connection-field) contains information necessary to establish a network connection.
219
+ * A session description MUST contain either at least one "c=" line in each media description or a single "c=" line
220
+ * at the session level. It MAY contain a single session-level "c=" line and additional media-level "c=" line(s)
221
+ * per-media-description, in which case the media-level values override the session-level settings for the
222
+ * respective media.
223
+ */
224
+ interface SdpConnectionInformation {
225
+ /**
226
+ * <nettype> is a text string giving the type of network. Initially "IN" is defined to have the meaning "Internet",
227
+ * but other values MAY be registered in the future.
228
+ */
229
+ netType?: 'IN';
230
+ /**
231
+ * <addrtype> is a text string giving the type of the address that follows. Initially "IP4" and "IP6" are defined,
232
+ * but other values MAY be registered in the future
233
+ */
234
+ addrType?: 'IP4' | 'IP6';
235
+ /**
236
+ * <base multicast address>[/<ttl>]/<number of addresses>
237
+ */
238
+ connectionAddress: string;
239
+ }
240
+ interface SdpBaseMediaSection extends SdpCommonAttributes {
241
+ mid?: string;
242
+ direction?: 'sendrecv' | 'sendonly' | 'recvonly' | 'inactive';
243
+ ports: number[];
244
+ proto: string;
245
+ bandwidthInformation?: SdpBandwidthInformation;
246
+ connectionInformation?: SdpConnectionInformation;
247
+ }
248
+ interface SdpAVMediaSection extends SdpBaseMediaSection {
249
+ type: 'audio' | 'video';
250
+ fmtp?: number[];
251
+ }
252
+ interface SdpAppMediaSection extends SdpBaseMediaSection {
253
+ type: 'application';
254
+ description?: string;
255
+ }
256
+ interface SdpOtherMediaSection extends SdpBaseMediaSection {
257
+ type: 'text' | 'message' | string;
258
+ fmtp?: string[];
259
+ }
260
+ type SdpMediaSection = SdpAVMediaSection | SdpAppMediaSection | SdpOtherMediaSection;
261
+ type SdpAttribute = string | boolean | string[];
262
+ interface SdpIceAttributes {
263
+ ufrag: string;
264
+ pwd: string;
265
+ options: string[];
266
+ }
267
+ interface SdpDtlsAttribute {
268
+ algorithm: string;
269
+ fingerprint: string;
270
+ setup: 'active' | 'passive' | 'actpass';
271
+ }
272
+ interface SdpPair {
273
+ offer: Sdp;
274
+ answer: Sdp;
275
+ }
276
+
277
+ declare const sdpReader: {
278
+ parse: (sdp: string) => Sdp;
279
+ isValid: (sdp: string, writeLog?: boolean) => boolean;
280
+ };
281
+
282
+ declare const version = "0.1.0";
283
+
284
+ export { Sdp, SdpEncryptionKey, SdpMediaSection, SdpOrigin, SdpPair, SdpRepeatTimes, SdpTiming, sdpReader, version };