@agentdance/node-webrtc-rtp 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/dist/extension.d.ts +32 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +133 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/rtcp/bye.d.ts +7 -0
- package/dist/rtcp/bye.d.ts.map +1 -0
- package/dist/rtcp/bye.js +59 -0
- package/dist/rtcp/bye.js.map +1 -0
- package/dist/rtcp/fb.d.ts +22 -0
- package/dist/rtcp/fb.d.ts.map +1 -0
- package/dist/rtcp/fb.js +171 -0
- package/dist/rtcp/fb.js.map +1 -0
- package/dist/rtcp/index.d.ts +23 -0
- package/dist/rtcp/index.d.ts.map +1 -0
- package/dist/rtcp/index.js +145 -0
- package/dist/rtcp/index.js.map +1 -0
- package/dist/rtcp/rr.d.ts +12 -0
- package/dist/rtcp/rr.d.ts.map +1 -0
- package/dist/rtcp/rr.js +65 -0
- package/dist/rtcp/rr.js.map +1 -0
- package/dist/rtcp/sdes.d.ts +7 -0
- package/dist/rtcp/sdes.d.ts.map +1 -0
- package/dist/rtcp/sdes.js +76 -0
- package/dist/rtcp/sdes.js.map +1 -0
- package/dist/rtcp/sr.d.ts +9 -0
- package/dist/rtcp/sr.d.ts.map +1 -0
- package/dist/rtcp/sr.js +59 -0
- package/dist/rtcp/sr.js.map +1 -0
- package/dist/rtp.d.ts +21 -0
- package/dist/rtp.d.ts.map +1 -0
- package/dist/rtp.js +149 -0
- package/dist/rtp.js.map +1 -0
- package/dist/sequence.d.ts +26 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +53 -0
- package/dist/sequence.js.map +1 -0
- package/dist/types.d.ts +127 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
- package/src/extension.ts +153 -0
- package/src/index.ts +68 -0
- package/src/rtcp/bye.ts +73 -0
- package/src/rtcp/fb.ts +206 -0
- package/src/rtcp/index.ts +150 -0
- package/src/rtcp/rr.ts +82 -0
- package/src/rtcp/sdes.ts +94 -0
- package/src/rtcp/sr.ts +75 -0
- package/src/rtp.ts +176 -0
- package/src/sequence.ts +59 -0
- package/src/types.ts +129 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCP compound packet dispatch — RFC 3550 Section 6.1
|
|
3
|
+
*
|
|
4
|
+
* Compound RTCP packets are multiple RTCP packets concatenated together
|
|
5
|
+
* in a single UDP datagram.
|
|
6
|
+
*/
|
|
7
|
+
import { RtcpPacketType } from '../types.js';
|
|
8
|
+
import { encodeSr, decodeSr } from './sr.js';
|
|
9
|
+
import { encodeRr, decodeRr } from './rr.js';
|
|
10
|
+
import { encodeSdes, decodeSdes } from './sdes.js';
|
|
11
|
+
import { encodeBye, decodeBye } from './bye.js';
|
|
12
|
+
import { encodeNack, decodeNack, encodePli, decodePli, encodeFir, decodeFir, encodeRemb, decodeRemb, } from './fb.js';
|
|
13
|
+
/**
|
|
14
|
+
* Returns true if the buffer looks like an RTCP packet:
|
|
15
|
+
* - version == 2
|
|
16
|
+
* - payload type in 200–207
|
|
17
|
+
* - at least 4 bytes
|
|
18
|
+
*/
|
|
19
|
+
export function isRtcpPacket(buf) {
|
|
20
|
+
if (buf.length < 4)
|
|
21
|
+
return false;
|
|
22
|
+
const byte0 = buf[0];
|
|
23
|
+
if (byte0 === undefined)
|
|
24
|
+
return false;
|
|
25
|
+
const version = (byte0 >> 6) & 0x03;
|
|
26
|
+
if (version !== 2)
|
|
27
|
+
return false;
|
|
28
|
+
const byte1 = buf[1];
|
|
29
|
+
if (byte1 === undefined)
|
|
30
|
+
return false;
|
|
31
|
+
// RTCP PT is the full second byte value (200–207)
|
|
32
|
+
return byte1 >= 200 && byte1 <= 207;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Decode a (possibly compound) RTCP buffer into an array of RtcpPacket objects.
|
|
36
|
+
*/
|
|
37
|
+
export function decodeRtcp(buf) {
|
|
38
|
+
const packets = [];
|
|
39
|
+
let offset = 0;
|
|
40
|
+
while (offset < buf.length) {
|
|
41
|
+
if (offset + 4 > buf.length)
|
|
42
|
+
break;
|
|
43
|
+
const byte0 = buf[offset];
|
|
44
|
+
const byte1 = buf[offset + 1];
|
|
45
|
+
const lengthWords = buf.readUInt16BE(offset + 2);
|
|
46
|
+
const packetByteLen = (lengthWords + 1) * 4;
|
|
47
|
+
if (offset + packetByteLen > buf.length) {
|
|
48
|
+
// Truncated — take what we have
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
const packetBuf = buf.subarray(offset, offset + packetByteLen);
|
|
52
|
+
offset += packetByteLen;
|
|
53
|
+
const pt = byte1; // RTCP PT occupies the full second byte (no marker bit)
|
|
54
|
+
const fmt = byte0 & 0x1f; // lower 5 bits (also RC / SC / FMT)
|
|
55
|
+
try {
|
|
56
|
+
if (pt === RtcpPacketType.SR) {
|
|
57
|
+
packets.push({ type: 'sr', packet: decodeSr(packetBuf) });
|
|
58
|
+
}
|
|
59
|
+
else if (pt === RtcpPacketType.RR) {
|
|
60
|
+
packets.push({ type: 'rr', packet: decodeRr(packetBuf) });
|
|
61
|
+
}
|
|
62
|
+
else if (pt === RtcpPacketType.SDES) {
|
|
63
|
+
packets.push({ type: 'sdes', packet: decodeSdes(packetBuf) });
|
|
64
|
+
}
|
|
65
|
+
else if (pt === RtcpPacketType.BYE) {
|
|
66
|
+
packets.push({ type: 'bye', packet: decodeBye(packetBuf) });
|
|
67
|
+
}
|
|
68
|
+
else if (pt === RtcpPacketType.TransportFeedback) {
|
|
69
|
+
// FMT=1: NACK
|
|
70
|
+
if (fmt === 1) {
|
|
71
|
+
packets.push({ type: 'nack', packet: decodeNack(packetBuf) });
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
packets.push({ type: 'unknown', raw: Buffer.from(packetBuf) });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else if (pt === RtcpPacketType.PayloadFeedback) {
|
|
78
|
+
if (fmt === 1) {
|
|
79
|
+
packets.push({ type: 'pli', packet: decodePli(packetBuf) });
|
|
80
|
+
}
|
|
81
|
+
else if (fmt === 4) {
|
|
82
|
+
packets.push({ type: 'fir', packet: decodeFir(packetBuf) });
|
|
83
|
+
}
|
|
84
|
+
else if (fmt === 15) {
|
|
85
|
+
// Could be REMB — check unique identifier
|
|
86
|
+
if (packetBuf.length >= 16 && packetBuf.subarray(12, 16).toString('ascii') === 'REMB') {
|
|
87
|
+
packets.push({ type: 'remb', packet: decodeRemb(packetBuf) });
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
packets.push({ type: 'unknown', raw: Buffer.from(packetBuf) });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
packets.push({ type: 'unknown', raw: Buffer.from(packetBuf) });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
packets.push({ type: 'unknown', raw: Buffer.from(packetBuf) });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
packets.push({ type: 'unknown', raw: Buffer.from(packetBuf) });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return packets;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Encode an array of RtcpPacket objects into a compound RTCP buffer.
|
|
109
|
+
*/
|
|
110
|
+
export function encodeRtcp(packets) {
|
|
111
|
+
const parts = [];
|
|
112
|
+
for (const pkt of packets) {
|
|
113
|
+
switch (pkt.type) {
|
|
114
|
+
case 'sr':
|
|
115
|
+
parts.push(encodeSr(pkt.packet));
|
|
116
|
+
break;
|
|
117
|
+
case 'rr':
|
|
118
|
+
parts.push(encodeRr(pkt.packet));
|
|
119
|
+
break;
|
|
120
|
+
case 'sdes':
|
|
121
|
+
parts.push(encodeSdes(pkt.packet));
|
|
122
|
+
break;
|
|
123
|
+
case 'bye':
|
|
124
|
+
parts.push(encodeBye(pkt.packet));
|
|
125
|
+
break;
|
|
126
|
+
case 'nack':
|
|
127
|
+
parts.push(encodeNack(pkt.packet));
|
|
128
|
+
break;
|
|
129
|
+
case 'pli':
|
|
130
|
+
parts.push(encodePli(pkt.packet));
|
|
131
|
+
break;
|
|
132
|
+
case 'fir':
|
|
133
|
+
parts.push(encodeFir(pkt.packet));
|
|
134
|
+
break;
|
|
135
|
+
case 'remb':
|
|
136
|
+
parts.push(encodeRemb(pkt.packet));
|
|
137
|
+
break;
|
|
138
|
+
case 'unknown':
|
|
139
|
+
parts.push(pkt.raw);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return Buffer.concat(parts);
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rtcp/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCP Receiver Report (RR) — RFC 3550 Section 6.4.2
|
|
3
|
+
* Also provides shared ReportBlock encode/decode helpers.
|
|
4
|
+
*/
|
|
5
|
+
import type { RtcpReceiverReport, ReportBlock } from '../types.js';
|
|
6
|
+
/** Each report block is exactly 24 bytes (6 x 32-bit words) */
|
|
7
|
+
export declare const REPORT_BLOCK_SIZE = 24;
|
|
8
|
+
export declare function encodeReportBlock(rb: ReportBlock, buf: Buffer, offset: number): void;
|
|
9
|
+
export declare function decodeReportBlock(buf: Buffer, offset: number): ReportBlock;
|
|
10
|
+
export declare function encodeRr(rr: RtcpReceiverReport): Buffer;
|
|
11
|
+
export declare function decodeRr(buf: Buffer): RtcpReceiverReport;
|
|
12
|
+
//# sourceMappingURL=rr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rr.d.ts","sourceRoot":"","sources":["../../src/rtcp/rr.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEnE,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAKpC,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAWpF;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAiB1E;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,kBAAkB,GAAG,MAAM,CAiBvD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAiBxD"}
|
package/dist/rtcp/rr.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCP Receiver Report (RR) — RFC 3550 Section 6.4.2
|
|
3
|
+
* Also provides shared ReportBlock encode/decode helpers.
|
|
4
|
+
*/
|
|
5
|
+
/** Each report block is exactly 24 bytes (6 x 32-bit words) */
|
|
6
|
+
export const REPORT_BLOCK_SIZE = 24;
|
|
7
|
+
/** RR base size: 4 (common hdr) + 4 (SSRC) */
|
|
8
|
+
const RR_BASE_SIZE = 8;
|
|
9
|
+
export function encodeReportBlock(rb, buf, offset) {
|
|
10
|
+
buf.writeUInt32BE(rb.ssrc >>> 0, offset);
|
|
11
|
+
// fractionLost (8 bits) | cumulativeLost (24 bits, two's complement)
|
|
12
|
+
const cumLost = rb.cumulativeLost & 0xffffff;
|
|
13
|
+
buf.writeUInt32BE(((rb.fractionLost & 0xff) << 24) | cumLost, offset + 4);
|
|
14
|
+
buf.writeUInt32BE(rb.extendedHighestSeq >>> 0, offset + 8);
|
|
15
|
+
buf.writeUInt32BE(rb.jitter >>> 0, offset + 12);
|
|
16
|
+
buf.writeUInt32BE(rb.lastSR >>> 0, offset + 16);
|
|
17
|
+
buf.writeUInt32BE(rb.delaySinceLastSR >>> 0, offset + 20);
|
|
18
|
+
}
|
|
19
|
+
export function decodeReportBlock(buf, offset) {
|
|
20
|
+
const ssrc = buf.readUInt32BE(offset);
|
|
21
|
+
const word2 = buf.readUInt32BE(offset + 4);
|
|
22
|
+
const fractionLost = (word2 >>> 24) & 0xff;
|
|
23
|
+
// cumulativeLost is 24-bit signed
|
|
24
|
+
let cumulativeLost = word2 & 0xffffff;
|
|
25
|
+
if (cumulativeLost & 0x800000) {
|
|
26
|
+
cumulativeLost = cumulativeLost - 0x1000000; // sign extend
|
|
27
|
+
}
|
|
28
|
+
const extendedHighestSeq = buf.readUInt32BE(offset + 8);
|
|
29
|
+
const jitter = buf.readUInt32BE(offset + 12);
|
|
30
|
+
const lastSR = buf.readUInt32BE(offset + 16);
|
|
31
|
+
const delaySinceLastSR = buf.readUInt32BE(offset + 20);
|
|
32
|
+
return { ssrc, fractionLost, cumulativeLost, extendedHighestSeq, jitter, lastSR, delaySinceLastSR };
|
|
33
|
+
}
|
|
34
|
+
export function encodeRr(rr) {
|
|
35
|
+
const blockCount = rr.reportBlocks.length;
|
|
36
|
+
const totalBytes = RR_BASE_SIZE + blockCount * REPORT_BLOCK_SIZE;
|
|
37
|
+
const buf = Buffer.allocUnsafe(totalBytes);
|
|
38
|
+
buf[0] = (2 << 6) | (blockCount & 0x1f);
|
|
39
|
+
buf[1] = 201;
|
|
40
|
+
buf.writeUInt16BE(totalBytes / 4 - 1, 2);
|
|
41
|
+
buf.writeUInt32BE(rr.ssrc >>> 0, 4);
|
|
42
|
+
let offset = RR_BASE_SIZE;
|
|
43
|
+
for (const rb of rr.reportBlocks) {
|
|
44
|
+
encodeReportBlock(rb, buf, offset);
|
|
45
|
+
offset += REPORT_BLOCK_SIZE;
|
|
46
|
+
}
|
|
47
|
+
return buf;
|
|
48
|
+
}
|
|
49
|
+
export function decodeRr(buf) {
|
|
50
|
+
if (buf.length < RR_BASE_SIZE) {
|
|
51
|
+
throw new RangeError(`RR packet too short: ${buf.length}`);
|
|
52
|
+
}
|
|
53
|
+
const rc = (buf[0] & 0x1f);
|
|
54
|
+
const ssrc = buf.readUInt32BE(4);
|
|
55
|
+
const reportBlocks = [];
|
|
56
|
+
let offset = RR_BASE_SIZE;
|
|
57
|
+
for (let i = 0; i < rc; i++) {
|
|
58
|
+
if (offset + REPORT_BLOCK_SIZE > buf.length)
|
|
59
|
+
break;
|
|
60
|
+
reportBlocks.push(decodeReportBlock(buf, offset));
|
|
61
|
+
offset += REPORT_BLOCK_SIZE;
|
|
62
|
+
}
|
|
63
|
+
return { ssrc, reportBlocks };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=rr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rr.js","sourceRoot":"","sources":["../../src/rtcp/rr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCP SDES (Source Description) — RFC 3550 Section 6.5
|
|
3
|
+
*/
|
|
4
|
+
import type { RtcpSdes } from '../types.js';
|
|
5
|
+
export declare function encodeSdes(sdes: RtcpSdes): Buffer;
|
|
6
|
+
export declare function decodeSdes(buf: Buffer): RtcpSdes;
|
|
7
|
+
//# sourceMappingURL=sdes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdes.d.ts","sourceRoot":"","sources":["../../src/rtcp/sdes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAuB,MAAM,aAAa,CAAC;AAKjE,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAwCjD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CA0ChD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCP SDES (Source Description) — RFC 3550 Section 6.5
|
|
3
|
+
*/
|
|
4
|
+
/** SDES base header: 4 bytes (common header) */
|
|
5
|
+
const SDES_HEADER_SIZE = 4;
|
|
6
|
+
export function encodeSdes(sdes) {
|
|
7
|
+
const chunkBuffers = [];
|
|
8
|
+
for (const chunk of sdes.chunks) {
|
|
9
|
+
const itemParts = [];
|
|
10
|
+
// SSRC (4 bytes)
|
|
11
|
+
const ssrcBuf = Buffer.allocUnsafe(4);
|
|
12
|
+
ssrcBuf.writeUInt32BE(chunk.ssrc >>> 0, 0);
|
|
13
|
+
itemParts.push(ssrcBuf);
|
|
14
|
+
for (const item of chunk.items) {
|
|
15
|
+
const textBuf = Buffer.from(item.text, 'utf8');
|
|
16
|
+
const itemBuf = Buffer.allocUnsafe(2 + textBuf.length);
|
|
17
|
+
itemBuf[0] = item.type & 0xff;
|
|
18
|
+
itemBuf[1] = textBuf.length & 0xff;
|
|
19
|
+
textBuf.copy(itemBuf, 2);
|
|
20
|
+
itemParts.push(itemBuf);
|
|
21
|
+
}
|
|
22
|
+
// END item (type=0)
|
|
23
|
+
itemParts.push(Buffer.from([0x00]));
|
|
24
|
+
// Concatenate and pad to 4-byte boundary
|
|
25
|
+
const chunkBody = Buffer.concat(itemParts);
|
|
26
|
+
const padLen = (4 - (chunkBody.length % 4)) % 4;
|
|
27
|
+
const padding = Buffer.alloc(padLen, 0x00);
|
|
28
|
+
chunkBuffers.push(Buffer.concat([chunkBody, padding]));
|
|
29
|
+
}
|
|
30
|
+
const body = Buffer.concat(chunkBuffers);
|
|
31
|
+
const totalBytes = SDES_HEADER_SIZE + body.length;
|
|
32
|
+
const header = Buffer.allocUnsafe(SDES_HEADER_SIZE);
|
|
33
|
+
const sc = sdes.chunks.length;
|
|
34
|
+
header[0] = (2 << 6) | (sc & 0x1f);
|
|
35
|
+
header[1] = 202;
|
|
36
|
+
header.writeUInt16BE(totalBytes / 4 - 1, 2);
|
|
37
|
+
return Buffer.concat([header, body]);
|
|
38
|
+
}
|
|
39
|
+
export function decodeSdes(buf) {
|
|
40
|
+
if (buf.length < SDES_HEADER_SIZE) {
|
|
41
|
+
throw new RangeError(`SDES packet too short: ${buf.length}`);
|
|
42
|
+
}
|
|
43
|
+
const sc = buf[0] & 0x1f;
|
|
44
|
+
// length word gives total 32-bit words - 1, so total bytes = (length+1)*4
|
|
45
|
+
const totalBytes = (buf.readUInt16BE(2) + 1) * 4;
|
|
46
|
+
const chunks = [];
|
|
47
|
+
let offset = SDES_HEADER_SIZE;
|
|
48
|
+
for (let c = 0; c < sc; c++) {
|
|
49
|
+
if (offset + 4 > buf.length)
|
|
50
|
+
break;
|
|
51
|
+
const ssrc = buf.readUInt32BE(offset);
|
|
52
|
+
offset += 4;
|
|
53
|
+
const items = [];
|
|
54
|
+
while (offset < totalBytes && offset < buf.length) {
|
|
55
|
+
const itemType = buf[offset];
|
|
56
|
+
if (itemType === undefined || itemType === 0x00) {
|
|
57
|
+
// END item — skip to 4-byte boundary
|
|
58
|
+
offset++;
|
|
59
|
+
const padTo = (offset + 3) & ~3;
|
|
60
|
+
offset = Math.min(padTo, buf.length);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
offset++;
|
|
64
|
+
const textLen = buf[offset];
|
|
65
|
+
if (textLen === undefined)
|
|
66
|
+
break;
|
|
67
|
+
offset++;
|
|
68
|
+
const text = buf.subarray(offset, offset + textLen).toString('utf8');
|
|
69
|
+
offset += textLen;
|
|
70
|
+
items.push({ type: itemType, text });
|
|
71
|
+
}
|
|
72
|
+
chunks.push({ ssrc, items });
|
|
73
|
+
}
|
|
74
|
+
return { chunks };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=sdes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdes.js","sourceRoot":"","sources":["../../src/rtcp/sdes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCP Sender Report (SR) — RFC 3550 Section 6.4.1
|
|
3
|
+
*/
|
|
4
|
+
import type { RtcpSenderReport } from '../types.js';
|
|
5
|
+
/** Full SR packet size without report blocks: 4 (common hdr) + 4 (SSRC) + 20 (sender info) */
|
|
6
|
+
export declare const SR_BASE_SIZE = 28;
|
|
7
|
+
export declare function encodeSr(sr: RtcpSenderReport): Buffer;
|
|
8
|
+
export declare function decodeSr(buf: Buffer): RtcpSenderReport;
|
|
9
|
+
//# sourceMappingURL=sr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sr.d.ts","sourceRoot":"","sources":["../../src/rtcp/sr.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAe,MAAM,aAAa,CAAC;AAMjE,8FAA8F;AAC9F,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,wBAAgB,QAAQ,CAAC,EAAE,EAAE,gBAAgB,GAAG,MAAM,CAoCrD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAuBtD"}
|
package/dist/rtcp/sr.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCP Sender Report (SR) — RFC 3550 Section 6.4.1
|
|
3
|
+
*/
|
|
4
|
+
import { encodeReportBlock, decodeReportBlock, REPORT_BLOCK_SIZE } from './rr.js';
|
|
5
|
+
/** Fixed size of SR sender info block (without report blocks) */
|
|
6
|
+
const SR_SENDER_INFO_SIZE = 20; // 5 x 32-bit words
|
|
7
|
+
/** Full SR packet size without report blocks: 4 (common hdr) + 4 (SSRC) + 20 (sender info) */
|
|
8
|
+
export const SR_BASE_SIZE = 28;
|
|
9
|
+
export function encodeSr(sr) {
|
|
10
|
+
const blockCount = sr.reportBlocks.length;
|
|
11
|
+
const totalBytes = SR_BASE_SIZE + blockCount * REPORT_BLOCK_SIZE;
|
|
12
|
+
const buf = Buffer.allocUnsafe(totalBytes);
|
|
13
|
+
// Common RTCP header
|
|
14
|
+
// V=2, P=0, RC=blockCount, PT=200
|
|
15
|
+
buf[0] = (2 << 6) | (blockCount & 0x1f);
|
|
16
|
+
buf[1] = 200;
|
|
17
|
+
// Length in 32-bit words minus 1
|
|
18
|
+
const lengthWords = totalBytes / 4 - 1;
|
|
19
|
+
buf.writeUInt16BE(lengthWords, 2);
|
|
20
|
+
// SSRC
|
|
21
|
+
buf.writeUInt32BE(sr.ssrc >>> 0, 4);
|
|
22
|
+
// NTP timestamp (64-bit)
|
|
23
|
+
buf.writeBigUInt64BE(sr.ntpTimestamp, 8);
|
|
24
|
+
// RTP timestamp
|
|
25
|
+
buf.writeUInt32BE(sr.rtpTimestamp >>> 0, 16);
|
|
26
|
+
// Packet count
|
|
27
|
+
buf.writeUInt32BE(sr.packetCount >>> 0, 20);
|
|
28
|
+
// Octet count
|
|
29
|
+
buf.writeUInt32BE(sr.octetCount >>> 0, 24);
|
|
30
|
+
// Report blocks
|
|
31
|
+
let offset = SR_BASE_SIZE;
|
|
32
|
+
for (const rb of sr.reportBlocks) {
|
|
33
|
+
encodeReportBlock(rb, buf, offset);
|
|
34
|
+
offset += REPORT_BLOCK_SIZE;
|
|
35
|
+
}
|
|
36
|
+
return buf;
|
|
37
|
+
}
|
|
38
|
+
export function decodeSr(buf) {
|
|
39
|
+
if (buf.length < SR_BASE_SIZE) {
|
|
40
|
+
throw new RangeError(`SR packet too short: ${buf.length}`);
|
|
41
|
+
}
|
|
42
|
+
// byte[0]: V(2)|P(1)|RC(5) — RC = report count
|
|
43
|
+
const rc = (buf[0] & 0x1f);
|
|
44
|
+
const ssrc = buf.readUInt32BE(4);
|
|
45
|
+
const ntpTimestamp = buf.readBigUInt64BE(8);
|
|
46
|
+
const rtpTimestamp = buf.readUInt32BE(16);
|
|
47
|
+
const packetCount = buf.readUInt32BE(20);
|
|
48
|
+
const octetCount = buf.readUInt32BE(24);
|
|
49
|
+
const reportBlocks = [];
|
|
50
|
+
let offset = SR_BASE_SIZE;
|
|
51
|
+
for (let i = 0; i < rc; i++) {
|
|
52
|
+
if (offset + REPORT_BLOCK_SIZE > buf.length)
|
|
53
|
+
break;
|
|
54
|
+
reportBlocks.push(decodeReportBlock(buf, offset));
|
|
55
|
+
offset += REPORT_BLOCK_SIZE;
|
|
56
|
+
}
|
|
57
|
+
return { ssrc, ntpTimestamp, rtpTimestamp, packetCount, octetCount, reportBlocks };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=sr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sr.js","sourceRoot":"","sources":["../../src/rtcp/sr.ts"],"names":[],"mappings":"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"}
|
package/dist/rtp.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTP packet encode/decode — RFC 3550 Section 5.1
|
|
3
|
+
*/
|
|
4
|
+
import type { RtpPacket } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Returns true if the buffer looks like an RTP packet:
|
|
7
|
+
* - version == 2
|
|
8
|
+
* - payload type NOT in the RTCP range 200–204
|
|
9
|
+
* - at least 12 bytes
|
|
10
|
+
*/
|
|
11
|
+
export declare function isRtpPacket(buf: Buffer): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Decode an RTP packet from a Buffer.
|
|
14
|
+
* Throws if the buffer is malformed or too short.
|
|
15
|
+
*/
|
|
16
|
+
export declare function decodeRtp(buf: Buffer): RtpPacket;
|
|
17
|
+
/**
|
|
18
|
+
* Encode an RTP packet into a Buffer.
|
|
19
|
+
*/
|
|
20
|
+
export declare function encodeRtp(packet: RtpPacket): Buffer;
|
|
21
|
+
//# sourceMappingURL=rtp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtp.d.ts","sourceRoot":"","sources":["../src/rtp.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAW5C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWhD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAiFhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAmDnD"}
|
package/dist/rtp.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTP packet encode/decode — RFC 3550 Section 5.1
|
|
3
|
+
*/
|
|
4
|
+
import { parseExtensionValues, serializeExtension, } from './extension.js';
|
|
5
|
+
/** Minimum RTP header size (no CSRC, no extension) */
|
|
6
|
+
const RTP_MIN_HEADER = 12;
|
|
7
|
+
/**
|
|
8
|
+
* Returns true if the buffer looks like an RTP packet:
|
|
9
|
+
* - version == 2
|
|
10
|
+
* - payload type NOT in the RTCP range 200–204
|
|
11
|
+
* - at least 12 bytes
|
|
12
|
+
*/
|
|
13
|
+
export function isRtpPacket(buf) {
|
|
14
|
+
if (buf.length < RTP_MIN_HEADER)
|
|
15
|
+
return false;
|
|
16
|
+
const firstByte = buf[0];
|
|
17
|
+
if (firstByte === undefined)
|
|
18
|
+
return false;
|
|
19
|
+
const version = (firstByte >> 6) & 0x03;
|
|
20
|
+
if (version !== 2)
|
|
21
|
+
return false;
|
|
22
|
+
const secondByte = buf[1];
|
|
23
|
+
if (secondByte === undefined)
|
|
24
|
+
return false;
|
|
25
|
+
// RTCP PT occupies the full second byte (200–207); check raw value, not masked
|
|
26
|
+
if (secondByte >= 200 && secondByte <= 207)
|
|
27
|
+
return false;
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Decode an RTP packet from a Buffer.
|
|
32
|
+
* Throws if the buffer is malformed or too short.
|
|
33
|
+
*/
|
|
34
|
+
export function decodeRtp(buf) {
|
|
35
|
+
if (buf.length < RTP_MIN_HEADER) {
|
|
36
|
+
throw new RangeError(`RTP buffer too short: ${buf.length}`);
|
|
37
|
+
}
|
|
38
|
+
const byte0 = buf[0];
|
|
39
|
+
const byte1 = buf[1];
|
|
40
|
+
const version = (byte0 >> 6) & 0x03;
|
|
41
|
+
if (version !== 2) {
|
|
42
|
+
throw new Error(`Invalid RTP version: ${version}`);
|
|
43
|
+
}
|
|
44
|
+
const padding = Boolean(byte0 & 0x20);
|
|
45
|
+
const hasExtension = Boolean(byte0 & 0x10);
|
|
46
|
+
const csrcCount = byte0 & 0x0f;
|
|
47
|
+
const marker = Boolean(byte1 & 0x80);
|
|
48
|
+
const payloadType = byte1 & 0x7f;
|
|
49
|
+
const sequenceNumber = buf.readUInt16BE(2);
|
|
50
|
+
const timestamp = buf.readUInt32BE(4);
|
|
51
|
+
const ssrc = buf.readUInt32BE(8);
|
|
52
|
+
let offset = RTP_MIN_HEADER;
|
|
53
|
+
// CSRC list
|
|
54
|
+
if (buf.length < offset + csrcCount * 4) {
|
|
55
|
+
throw new RangeError('RTP buffer too short for CSRC list');
|
|
56
|
+
}
|
|
57
|
+
const csrcs = [];
|
|
58
|
+
for (let i = 0; i < csrcCount; i++) {
|
|
59
|
+
csrcs.push(buf.readUInt32BE(offset));
|
|
60
|
+
offset += 4;
|
|
61
|
+
}
|
|
62
|
+
// Header extension
|
|
63
|
+
let headerExtension;
|
|
64
|
+
if (hasExtension) {
|
|
65
|
+
if (buf.length < offset + 4) {
|
|
66
|
+
throw new RangeError('RTP buffer too short for extension header');
|
|
67
|
+
}
|
|
68
|
+
const extProfile = buf.readUInt16BE(offset);
|
|
69
|
+
const extLengthWords = buf.readUInt16BE(offset + 2);
|
|
70
|
+
offset += 4;
|
|
71
|
+
const extBodyLen = extLengthWords * 4;
|
|
72
|
+
if (buf.length < offset + extBodyLen) {
|
|
73
|
+
throw new RangeError('RTP buffer too short for extension body');
|
|
74
|
+
}
|
|
75
|
+
const extBody = buf.subarray(offset, offset + extBodyLen);
|
|
76
|
+
offset += extBodyLen;
|
|
77
|
+
const values = parseExtensionValues(extProfile, extBody);
|
|
78
|
+
headerExtension = { id: extProfile, values };
|
|
79
|
+
}
|
|
80
|
+
// Payload
|
|
81
|
+
let payloadEnd = buf.length;
|
|
82
|
+
if (padding) {
|
|
83
|
+
const padLen = buf[buf.length - 1];
|
|
84
|
+
payloadEnd = buf.length - padLen;
|
|
85
|
+
}
|
|
86
|
+
const payload = Buffer.from(buf.subarray(offset, payloadEnd));
|
|
87
|
+
const result = {
|
|
88
|
+
version: 2,
|
|
89
|
+
padding,
|
|
90
|
+
extension: hasExtension,
|
|
91
|
+
csrcCount,
|
|
92
|
+
marker,
|
|
93
|
+
payloadType,
|
|
94
|
+
sequenceNumber,
|
|
95
|
+
timestamp,
|
|
96
|
+
ssrc,
|
|
97
|
+
csrcs,
|
|
98
|
+
payload,
|
|
99
|
+
};
|
|
100
|
+
if (headerExtension !== undefined) {
|
|
101
|
+
result.headerExtension = headerExtension;
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Encode an RTP packet into a Buffer.
|
|
107
|
+
*/
|
|
108
|
+
export function encodeRtp(packet) {
|
|
109
|
+
const csrcCount = packet.csrcs.length;
|
|
110
|
+
// Build extension bytes if present
|
|
111
|
+
let extBuf = Buffer.alloc(0);
|
|
112
|
+
if (packet.headerExtension) {
|
|
113
|
+
extBuf = serializeExtension(packet.headerExtension);
|
|
114
|
+
}
|
|
115
|
+
// Build padding
|
|
116
|
+
let padBuf = Buffer.alloc(0);
|
|
117
|
+
if (packet.padding) {
|
|
118
|
+
// Add minimal 1-byte padding (caller controls actual padding amount via payload)
|
|
119
|
+
// The last byte of padding holds the count.
|
|
120
|
+
// We always emit padding as part of the payload in this implementation.
|
|
121
|
+
// If the caller set padding=true the payload should already include it.
|
|
122
|
+
}
|
|
123
|
+
const headerLen = RTP_MIN_HEADER + csrcCount * 4;
|
|
124
|
+
const totalLen = headerLen + extBuf.length + packet.payload.length + padBuf.length;
|
|
125
|
+
const buf = Buffer.allocUnsafe(totalLen);
|
|
126
|
+
const hasExt = packet.headerExtension !== undefined || packet.extension;
|
|
127
|
+
const byte0 = (2 << 6) |
|
|
128
|
+
(packet.padding ? 0x20 : 0) |
|
|
129
|
+
(hasExt ? 0x10 : 0) |
|
|
130
|
+
(csrcCount & 0x0f);
|
|
131
|
+
const byte1 = ((packet.marker ? 1 : 0) << 7) | (packet.payloadType & 0x7f);
|
|
132
|
+
buf[0] = byte0;
|
|
133
|
+
buf[1] = byte1;
|
|
134
|
+
buf.writeUInt16BE(packet.sequenceNumber, 2);
|
|
135
|
+
buf.writeUInt32BE(packet.timestamp >>> 0, 4);
|
|
136
|
+
buf.writeUInt32BE(packet.ssrc >>> 0, 8);
|
|
137
|
+
let offset = RTP_MIN_HEADER;
|
|
138
|
+
for (const csrc of packet.csrcs) {
|
|
139
|
+
buf.writeUInt32BE(csrc >>> 0, offset);
|
|
140
|
+
offset += 4;
|
|
141
|
+
}
|
|
142
|
+
if (extBuf.length > 0) {
|
|
143
|
+
extBuf.copy(buf, offset);
|
|
144
|
+
offset += extBuf.length;
|
|
145
|
+
}
|
|
146
|
+
packet.payload.copy(buf, offset);
|
|
147
|
+
return buf;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=rtp.js.map
|
package/dist/rtp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtp.js","sourceRoot":"","sources":["../src/rtp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap-around aware sequence number utilities for RTP (RFC 3550 Section A.1).
|
|
3
|
+
* Sequence numbers are 16-bit unsigned (0–65535).
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Returns a - b, wrap-around aware.
|
|
7
|
+
* Result is in range (-32768, 32768].
|
|
8
|
+
*/
|
|
9
|
+
export declare function seqDiff(a: number, b: number): number;
|
|
10
|
+
/** Returns true if a < b (wrap-around aware) */
|
|
11
|
+
export declare function seqLt(a: number, b: number): boolean;
|
|
12
|
+
/** Returns true if a <= b (wrap-around aware) */
|
|
13
|
+
export declare function seqLte(a: number, b: number): boolean;
|
|
14
|
+
/** Returns true if a > b (wrap-around aware) */
|
|
15
|
+
export declare function seqGt(a: number, b: number): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Convert a 64-bit NTP timestamp to Unix milliseconds.
|
|
18
|
+
* NTP format: upper 32 bits = seconds since 1900-01-01,
|
|
19
|
+
* lower 32 bits = fractional seconds.
|
|
20
|
+
*/
|
|
21
|
+
export declare function ntpToUnix(ntp: bigint): number;
|
|
22
|
+
/**
|
|
23
|
+
* Convert Unix milliseconds to a 64-bit NTP timestamp.
|
|
24
|
+
*/
|
|
25
|
+
export declare function unixToNtp(ms: number): bigint;
|
|
26
|
+
//# sourceMappingURL=sequence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,gDAAgD;AAChD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,iDAAiD;AACjD,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,gDAAgD;AAChD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEnD;AAKD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAM5C"}
|