@tomgiee/tsdp 1.0.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 +21 -0
- package/README.md +124 -0
- package/dist/src/builder/media-builder.d.ts +221 -0
- package/dist/src/builder/media-builder.d.ts.map +1 -0
- package/dist/src/builder/media-builder.js +385 -0
- package/dist/src/builder/session-builder.d.ts +195 -0
- package/dist/src/builder/session-builder.d.ts.map +1 -0
- package/dist/src/builder/session-builder.js +366 -0
- package/dist/src/index.d.ts +67 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +250 -0
- package/dist/src/parser/attribute-parser.d.ts +100 -0
- package/dist/src/parser/attribute-parser.d.ts.map +1 -0
- package/dist/src/parser/attribute-parser.js +217 -0
- package/dist/src/parser/field-parser.d.ts +124 -0
- package/dist/src/parser/field-parser.d.ts.map +1 -0
- package/dist/src/parser/field-parser.js +335 -0
- package/dist/src/parser/media-parser.d.ts +45 -0
- package/dist/src/parser/media-parser.d.ts.map +1 -0
- package/dist/src/parser/media-parser.js +157 -0
- package/dist/src/parser/primitive-parser.d.ts +138 -0
- package/dist/src/parser/primitive-parser.d.ts.map +1 -0
- package/dist/src/parser/primitive-parser.js +316 -0
- package/dist/src/parser/scanner.d.ts +142 -0
- package/dist/src/parser/scanner.d.ts.map +1 -0
- package/dist/src/parser/scanner.js +284 -0
- package/dist/src/parser/session-parser.d.ts +35 -0
- package/dist/src/parser/session-parser.d.ts.map +1 -0
- package/dist/src/parser/session-parser.js +207 -0
- package/dist/src/parser/time-parser.d.ts +74 -0
- package/dist/src/parser/time-parser.d.ts.map +1 -0
- package/dist/src/parser/time-parser.js +168 -0
- package/dist/src/serializer/attribute-serializer.d.ts +18 -0
- package/dist/src/serializer/attribute-serializer.d.ts.map +1 -0
- package/dist/src/serializer/attribute-serializer.js +34 -0
- package/dist/src/serializer/field-serializer.d.ts +112 -0
- package/dist/src/serializer/field-serializer.d.ts.map +1 -0
- package/dist/src/serializer/field-serializer.js +212 -0
- package/dist/src/serializer/media-serializer.d.ts +31 -0
- package/dist/src/serializer/media-serializer.d.ts.map +1 -0
- package/dist/src/serializer/media-serializer.js +83 -0
- package/dist/src/serializer/session-serializer.d.ts +29 -0
- package/dist/src/serializer/session-serializer.d.ts.map +1 -0
- package/dist/src/serializer/session-serializer.js +99 -0
- package/dist/src/serializer/time-serializer.d.ts +46 -0
- package/dist/src/serializer/time-serializer.d.ts.map +1 -0
- package/dist/src/serializer/time-serializer.js +86 -0
- package/dist/src/types/attributes.d.ts +318 -0
- package/dist/src/types/attributes.d.ts.map +1 -0
- package/dist/src/types/attributes.js +225 -0
- package/dist/src/types/errors.d.ts +129 -0
- package/dist/src/types/errors.d.ts.map +1 -0
- package/dist/src/types/errors.js +186 -0
- package/dist/src/types/fields.d.ts +100 -0
- package/dist/src/types/fields.d.ts.map +1 -0
- package/dist/src/types/fields.js +48 -0
- package/dist/src/types/media.d.ts +148 -0
- package/dist/src/types/media.d.ts.map +1 -0
- package/dist/src/types/media.js +137 -0
- package/dist/src/types/network.d.ts +136 -0
- package/dist/src/types/network.d.ts.map +1 -0
- package/dist/src/types/network.js +130 -0
- package/dist/src/types/primitives.d.ts +193 -0
- package/dist/src/types/primitives.d.ts.map +1 -0
- package/dist/src/types/primitives.js +195 -0
- package/dist/src/types/session.d.ts +122 -0
- package/dist/src/types/session.d.ts.map +1 -0
- package/dist/src/types/session.js +81 -0
- package/dist/src/types/time.d.ts +129 -0
- package/dist/src/types/time.d.ts.map +1 -0
- package/dist/src/types/time.js +84 -0
- package/dist/src/utils/address-parser.d.ts +100 -0
- package/dist/src/utils/address-parser.d.ts.map +1 -0
- package/dist/src/utils/address-parser.js +338 -0
- package/dist/src/utils/format-validators.d.ts +77 -0
- package/dist/src/utils/format-validators.d.ts.map +1 -0
- package/dist/src/utils/format-validators.js +504 -0
- package/dist/src/utils/line-reader.d.ts +84 -0
- package/dist/src/utils/line-reader.d.ts.map +1 -0
- package/dist/src/utils/line-reader.js +169 -0
- package/dist/src/utils/time-converter.d.ts +99 -0
- package/dist/src/utils/time-converter.d.ts.map +1 -0
- package/dist/src/utils/time-converter.js +195 -0
- package/dist/src/validator/media-validator.d.ts +27 -0
- package/dist/src/validator/media-validator.d.ts.map +1 -0
- package/dist/src/validator/media-validator.js +241 -0
- package/dist/src/validator/semantic-validator.d.ts +47 -0
- package/dist/src/validator/semantic-validator.d.ts.map +1 -0
- package/dist/src/validator/semantic-validator.js +207 -0
- package/dist/src/validator/session-validator.d.ts +36 -0
- package/dist/src/validator/session-validator.d.ts.map +1 -0
- package/dist/src/validator/session-validator.js +280 -0
- package/dist/tests/integration/round-trip.test.d.ts +5 -0
- package/dist/tests/integration/round-trip.test.d.ts.map +1 -0
- package/dist/tests/integration/round-trip.test.js +320 -0
- package/dist/tests/integration/voip-examples.test.d.ts +5 -0
- package/dist/tests/integration/voip-examples.test.d.ts.map +1 -0
- package/dist/tests/integration/voip-examples.test.js +361 -0
- package/dist/tests/unit/builder/media-builder.test.d.ts +5 -0
- package/dist/tests/unit/builder/media-builder.test.d.ts.map +1 -0
- package/dist/tests/unit/builder/media-builder.test.js +524 -0
- package/dist/tests/unit/builder/session-builder.test.d.ts +5 -0
- package/dist/tests/unit/builder/session-builder.test.d.ts.map +1 -0
- package/dist/tests/unit/builder/session-builder.test.js +367 -0
- package/dist/tests/unit/parser/attribute-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/attribute-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/attribute-parser.test.js +319 -0
- package/dist/tests/unit/parser/field-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/field-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/field-parser.test.js +355 -0
- package/dist/tests/unit/parser/media-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/media-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/media-parser.test.js +241 -0
- package/dist/tests/unit/parser/primitive-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/primitive-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/primitive-parser.test.js +261 -0
- package/dist/tests/unit/parser/scanner.test.d.ts +5 -0
- package/dist/tests/unit/parser/scanner.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/scanner.test.js +241 -0
- package/dist/tests/unit/parser/session-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/session-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/session-parser.test.js +346 -0
- package/dist/tests/unit/parser/time-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/time-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/time-parser.test.js +173 -0
- package/dist/tests/unit/serializer/attribute-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/attribute-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/attribute-serializer.test.js +78 -0
- package/dist/tests/unit/serializer/field-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/field-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/field-serializer.test.js +159 -0
- package/dist/tests/unit/serializer/media-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/media-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/media-serializer.test.js +155 -0
- package/dist/tests/unit/serializer/session-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/session-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/session-serializer.test.js +317 -0
- package/dist/tests/unit/serializer/time-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/time-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/time-serializer.test.js +115 -0
- package/dist/tests/unit/types/errors.test.d.ts +5 -0
- package/dist/tests/unit/types/errors.test.d.ts.map +1 -0
- package/dist/tests/unit/types/errors.test.js +127 -0
- package/dist/tests/unit/types/network.test.d.ts +5 -0
- package/dist/tests/unit/types/network.test.d.ts.map +1 -0
- package/dist/tests/unit/types/network.test.js +132 -0
- package/dist/tests/unit/types/primitives.test.d.ts +5 -0
- package/dist/tests/unit/types/primitives.test.d.ts.map +1 -0
- package/dist/tests/unit/types/primitives.test.js +108 -0
- package/dist/tests/unit/utils/address-parser.test.d.ts +5 -0
- package/dist/tests/unit/utils/address-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/address-parser.test.js +203 -0
- package/dist/tests/unit/utils/format-validators.test.d.ts +5 -0
- package/dist/tests/unit/utils/format-validators.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/format-validators.test.js +224 -0
- package/dist/tests/unit/utils/line-reader.test.d.ts +5 -0
- package/dist/tests/unit/utils/line-reader.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/line-reader.test.js +157 -0
- package/dist/tests/unit/utils/time-converter.test.d.ts +5 -0
- package/dist/tests/unit/utils/time-converter.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/time-converter.test.js +190 -0
- package/dist/tests/unit/validator/media-validator.test.d.ts +5 -0
- package/dist/tests/unit/validator/media-validator.test.d.ts.map +1 -0
- package/dist/tests/unit/validator/media-validator.test.js +313 -0
- package/dist/tests/unit/validator/semantic-validator.test.d.ts +5 -0
- package/dist/tests/unit/validator/semantic-validator.test.d.ts.map +1 -0
- package/dist/tests/unit/validator/semantic-validator.test.js +262 -0
- package/dist/tests/unit/validator/session-validator.test.d.ts +5 -0
- package/dist/tests/unit/validator/session-validator.test.d.ts.map +1 -0
- package/dist/tests/unit/validator/session-validator.test.js +447 -0
- package/package.json +50 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Media builder for SDP (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Provides a fluent builder API for creating SDP media descriptions.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.MediaBuilder = void 0;
|
|
9
|
+
exports.mediaBuilder = mediaBuilder;
|
|
10
|
+
exports.audioBuilder = audioBuilder;
|
|
11
|
+
exports.videoBuilder = videoBuilder;
|
|
12
|
+
const media_1 = require("../types/media");
|
|
13
|
+
const fields_1 = require("../types/fields");
|
|
14
|
+
const attributes_1 = require("../types/attributes");
|
|
15
|
+
const network_1 = require("../types/network");
|
|
16
|
+
const primitives_1 = require("../types/primitives");
|
|
17
|
+
const errors_1 = require("../types/errors");
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Media Builder
|
|
20
|
+
// ============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Fluent builder for creating SDP media descriptions
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const media = new MediaBuilder()
|
|
27
|
+
* .type('audio')
|
|
28
|
+
* .port(49170)
|
|
29
|
+
* .protocol('RTP/AVP')
|
|
30
|
+
* .formats(['0', '8'])
|
|
31
|
+
* .rtpmap(0, 'PCMU', 8000)
|
|
32
|
+
* .rtpmap(8, 'PCMA', 8000)
|
|
33
|
+
* .build();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
class MediaBuilder {
|
|
37
|
+
constructor() {
|
|
38
|
+
this._formats = [];
|
|
39
|
+
this._connections = [];
|
|
40
|
+
this._bandwidths = [];
|
|
41
|
+
this._attributes = [];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Set the media type
|
|
45
|
+
*
|
|
46
|
+
* @param type - Media type ('audio', 'video', 'text', 'application', 'message', 'image')
|
|
47
|
+
*/
|
|
48
|
+
type(type) {
|
|
49
|
+
this._type = type;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Set the port
|
|
54
|
+
*
|
|
55
|
+
* @param port - Port number (0-65535)
|
|
56
|
+
*/
|
|
57
|
+
port(port) {
|
|
58
|
+
this._port = (0, media_1.createSimplePort)(port);
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Set the port range
|
|
63
|
+
*
|
|
64
|
+
* @param base - Base port number
|
|
65
|
+
* @param count - Number of ports
|
|
66
|
+
*/
|
|
67
|
+
portRange(base, count) {
|
|
68
|
+
this._port = (0, media_1.createPortRange)(base, count);
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Disable this media stream (set port to 0)
|
|
73
|
+
*/
|
|
74
|
+
disabled() {
|
|
75
|
+
this._port = (0, media_1.createSimplePort)(0);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Set the transport protocol
|
|
80
|
+
*
|
|
81
|
+
* @param proto - Protocol (e.g., 'RTP/AVP', 'RTP/SAVP', 'RTP/SAVPF', 'udp', 'TCP/RTP/AVP')
|
|
82
|
+
*/
|
|
83
|
+
protocol(proto) {
|
|
84
|
+
this._protocol = proto;
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Set the formats (payload types for RTP)
|
|
89
|
+
*
|
|
90
|
+
* @param formats - Array of format strings
|
|
91
|
+
*/
|
|
92
|
+
formats(formats) {
|
|
93
|
+
this._formats = formats.map((f) => f);
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Add a single format
|
|
98
|
+
*/
|
|
99
|
+
addFormat(format) {
|
|
100
|
+
this._formats.push(format);
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Set the media information/title
|
|
105
|
+
*/
|
|
106
|
+
information(info) {
|
|
107
|
+
this._information = info;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Add a connection
|
|
112
|
+
*
|
|
113
|
+
* @param address - Connection address (IPv4, IPv6, or FQDN)
|
|
114
|
+
* @param addrType - Address type, auto-detected if not provided
|
|
115
|
+
*/
|
|
116
|
+
connection(address, addrType) {
|
|
117
|
+
const detectedAddrType = addrType !== null && addrType !== void 0 ? addrType : this.detectAddressType(address);
|
|
118
|
+
const connectionAddress = this.parseAddress(address, detectedAddrType);
|
|
119
|
+
this._connections.push((0, fields_1.createConnection)('IN', detectedAddrType, connectionAddress));
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Add a connection with multicast TTL
|
|
124
|
+
*/
|
|
125
|
+
connectionMulticast(address, ttl, addrType) {
|
|
126
|
+
const detectedAddrType = addrType !== null && addrType !== void 0 ? addrType : this.detectAddressType(address);
|
|
127
|
+
let connectionAddress;
|
|
128
|
+
if (detectedAddrType === 'IP4') {
|
|
129
|
+
connectionAddress = (0, network_1.createIP4MulticastAddress)((0, network_1.createIP4Address)(address), ttl);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
connectionAddress = (0, network_1.createIP6MulticastAddress)((0, network_1.createIP6Address)(address));
|
|
133
|
+
}
|
|
134
|
+
this._connections.push((0, fields_1.createConnection)('IN', detectedAddrType, connectionAddress));
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Add bandwidth information
|
|
139
|
+
*
|
|
140
|
+
* @param type - Bandwidth type ('CT' or 'AS')
|
|
141
|
+
* @param kbps - Bandwidth in kilobits per second
|
|
142
|
+
*/
|
|
143
|
+
addBandwidth(type, kbps) {
|
|
144
|
+
this._bandwidths.push((0, fields_1.createBandwidth)(type, kbps));
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Set AS (Application Specific) bandwidth
|
|
149
|
+
*/
|
|
150
|
+
bandwidth(kbps) {
|
|
151
|
+
return this.addBandwidth('AS', kbps);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Set encryption key (OBSOLETE per RFC 8866)
|
|
155
|
+
*
|
|
156
|
+
* @param keyValue - The key value (e.g., "clear:password" or "base64:encoded")
|
|
157
|
+
*/
|
|
158
|
+
key(keyValue) {
|
|
159
|
+
this._key = (0, primitives_1.createKey)(keyValue);
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Add an attribute
|
|
164
|
+
*/
|
|
165
|
+
addAttribute(attr) {
|
|
166
|
+
this._attributes.push(attr);
|
|
167
|
+
return this;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Add a custom property attribute
|
|
171
|
+
*/
|
|
172
|
+
addPropertyAttribute(name) {
|
|
173
|
+
this._attributes.push({ kind: 'property', name });
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Add a custom value attribute
|
|
178
|
+
*/
|
|
179
|
+
addValueAttribute(name, value) {
|
|
180
|
+
this._attributes.push((0, attributes_1.createValueAttribute)(name, value));
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Set direction to sendrecv
|
|
185
|
+
*/
|
|
186
|
+
sendrecv() {
|
|
187
|
+
return this.addAttribute((0, attributes_1.createSendrecv)());
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Set direction to recvonly
|
|
191
|
+
*/
|
|
192
|
+
recvonly() {
|
|
193
|
+
return this.addAttribute((0, attributes_1.createRecvonly)());
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Set direction to sendonly
|
|
197
|
+
*/
|
|
198
|
+
sendonly() {
|
|
199
|
+
return this.addAttribute((0, attributes_1.createSendonly)());
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Set direction to inactive
|
|
203
|
+
*/
|
|
204
|
+
inactive() {
|
|
205
|
+
return this.addAttribute((0, attributes_1.createInactive)());
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Add an rtpmap attribute
|
|
209
|
+
*
|
|
210
|
+
* @param payloadType - RTP payload type (0-127)
|
|
211
|
+
* @param encodingName - Encoding name (e.g., 'PCMU', 'H264')
|
|
212
|
+
* @param clockRate - Clock rate (e.g., 8000, 90000)
|
|
213
|
+
* @param encodingParams - Optional encoding parameters (e.g., 2 for stereo)
|
|
214
|
+
*/
|
|
215
|
+
rtpmap(payloadType, encodingName, clockRate, encodingParams) {
|
|
216
|
+
return this.addAttribute((0, attributes_1.createRtpmap)(payloadType, encodingName, clockRate, encodingParams));
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Add an fmtp attribute
|
|
220
|
+
*
|
|
221
|
+
* @param format - Format/payload type
|
|
222
|
+
* @param parameters - Format-specific parameters
|
|
223
|
+
*/
|
|
224
|
+
fmtp(format, parameters) {
|
|
225
|
+
return this.addAttribute((0, attributes_1.createFmtp)(format.toString(), parameters));
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Set the ptime attribute
|
|
229
|
+
*
|
|
230
|
+
* @param milliseconds - Packet time in milliseconds
|
|
231
|
+
*/
|
|
232
|
+
ptime(milliseconds) {
|
|
233
|
+
return this.addAttribute((0, attributes_1.createPtime)(milliseconds));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Set the maxptime attribute
|
|
237
|
+
*
|
|
238
|
+
* @param milliseconds - Maximum packet time in milliseconds
|
|
239
|
+
*/
|
|
240
|
+
maxptime(milliseconds) {
|
|
241
|
+
return this.addAttribute((0, attributes_1.createMaxptime)(milliseconds));
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Set the framerate attribute (for video)
|
|
245
|
+
*/
|
|
246
|
+
framerate(fps) {
|
|
247
|
+
return this.addValueAttribute('framerate', fps.toString());
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Set the quality attribute (for video, 0-10)
|
|
251
|
+
*/
|
|
252
|
+
quality(q) {
|
|
253
|
+
if (q < 0 || q > 10) {
|
|
254
|
+
throw errors_1.BuilderError.invalidConfiguration('Quality must be between 0 and 10');
|
|
255
|
+
}
|
|
256
|
+
return this.addValueAttribute('quality', q.toString());
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Add mid attribute (media identification)
|
|
260
|
+
*/
|
|
261
|
+
mid(id) {
|
|
262
|
+
return this.addValueAttribute('mid', id);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Add ice-ufrag attribute
|
|
266
|
+
*/
|
|
267
|
+
iceUfrag(ufrag) {
|
|
268
|
+
return this.addValueAttribute('ice-ufrag', ufrag);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Add ice-pwd attribute
|
|
272
|
+
*/
|
|
273
|
+
icePwd(pwd) {
|
|
274
|
+
return this.addValueAttribute('ice-pwd', pwd);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Add fingerprint attribute
|
|
278
|
+
*/
|
|
279
|
+
fingerprint(hashFunc, fingerprint) {
|
|
280
|
+
return this.addValueAttribute('fingerprint', `${hashFunc} ${fingerprint}`);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Add setup attribute
|
|
284
|
+
*/
|
|
285
|
+
setup(role) {
|
|
286
|
+
return this.addValueAttribute('setup', role);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Add RTCP attribute
|
|
290
|
+
*/
|
|
291
|
+
rtcp(port, address) {
|
|
292
|
+
let value = port.toString();
|
|
293
|
+
if (address) {
|
|
294
|
+
const addrType = this.detectAddressType(address);
|
|
295
|
+
value = `${port} IN ${addrType} ${address}`;
|
|
296
|
+
}
|
|
297
|
+
return this.addValueAttribute('rtcp', value);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Add rtcp-mux attribute
|
|
301
|
+
*/
|
|
302
|
+
rtcpMux() {
|
|
303
|
+
return this.addPropertyAttribute('rtcp-mux');
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Add rtcp-rsize attribute
|
|
307
|
+
*/
|
|
308
|
+
rtcpRsize() {
|
|
309
|
+
return this.addPropertyAttribute('rtcp-rsize');
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Build the media description
|
|
313
|
+
*
|
|
314
|
+
* @throws BuilderError if required fields are missing
|
|
315
|
+
*/
|
|
316
|
+
build() {
|
|
317
|
+
// Validate required fields
|
|
318
|
+
if (!this._type) {
|
|
319
|
+
throw errors_1.BuilderError.missingRequired('media type');
|
|
320
|
+
}
|
|
321
|
+
if (!this._port) {
|
|
322
|
+
throw errors_1.BuilderError.missingRequired('port');
|
|
323
|
+
}
|
|
324
|
+
if (!this._protocol) {
|
|
325
|
+
throw errors_1.BuilderError.missingRequired('protocol');
|
|
326
|
+
}
|
|
327
|
+
if (this._formats.length === 0) {
|
|
328
|
+
throw errors_1.BuilderError.missingRequired('formats (at least one format required)');
|
|
329
|
+
}
|
|
330
|
+
const media = {
|
|
331
|
+
type: this._type,
|
|
332
|
+
port: this._port,
|
|
333
|
+
proto: this._protocol,
|
|
334
|
+
formats: this._formats,
|
|
335
|
+
};
|
|
336
|
+
return {
|
|
337
|
+
media,
|
|
338
|
+
information: this._information,
|
|
339
|
+
connections: this._connections,
|
|
340
|
+
bandwidths: this._bandwidths,
|
|
341
|
+
key: this._key,
|
|
342
|
+
attributes: this._attributes,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
// ============================================================================
|
|
346
|
+
// Private Helpers
|
|
347
|
+
// ============================================================================
|
|
348
|
+
detectAddressType(address) {
|
|
349
|
+
if (address.includes(':')) {
|
|
350
|
+
return 'IP6';
|
|
351
|
+
}
|
|
352
|
+
return 'IP4';
|
|
353
|
+
}
|
|
354
|
+
parseAddress(address, addrType) {
|
|
355
|
+
if (addrType === 'IP6' || address.includes(':')) {
|
|
356
|
+
return (0, network_1.createIP6Address)(address);
|
|
357
|
+
}
|
|
358
|
+
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(address)) {
|
|
359
|
+
return (0, network_1.createIP4Address)(address);
|
|
360
|
+
}
|
|
361
|
+
return (0, network_1.createFQDN)(address);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
exports.MediaBuilder = MediaBuilder;
|
|
365
|
+
// ============================================================================
|
|
366
|
+
// Factory Functions
|
|
367
|
+
// ============================================================================
|
|
368
|
+
/**
|
|
369
|
+
* Create a new media builder
|
|
370
|
+
*/
|
|
371
|
+
function mediaBuilder() {
|
|
372
|
+
return new MediaBuilder();
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Create an audio media builder pre-configured for audio
|
|
376
|
+
*/
|
|
377
|
+
function audioBuilder() {
|
|
378
|
+
return new MediaBuilder().type('audio');
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Create a video media builder pre-configured for video
|
|
382
|
+
*/
|
|
383
|
+
function videoBuilder() {
|
|
384
|
+
return new MediaBuilder().type('video');
|
|
385
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session builder for SDP (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent builder API for creating SDP session descriptions.
|
|
5
|
+
*/
|
|
6
|
+
import { SessionDescription } from '../types/session';
|
|
7
|
+
import { TimeDescription } from '../types/time';
|
|
8
|
+
import { Attribute } from '../types/attributes';
|
|
9
|
+
import { MediaDescription } from '../types/media';
|
|
10
|
+
import { MediaBuilder } from './media-builder';
|
|
11
|
+
/**
|
|
12
|
+
* Fluent builder for creating SDP session descriptions
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const sdp = new SessionBuilder()
|
|
17
|
+
* .origin('alice', '2890844526', '2890842807', '192.168.1.1')
|
|
18
|
+
* .sessionName('My Session')
|
|
19
|
+
* .connection('192.168.1.100')
|
|
20
|
+
* .addAudioMedia(49170, 'RTP/AVP', ['0', '8'])
|
|
21
|
+
* .build();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class SessionBuilder {
|
|
25
|
+
private _version;
|
|
26
|
+
private _origin?;
|
|
27
|
+
private _sessionName?;
|
|
28
|
+
private _sessionInformation?;
|
|
29
|
+
private _uri?;
|
|
30
|
+
private _emails;
|
|
31
|
+
private _phones;
|
|
32
|
+
private _connection?;
|
|
33
|
+
private _bandwidths;
|
|
34
|
+
private _timeDescriptions;
|
|
35
|
+
private _key?;
|
|
36
|
+
private _attributes;
|
|
37
|
+
private _mediaDescriptions;
|
|
38
|
+
/**
|
|
39
|
+
* Set the origin field
|
|
40
|
+
*
|
|
41
|
+
* @param username - Username (use '-' if no username)
|
|
42
|
+
* @param sessId - Session ID (recommend NTP timestamp string)
|
|
43
|
+
* @param sessVersion - Session version (recommend NTP timestamp string)
|
|
44
|
+
* @param address - Origin address (IPv4, IPv6, or FQDN)
|
|
45
|
+
* @param addrType - Address type ('IP4' or 'IP6'), auto-detected if not provided
|
|
46
|
+
*/
|
|
47
|
+
origin(username: string, sessId: string, sessVersion: string, address: string, addrType?: 'IP4' | 'IP6'): this;
|
|
48
|
+
/**
|
|
49
|
+
* Set the origin with auto-generated session ID and version
|
|
50
|
+
*
|
|
51
|
+
* @param username - Username (use '-' if no username)
|
|
52
|
+
* @param address - Origin address
|
|
53
|
+
*/
|
|
54
|
+
originAuto(username: string, address: string): this;
|
|
55
|
+
/**
|
|
56
|
+
* Set the session name
|
|
57
|
+
*
|
|
58
|
+
* @param name - Session name (use ' ' if no meaningful name)
|
|
59
|
+
*/
|
|
60
|
+
sessionName(name: string): this;
|
|
61
|
+
/**
|
|
62
|
+
* Set the session information/title
|
|
63
|
+
*/
|
|
64
|
+
sessionInformation(info: string): this;
|
|
65
|
+
/**
|
|
66
|
+
* Set the URI for more information
|
|
67
|
+
*/
|
|
68
|
+
uri(uri: string): this;
|
|
69
|
+
/**
|
|
70
|
+
* Add an email address
|
|
71
|
+
*/
|
|
72
|
+
addEmail(email: string): this;
|
|
73
|
+
/**
|
|
74
|
+
* Add a phone number
|
|
75
|
+
*/
|
|
76
|
+
addPhone(phone: string): this;
|
|
77
|
+
/**
|
|
78
|
+
* Set the session-level connection
|
|
79
|
+
*
|
|
80
|
+
* @param address - Connection address (IPv4, IPv6, or FQDN)
|
|
81
|
+
* @param addrType - Address type, auto-detected if not provided
|
|
82
|
+
*/
|
|
83
|
+
connection(address: string, addrType?: 'IP4' | 'IP6'): this;
|
|
84
|
+
/**
|
|
85
|
+
* Set the session-level connection with multicast TTL
|
|
86
|
+
*/
|
|
87
|
+
connectionMulticast(address: string, ttl: number, addrType?: 'IP4' | 'IP6'): this;
|
|
88
|
+
/**
|
|
89
|
+
* Add bandwidth information
|
|
90
|
+
*
|
|
91
|
+
* @param type - Bandwidth type ('CT' for conference total, 'AS' for application specific)
|
|
92
|
+
* @param kbps - Bandwidth in kilobits per second
|
|
93
|
+
*/
|
|
94
|
+
addBandwidth(type: 'CT' | 'AS' | string, kbps: number): this;
|
|
95
|
+
/**
|
|
96
|
+
* Add a time description
|
|
97
|
+
*
|
|
98
|
+
* @param startTime - Start time (NTP timestamp, 0 for unbounded)
|
|
99
|
+
* @param stopTime - Stop time (NTP timestamp, 0 for unbounded)
|
|
100
|
+
*/
|
|
101
|
+
addTiming(startTime: number, stopTime: number): this;
|
|
102
|
+
/**
|
|
103
|
+
* Add permanent timing (0 to 0 = unbounded session)
|
|
104
|
+
*/
|
|
105
|
+
permanentTiming(): this;
|
|
106
|
+
/**
|
|
107
|
+
* Add a time description object
|
|
108
|
+
*/
|
|
109
|
+
addTimeDescription(timeDescription: TimeDescription): this;
|
|
110
|
+
/**
|
|
111
|
+
* Set encryption key (OBSOLETE per RFC 8866)
|
|
112
|
+
*
|
|
113
|
+
* @param keyValue - The key value (e.g., "clear:password" or "base64:encoded")
|
|
114
|
+
*/
|
|
115
|
+
key(keyValue: string): this;
|
|
116
|
+
/**
|
|
117
|
+
* Add a session-level attribute
|
|
118
|
+
*/
|
|
119
|
+
addAttribute(attr: Attribute): this;
|
|
120
|
+
/**
|
|
121
|
+
* Add a custom property attribute
|
|
122
|
+
*/
|
|
123
|
+
addPropertyAttribute(name: string): this;
|
|
124
|
+
/**
|
|
125
|
+
* Add a custom value attribute
|
|
126
|
+
*/
|
|
127
|
+
addValueAttribute(name: string, value: string): this;
|
|
128
|
+
/**
|
|
129
|
+
* Set direction to sendrecv
|
|
130
|
+
*/
|
|
131
|
+
sendrecv(): this;
|
|
132
|
+
/**
|
|
133
|
+
* Set direction to recvonly
|
|
134
|
+
*/
|
|
135
|
+
recvonly(): this;
|
|
136
|
+
/**
|
|
137
|
+
* Set direction to sendonly
|
|
138
|
+
*/
|
|
139
|
+
sendonly(): this;
|
|
140
|
+
/**
|
|
141
|
+
* Set direction to inactive
|
|
142
|
+
*/
|
|
143
|
+
inactive(): this;
|
|
144
|
+
/**
|
|
145
|
+
* Add a category attribute
|
|
146
|
+
*/
|
|
147
|
+
category(cat: string): this;
|
|
148
|
+
/**
|
|
149
|
+
* Add keywords attribute
|
|
150
|
+
*/
|
|
151
|
+
keywords(keywords: string): this;
|
|
152
|
+
/**
|
|
153
|
+
* Add tool attribute
|
|
154
|
+
*/
|
|
155
|
+
tool(tool: string): this;
|
|
156
|
+
/**
|
|
157
|
+
* Add charset attribute
|
|
158
|
+
*/
|
|
159
|
+
charset(charset: string): this;
|
|
160
|
+
/**
|
|
161
|
+
* Add a media description
|
|
162
|
+
*/
|
|
163
|
+
addMedia(mediaDescription: MediaDescription): this;
|
|
164
|
+
/**
|
|
165
|
+
* Add a media description using a builder
|
|
166
|
+
*
|
|
167
|
+
* @param builderFn - Function that configures the media builder
|
|
168
|
+
*/
|
|
169
|
+
addMediaBuilder(builderFn: (builder: MediaBuilder) => MediaBuilder): this;
|
|
170
|
+
/**
|
|
171
|
+
* Add an audio media description
|
|
172
|
+
*
|
|
173
|
+
* @param port - Port number
|
|
174
|
+
* @param proto - Protocol (e.g., 'RTP/AVP')
|
|
175
|
+
* @param formats - Format list (e.g., ['0', '8'] for PCMU and PCMA)
|
|
176
|
+
*/
|
|
177
|
+
addAudioMedia(port: number, proto: string, formats: string[]): this;
|
|
178
|
+
/**
|
|
179
|
+
* Add a video media description
|
|
180
|
+
*/
|
|
181
|
+
addVideoMedia(port: number, proto: string, formats: string[]): this;
|
|
182
|
+
/**
|
|
183
|
+
* Build the session description
|
|
184
|
+
*
|
|
185
|
+
* @throws BuilderError if required fields are missing
|
|
186
|
+
*/
|
|
187
|
+
build(): SessionDescription;
|
|
188
|
+
private detectAddressType;
|
|
189
|
+
private parseAddress;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Create a new session builder
|
|
193
|
+
*/
|
|
194
|
+
export declare function sessionBuilder(): SessionBuilder;
|
|
195
|
+
//# sourceMappingURL=session-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-builder.d.ts","sourceRoot":"","sources":["../../../src/builder/session-builder.ts"],"names":[],"mappings":"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"}
|