krtp
Version:
Node implementation of rtp protocol. RFC 3550
117 lines (102 loc) • 3.27 kB
text/typescript
/*
* +===============================================
* | Author: Parham Alvani (parham.alvani@gmail.com)
* |
* | Creation Date: 03-06-2017
* |
* | File Name: Control.ts
* +===============================================
*/
/**
* ControlSR implements sender report message of real-time control protocol.
* The sender report is sent periodically by the active senders in a conference to report transmission
* and reception statistics for all RTP packets sent during the interval.
*/
export class ControlSR {
public readonly packetCount: number;
public readonly octetCount: number;
public readonly ssrc: number;
public readonly timestamp: number;
public readonly ntpTimestamp: number;
private rc: number = 0; // Reception report count
constructor(
packetCount: number,
octetCount: number,
ssrc: number,
timestamp: number,
ntpTimestamp: number = Date.now(),
) {
this.packetCount = packetCount;
this.octetCount = octetCount;
this.ssrc = ssrc;
this.timestamp = timestamp;
this.ntpTimestamp = ntpTimestamp;
}
public static deserialize(buff: Buffer): ControlSR {
if (buff.length < 28) {
throw new Error("invalid rtcp packet");
}
// header
// buff[0] = (V << 6 | P << 5 | RC)
if ((buff[0]! & (0xc0 >> 6)) !== 2) {
throw new Error("invalid rtcp packet");
}
// buff[1] = PT
if (buff[1]! !== 200) {
throw new Error("invalid rtcp packet");
}
// buff[2, 3] = length
const length: number = (buff.readUInt16BE(2) + 1) * 4;
if (buff.length < length) {
throw new Error("invalid rtcp packet");
}
if (buff.length !== length) {
throw new Error("invalid rtcp packet");
}
// buff[4, 5, 6, 7] = SSRC
const ssrc: number = buff.readUInt32BE(4);
// sender info
// buff[8, 9, 10, 11] = ntpTS
// buff[12, 13, 14, 15] = ntpTS
const ntpTimestamp: number =
buff.readUInt32BE(8) * 1000 + buff.readUInt32BE(12);
// buff[16, 17, 18, 19] = TS
const timestamp: number = buff.readUInt32BE(16);
// buff[20, 21, 22, 23] = packetCount
const packetCount: number = buff.readUInt32BE(20);
// buff[24, 25, 26, 27] = octetCount
const octetCount: number = buff.readUInt32BE(24);
return new ControlSR(
packetCount,
octetCount,
ssrc,
timestamp,
ntpTimestamp,
);
}
public serialize(): Buffer {
const buff: Buffer = Buffer.alloc(8 + 20);
// header
// buff[0] = (V << 6 | P << 5 | RC)
buff[0] = (2 << 6) | (0 << 5) | this.rc;
// buff[1] = PT
// Sender Report Packet Type
buff[1] = 200;
// buff[2, 3] = length
buff.writeUInt16BE(((buff.length / 4) | 0) - 1, 2);
// buff[4, 5, 6, 7] = SSRC
buff.writeUInt32BE(this.ssrc, 4);
// sender info
// buff[8, 9, 10, 11] = ntpTS
buff.writeUInt32BE((this.ntpTimestamp / 1000) | 0, 8);
// buff[12, 13, 14, 15] = ntpTS
buff.writeUInt32BE(this.ntpTimestamp % 1000, 12);
// buff[16, 17, 18, 19] = TS
buff.writeUInt32BE(this.timestamp, 16);
// buff[20, 21, 22, 23] = packetCount
buff.writeUInt32BE(this.packetCount, 20);
// buff[24, 25, 26, 27] = octetCount
buff.writeUInt32BE(this.octetCount, 24);
return buff;
}
}