werift 0.13.7 → 0.14.2-debug0

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.
Files changed (76) hide show
  1. package/lib/common/src/binary.d.ts +10 -0
  2. package/lib/common/src/binary.js +83 -1
  3. package/lib/common/src/binary.js.map +1 -1
  4. package/lib/dtls/src/context/cipher.d.ts +1 -2
  5. package/lib/dtls/src/context/cipher.js +69 -68
  6. package/lib/dtls/src/context/cipher.js.map +1 -1
  7. package/lib/ice/src/ice.js +10 -4
  8. package/lib/ice/src/ice.js.map +1 -1
  9. package/lib/rtp/src/index.d.ts +12 -9
  10. package/lib/rtp/src/index.js +12 -18
  11. package/lib/rtp/src/index.js.map +1 -1
  12. package/lib/rtp/src/processor/jitterBuffer.js +1 -1
  13. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  14. package/lib/rtp/src/processor/webm.d.ts +5 -1
  15. package/lib/rtp/src/processor/webm.js +12 -29
  16. package/lib/rtp/src/processor/webm.js.map +1 -1
  17. package/lib/rtp/src/rtp/red/encoder.d.ts +14 -0
  18. package/lib/rtp/src/rtp/red/encoder.js +40 -0
  19. package/lib/rtp/src/rtp/red/encoder.js.map +1 -0
  20. package/lib/rtp/src/rtp/{red.d.ts → red/packet.d.ts} +5 -5
  21. package/lib/rtp/src/rtp/red/packet.js +115 -0
  22. package/lib/rtp/src/rtp/red/packet.js.map +1 -0
  23. package/lib/rtp/src/rtp/rtp.d.ts +1 -1
  24. package/lib/rtp/src/rtp/rtp.js +1 -1
  25. package/lib/rtp/src/rtp/rtp.js.map +1 -1
  26. package/lib/sctp/src/sctp.d.ts +2 -1
  27. package/lib/sctp/src/sctp.js +4 -2
  28. package/lib/sctp/src/sctp.js.map +1 -1
  29. package/lib/webrtc/src/const.d.ts +2 -0
  30. package/lib/webrtc/src/const.js +3 -1
  31. package/lib/webrtc/src/const.js.map +1 -1
  32. package/lib/webrtc/src/index.d.ts +1 -0
  33. package/lib/webrtc/src/index.js +1 -0
  34. package/lib/webrtc/src/index.js.map +1 -1
  35. package/lib/webrtc/src/media/parameters.d.ts +1 -1
  36. package/lib/webrtc/src/media/parameters.js +0 -1
  37. package/lib/webrtc/src/media/parameters.js.map +1 -1
  38. package/lib/webrtc/src/media/receiver/red.js +8 -6
  39. package/lib/webrtc/src/media/receiver/red.js.map +1 -1
  40. package/lib/webrtc/src/media/rtpReceiver.d.ts +1 -1
  41. package/lib/webrtc/src/media/rtpReceiver.js +3 -1
  42. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  43. package/lib/webrtc/src/media/rtpSender.d.ts +8 -6
  44. package/lib/webrtc/src/media/rtpSender.js +21 -28
  45. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  46. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +21 -1
  47. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  48. package/lib/webrtc/src/peerConnection.d.ts +10 -4
  49. package/lib/webrtc/src/peerConnection.js +39 -12
  50. package/lib/webrtc/src/peerConnection.js.map +1 -1
  51. package/lib/webrtc/src/sdp.d.ts +4 -0
  52. package/lib/webrtc/src/sdp.js +11 -9
  53. package/lib/webrtc/src/sdp.js.map +1 -1
  54. package/lib/webrtc/src/transport/dtls.d.ts +6 -1
  55. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  56. package/lib/webrtc/src/transport/sctp.d.ts +1 -0
  57. package/lib/webrtc/src/transport/sctp.js +5 -1
  58. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  59. package/lib/webrtc/src/utils.d.ts +10 -0
  60. package/lib/webrtc/src/utils.js +8 -1
  61. package/lib/webrtc/src/utils.js.map +1 -1
  62. package/package.json +1 -1
  63. package/src/const.ts +6 -0
  64. package/src/index.ts +1 -0
  65. package/src/media/parameters.ts +1 -1
  66. package/src/media/receiver/red.ts +11 -12
  67. package/src/media/rtpReceiver.ts +3 -1
  68. package/src/media/rtpSender.ts +26 -45
  69. package/src/nonstandard/recorder/writer/webm.ts +3 -0
  70. package/src/peerConnection.ts +52 -15
  71. package/src/sdp.ts +10 -8
  72. package/src/transport/dtls.ts +6 -0
  73. package/src/transport/sctp.ts +6 -1
  74. package/src/utils.ts +9 -0
  75. package/lib/rtp/src/rtp/red.js +0 -104
  76. package/lib/rtp/src/rtp/red.js.map +0 -1
@@ -16,6 +16,7 @@ import {
16
16
  RtpHeader,
17
17
  RtpPacket,
18
18
  } from "../../../rtp/src";
19
+ import { codecParametersFromString } from "..";
19
20
  import { RTCDtlsTransport } from "../transport/dtls";
20
21
  import { Kind } from "../types/domain";
21
22
  import { compactNtp } from "../utils";
@@ -251,7 +252,8 @@ export class RTCRtpReceiver {
251
252
 
252
253
  if (codec.name.toLowerCase() === "rtx") {
253
254
  const originalSsrc = this.ssrcByRtx[packet.header.ssrc];
254
- const rtxCodec = this.codecs[codec.parameters["apt"]];
255
+ const codecParams = codecParametersFromString(codec.parameters ?? "");
256
+ const rtxCodec = this.codecs[codecParams["apt"]];
255
257
  if (packet.payload.length < 2) return;
256
258
 
257
259
  packet = unwrapRtx(packet, rtxCodec.payloadType, originalSsrc);
@@ -16,7 +16,7 @@ import {
16
16
  GenericNack,
17
17
  PictureLossIndication,
18
18
  ReceiverEstimatedMaxBitrate,
19
- Red,
19
+ RedEncoder,
20
20
  RtcpPacket,
21
21
  RtcpPayloadSpecificFeedback,
22
22
  RtcpRrPacket,
@@ -30,6 +30,7 @@ import {
30
30
  SourceDescriptionItem,
31
31
  TransportWideCC,
32
32
  } from "../../../rtp/src";
33
+ import { codecParametersFromString } from "..";
33
34
  import { RTCDtlsTransport } from "../transport/dtls";
34
35
  import { Kind } from "../types/domain";
35
36
  import { compactNtp, milliTime, ntpTime } from "../utils";
@@ -69,8 +70,9 @@ export class RTCRtpSender {
69
70
  private repairedRtpStreamId?: string;
70
71
  private rtxPayloadType?: number;
71
72
  private rtxSequenceNumber = random16();
72
- private redRedundantPayloadType?: number;
73
- redDistance = 2;
73
+ redRedundantPayloadType?: number;
74
+ private _redDistance = 2;
75
+ redEncoder = new RedEncoder(this._redDistance);
74
76
  private headerExtensions: RTCRtpHeaderExtensionParameters[] = [];
75
77
  private disposeTrack?: () => void;
76
78
 
@@ -90,7 +92,7 @@ export class RTCRtpSender {
90
92
  private timestampOffset = 0;
91
93
  private seqOffset = 0;
92
94
  private rtpCache: RtpPacket[] = [];
93
- private codec?: RTCRtpCodecParameters;
95
+ codec?: RTCRtpCodecParameters;
94
96
 
95
97
  track?: MediaStreamTrack;
96
98
  stopped = false;
@@ -114,6 +116,14 @@ export class RTCRtpSender {
114
116
  }
115
117
  }
116
118
 
119
+ get redDistance() {
120
+ return this._redDistance;
121
+ }
122
+ set redDistance(n: number) {
123
+ this._redDistance = n;
124
+ this.redEncoder.distance = n;
125
+ }
126
+
117
127
  prepareSend(params: RTCRtpSendParameters) {
118
128
  this.cname = params.rtcp?.cname;
119
129
  this.mid = params.muxId;
@@ -126,15 +136,18 @@ export class RTCRtpSender {
126
136
  this.track.codec = this.codec;
127
137
  }
128
138
 
129
- params.codecs.forEach((codec, i) => {
139
+ params.codecs.forEach((codec) => {
140
+ const codecParams = codecParametersFromString(codec.parameters ?? "");
130
141
  if (
131
142
  codec.name.toLowerCase() === "rtx" &&
132
- codec.parameters["apt"] === this.codec!.payloadType
143
+ codecParams["apt"] === this.codec?.payloadType
133
144
  ) {
134
145
  this.rtxPayloadType = codec.payloadType;
135
146
  }
136
147
  if (codec.name.toLowerCase() === "red") {
137
- this.redRedundantPayloadType = params.codecs[i + 1].payloadType;
148
+ this.redRedundantPayloadType = Number(
149
+ (codec.parameters ?? "").split("/")[0]
150
+ );
138
151
  }
139
152
  });
140
153
  }
@@ -323,20 +336,12 @@ export class RTCRtpSender {
323
336
  let rtpPayload = rtp.payload;
324
337
 
325
338
  if (this.redRedundantPayloadType) {
326
- const redundantPackets = [...Array(this.redDistance).keys()]
327
- .map((i) => {
328
- return this.rtpCache.find(
329
- (c) =>
330
- c.header.sequenceNumber ===
331
- header.sequenceNumber - (this.redDistance - i)
332
- );
333
- })
334
- .filter((p): p is NonNullable<typeof p> => typeof p !== "undefined");
335
- const red = buildRedPacket(
336
- redundantPackets,
337
- this.redRedundantPayloadType,
338
- rtp
339
- );
339
+ this.redEncoder.push({
340
+ block: rtpPayload,
341
+ timestamp: header.timestamp,
342
+ blockPT: this.redRedundantPayloadType,
343
+ });
344
+ const red = this.redEncoder.build();
340
345
  rtpPayload = red.serialize();
341
346
  }
342
347
 
@@ -458,27 +463,3 @@ export function wrapRtx(
458
463
  );
459
464
  return rtx;
460
465
  }
461
-
462
- export function buildRedPacket(
463
- redundantPackets: RtpPacket[],
464
- blockPT: number,
465
- presentPacket: RtpPacket
466
- ) {
467
- const red = new Red();
468
- redundantPackets.forEach((redundant) => {
469
- red.payloads.push({
470
- bin: redundant.payload,
471
- blockPT,
472
- timestampOffset: uint32Add(
473
- presentPacket.header.timestamp,
474
- -redundant.header.timestamp
475
- ),
476
- });
477
- });
478
-
479
- red.payloads.push({
480
- bin: presentPacket.payload,
481
- blockPT,
482
- });
483
- return red;
484
- }
@@ -1,3 +1,5 @@
1
+ import * as fs from "fs/promises";
2
+
1
3
  import { SupportedCodec } from "../../../../../rtp/src/container/webm";
2
4
  import {
3
5
  JitterBuffer,
@@ -12,6 +14,7 @@ export class WebmFactory extends MediaWriter {
12
14
 
13
15
  start(tracks: MediaStreamTrack[]) {
14
16
  this.webm = new WebmOutput(
17
+ fs,
15
18
  "./test.webm",
16
19
  tracks.map((track, i) => {
17
20
  const trackNumber = i + 1;
@@ -4,6 +4,7 @@ import Event from "rx.mini";
4
4
  import * as uuid from "uuid";
5
5
 
6
6
  import { Profile } from "../../dtls/src/context/srtp";
7
+ import { codecParametersFromString, DtlsKeys } from ".";
7
8
  import {
8
9
  DISCARD_HOST,
9
10
  DISCARD_PORT,
@@ -96,7 +97,7 @@ export class RTCPeerConnection extends EventTarget {
96
97
 
97
98
  private readonly router = new RtpRouter();
98
99
  private readonly certificates: RTCCertificate[] = [];
99
- private sctpRemotePort?: number;
100
+ sctpRemotePort?: number;
100
101
  private seenMid = new Set<string>();
101
102
  private currentLocalDescription?: SessionDescription;
102
103
  private currentRemoteDescription?: SessionDescription;
@@ -111,6 +112,7 @@ export class RTCPeerConnection extends EventTarget {
111
112
  iceServers,
112
113
  iceTransportPolicy,
113
114
  icePortRange,
115
+ dtls,
114
116
  }: Partial<PeerConfig> = {}) {
115
117
  super();
116
118
 
@@ -126,15 +128,27 @@ export class RTCPeerConnection extends EventTarget {
126
128
  if (codecs?.audio) this.configuration.codecs.audio = codecs.audio;
127
129
  if (codecs?.video) this.configuration.codecs.video = codecs.video;
128
130
 
129
- [
131
+ for (const [i, codecParams] of enumerate([
130
132
  ...(this.configuration.codecs.audio || []),
131
133
  ...(this.configuration.codecs.video || []),
132
- ].forEach((v, i) => {
133
- v.payloadType = 96 + i;
134
- if (v.name.toLowerCase() === "rtx") {
135
- v.parameters = { apt: v.payloadType - 1 };
134
+ ])) {
135
+ codecParams.payloadType = 96 + i;
136
+ switch (codecParams.name.toLowerCase()) {
137
+ case "rtx":
138
+ {
139
+ codecParams.parameters = `apt=${codecParams.payloadType - 1}`;
140
+ }
141
+ break;
142
+ case "red":
143
+ {
144
+ const redundant = codecParams.payloadType + 1;
145
+ codecParams.parameters = `${redundant}/${redundant}`;
146
+ codecParams.payloadType = 63;
147
+ }
148
+ break;
136
149
  }
137
- });
150
+ }
151
+
138
152
  if (headerExtensions?.audio)
139
153
  this.configuration.headerExtensions.audio = headerExtensions.audio;
140
154
  if (headerExtensions?.video)
@@ -146,6 +160,15 @@ export class RTCPeerConnection extends EventTarget {
146
160
  v.id = 1 + i;
147
161
  });
148
162
 
163
+ if (dtls) {
164
+ const { keys } = dtls;
165
+ if (keys) {
166
+ this.certificates.push(
167
+ new RTCCertificate(keys.keyPem, keys.certPem, keys.signatureHash)
168
+ );
169
+ }
170
+ }
171
+
149
172
  this.iceConnectionStateChange.subscribe((state) => {
150
173
  switch (state) {
151
174
  case "disconnected":
@@ -576,7 +599,8 @@ export class RTCPeerConnection extends EventTarget {
576
599
  transceiver.codecs.reduce(
577
600
  (acc: { [pt: number]: RTCRtpCodingParameters }, codec) => {
578
601
  if (codec.name.toLowerCase() === "rtx") {
579
- const apt = acc[codec.parameters["apt"]];
602
+ const params = codecParametersFromString(codec.parameters ?? "");
603
+ const apt = acc[params["apt"]];
580
604
  if (apt && media.ssrc.length === 2) {
581
605
  apt.rtx = new RTCRtpRtxParameters({ ssrc: media.ssrc[1].ssrc });
582
606
  }
@@ -639,7 +663,10 @@ export class RTCPeerConnection extends EventTarget {
639
663
  if (!existCodec) return false;
640
664
 
641
665
  if (existCodec?.name.toLowerCase() === "rtx") {
642
- const pt = existCodec.parameters["apt"];
666
+ const params = codecParametersFromString(
667
+ existCodec.parameters ?? ""
668
+ );
669
+ const pt = params["apt"];
643
670
  const origin = remoteMedia.rtp.codecs.find(
644
671
  (c) => c.payloadType === pt
645
672
  );
@@ -711,16 +738,18 @@ export class RTCPeerConnection extends EventTarget {
711
738
 
712
739
  transceiver.receiver.setupTWCC(remoteMedia.ssrc[0]?.ssrc);
713
740
  } else if (remoteMedia.kind === "application") {
741
+ // # configure sctp
742
+ this.sctpRemotePort = remoteMedia.sctpPort;
714
743
  if (!this.sctpTransport) {
744
+ if (!this.sctpRemotePort) {
745
+ throw new Error("sctpRemotePort not exist");
746
+ }
715
747
  this.sctpTransport = this.createSctpTransport();
748
+ this.sctpTransport.setRemotePort(this.sctpRemotePort);
716
749
  }
717
-
718
750
  if (!this.sctpTransport.mid) {
719
751
  this.sctpTransport.mid = remoteMedia.rtp.muxId;
720
752
  }
721
-
722
- // # configure sctp
723
- this.sctpRemotePort = remoteMedia.sctpPort;
724
753
  }
725
754
 
726
755
  if (remoteMedia.iceParams && remoteMedia.dtlsParams) {
@@ -879,7 +908,7 @@ export class RTCPeerConnection extends EventTarget {
879
908
  return this.transceivers;
880
909
  }
881
910
 
882
- getSenders() {
911
+ getSenders(): RTCRtpSender[] {
883
912
  return this.getTransceivers().map((t) => t.sender);
884
913
  }
885
914
 
@@ -888,7 +917,11 @@ export class RTCPeerConnection extends EventTarget {
888
917
  }
889
918
 
890
919
  // todo fix
891
- addTrack(track: MediaStreamTrack, ms?: MediaStream) {
920
+ addTrack(
921
+ track: MediaStreamTrack,
922
+ /**todo impl */
923
+ ms?: MediaStream
924
+ ) {
892
925
  if (this.isClosed) throw new Error("is closed");
893
926
  if (this.getSenders().find((sender) => sender.track?.uuid === track.uuid)) {
894
927
  throw new Error("track exist");
@@ -1185,6 +1218,9 @@ export interface PeerConfig {
1185
1218
  iceServers: RTCIceServer[];
1186
1219
  /**Minimum port and Maximum port must not be the same value */
1187
1220
  icePortRange: [number, number] | undefined;
1221
+ dtls: Partial<{
1222
+ keys: DtlsKeys;
1223
+ }>;
1188
1224
  }
1189
1225
 
1190
1226
  export const findCodecByMimeType = (
@@ -1235,6 +1271,7 @@ export const defaultPeerConfig: PeerConfig = {
1235
1271
  iceTransportPolicy: "all",
1236
1272
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
1237
1273
  icePortRange: undefined,
1274
+ dtls: {},
1238
1275
  };
1239
1276
 
1240
1277
  export interface RTCTrackEvent {
package/src/sdp.ts CHANGED
@@ -223,7 +223,8 @@ export class SessionDescription {
223
223
  case "sctpmap":
224
224
  if (!value) throw new Error();
225
225
  const [formatId, formatDesc] = divide(value, " ");
226
- (currentMedia as any)[attr][parseInt(formatId)] = formatDesc;
226
+ currentMedia.sctpMap[parseInt(formatId)] = formatDesc;
227
+ currentMedia.sctpPort = parseInt(formatId);
227
228
  break;
228
229
  case "sctp-port":
229
230
  if (!value) throw new Error();
@@ -274,7 +275,7 @@ export class SessionDescription {
274
275
  if (attr === "fmtp") {
275
276
  const [formatId, formatDesc] = divide(value, " ");
276
277
  const codec = findCodec(Number(formatId))!;
277
- codec.parameters = parametersFromSdp(formatDesc);
278
+ codec.parameters = formatDesc;
278
279
  } else if (attr === "rtcp-fb") {
279
280
  const [payloadType, feedbackType, feedbackParam] = value.split(" ");
280
281
  currentMedia.rtp.codecs.forEach((codec) => {
@@ -453,9 +454,8 @@ export class MediaDescription {
453
454
  lines.push(`a=rtcp-fb:${codec.payloadType} ${value}`);
454
455
  });
455
456
 
456
- const params = parametersToSDP(codec.parameters);
457
- if (params) {
458
- lines.push(`a=fmtp:${codec.payloadType} ${params}`);
457
+ if (codec.parameters) {
458
+ lines.push(`a=fmtp:${codec.payloadType} ${codec.parameters}`);
459
459
  }
460
460
  });
461
461
 
@@ -634,9 +634,9 @@ export function addSDPHeader(
634
634
  description.type = type;
635
635
  }
636
636
 
637
- function parametersFromSdp(sdp: string) {
637
+ export function codecParametersFromString(str: string) {
638
638
  const parameters = {};
639
- sdp.split(";").forEach((param) => {
639
+ str.split(";").forEach((param) => {
640
640
  if (param.includes("=")) {
641
641
  const [k, v] = divide(param, "=");
642
642
  if (FMTP_INT_PARAMETERS.includes(k)) {
@@ -651,7 +651,9 @@ function parametersFromSdp(sdp: string) {
651
651
  return parameters;
652
652
  }
653
653
 
654
- function parametersToSDP(parameters: { [key: string]: string }) {
654
+ export function codecParametersToString(parameters: {
655
+ [key: string]: string | number;
656
+ }) {
655
657
  const params = Object.entries(parameters).map(([k, v]) => {
656
658
  if (v) return `${k}=${v}`;
657
659
  else return k;
@@ -261,6 +261,12 @@ export class RTCCertificate {
261
261
  }
262
262
  }
263
263
 
264
+ export type DtlsKeys = {
265
+ certPem: string;
266
+ keyPem: string;
267
+ signatureHash: SignatureHash;
268
+ };
269
+
264
270
  export class RTCDtlsFingerprint {
265
271
  constructor(public algorithm: string, public value: string) {}
266
272
  }
@@ -301,6 +301,10 @@ export class RTCSctpTransport {
301
301
  return new RTCSctpCapabilities(65536);
302
302
  }
303
303
 
304
+ setRemotePort(port: number) {
305
+ this.sctp.setRemotePort(port);
306
+ }
307
+
304
308
  async start(remotePort: number) {
305
309
  if (this.isServer) {
306
310
  this.dataChannelId = 0;
@@ -309,7 +313,8 @@ export class RTCSctpTransport {
309
313
  }
310
314
  this.sctp.isServer = this.isServer;
311
315
 
312
- await this.sctp.start(remotePort);
316
+ this.setRemotePort(remotePort);
317
+ await this.sctp.start();
313
318
  }
314
319
 
315
320
  async stop() {
package/src/utils.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  uint16Add,
12
12
  uint32Add,
13
13
  } from "../../common/src";
14
+ import { CipherContext } from "../../dtls/src/context/cipher";
14
15
  import { Address } from "../../ice/src";
15
16
  import { RtpHeader, RtpPacket } from "../../rtp/src";
16
17
  import { Direction, Directions } from "./media/rtpTransceiver";
@@ -128,3 +129,11 @@ export class RtpBuilder {
128
129
  return rtp;
129
130
  }
130
131
  }
132
+
133
+ /**
134
+ *
135
+ * @param signatureHash
136
+ * @param namedCurveAlgorithm necessary when use ecdsa
137
+ */
138
+ export const createSelfSignedCertificate =
139
+ CipherContext.createSelfSignedCertificateWithKey;
@@ -1,104 +0,0 @@
1
- "use strict";
2
- // rfc2198
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.RedHeader = exports.Red = void 0;
5
- const src_1 = require("../../../common/src");
6
- // 0 1 2 3
7
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
8
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
9
- // |F| block PT | timestamp offset | block length |
10
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11
- // 0 1 2 3 4 5 6 7
12
- // +-+-+-+-+-+-+-+-+
13
- // |0| Block PT |
14
- // +-+-+-+-+-+-+-+-+
15
- class Red {
16
- constructor() {
17
- this.payloads = [];
18
- }
19
- static deSerialize(buf) {
20
- const red = new Red();
21
- let offset = 0;
22
- [red.header, offset] = RedHeader.deSerialize(buf);
23
- red.header.payloads.forEach(({ blockLength, timestampOffset, blockPT }) => {
24
- if (blockLength && timestampOffset) {
25
- const payload = buf.slice(offset, offset + blockLength);
26
- red.payloads.push({ bin: payload, blockPT, timestampOffset });
27
- offset += blockLength;
28
- }
29
- else {
30
- const payload = buf.slice(offset);
31
- red.payloads.push({ bin: payload, blockPT });
32
- }
33
- });
34
- return red;
35
- }
36
- serialize() {
37
- this.header = new RedHeader();
38
- for (const { timestampOffset, blockPT, bin } of this.payloads) {
39
- if (timestampOffset) {
40
- this.header.payloads.push({
41
- fBit: 1,
42
- blockPT,
43
- blockLength: bin.length,
44
- timestampOffset,
45
- });
46
- }
47
- else {
48
- this.header.payloads.push({ fBit: 0, blockPT });
49
- }
50
- }
51
- let buf = this.header.serialize();
52
- for (const { bin } of this.payloads) {
53
- buf = Buffer.concat([buf, bin]);
54
- }
55
- return buf;
56
- }
57
- }
58
- exports.Red = Red;
59
- class RedHeader {
60
- constructor() {
61
- this.payloads = [];
62
- }
63
- static deSerialize(buf) {
64
- let offset = 0;
65
- const header = new RedHeader();
66
- for (;;) {
67
- const payload = {};
68
- header.payloads.push(payload);
69
- payload.fBit = (0, src_1.getBit)(buf[offset], 0);
70
- payload.blockPT = (0, src_1.getBit)(buf[offset], 1, 7);
71
- offset++;
72
- if (payload.fBit === 0) {
73
- break;
74
- }
75
- payload.timestampOffset =
76
- (buf[offset] << 6) + ((buf[offset + 1] & 0b11111100) >> 2);
77
- offset++;
78
- payload.blockLength = ((buf[offset] & 0b11) << 8) + buf[offset + 1];
79
- offset += 2;
80
- }
81
- return [header, offset];
82
- }
83
- serialize() {
84
- let buf = Buffer.alloc(0);
85
- for (const payload of this.payloads) {
86
- if (payload.timestampOffset && payload.blockLength) {
87
- const a = new src_1.BitWriter2(8)
88
- .set(payload.fBit)
89
- .set(payload.blockPT, 7).buffer;
90
- const b = Buffer.alloc(3);
91
- b.writeUInt16BE((payload.timestampOffset << 2) | (payload.blockLength >> 8));
92
- b.writeUInt8(payload.blockLength & 0b11111111, 2);
93
- buf = Buffer.concat([buf, a, b]);
94
- }
95
- else {
96
- const chunk = new src_1.BitWriter2(8).set(0).set(payload.blockPT, 7).buffer;
97
- buf = Buffer.concat([buf, chunk]);
98
- }
99
- }
100
- return buf;
101
- }
102
- }
103
- exports.RedHeader = RedHeader;
104
- //# sourceMappingURL=red.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"red.js","sourceRoot":"","sources":["../../../../../rtp/src/rtp/red.ts"],"names":[],"mappings":"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","sourcesContent":["// rfc2198\n\nimport { BitWriter2, getBit } from \"../../../common/src\";\n\n// 0 1 2 3\n// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |F| block PT | timestamp offset | block length |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// 0 1 2 3 4 5 6 7\n// +-+-+-+-+-+-+-+-+\n// |0| Block PT |\n// +-+-+-+-+-+-+-+-+\n\nexport class Red {\n header!: RedHeader;\n payloads: {\n bin: Buffer;\n blockPT: number;\n /**14bit */\n timestampOffset?: number;\n }[] = [];\n\n static deSerialize(buf: Buffer) {\n const red = new Red();\n let offset = 0;\n [red.header, offset] = RedHeader.deSerialize(buf);\n\n red.header.payloads.forEach(({ blockLength, timestampOffset, blockPT }) => {\n if (blockLength && timestampOffset) {\n const payload = buf.slice(offset, offset + blockLength);\n red.payloads.push({ bin: payload, blockPT, timestampOffset });\n offset += blockLength;\n } else {\n const payload = buf.slice(offset);\n red.payloads.push({ bin: payload, blockPT });\n }\n });\n\n return red;\n }\n\n serialize() {\n this.header = new RedHeader();\n\n for (const { timestampOffset, blockPT, bin } of this.payloads) {\n if (timestampOffset) {\n this.header.payloads.push({\n fBit: 1,\n blockPT,\n blockLength: bin.length,\n timestampOffset,\n });\n } else {\n this.header.payloads.push({ fBit: 0, blockPT });\n }\n }\n\n let buf = this.header.serialize();\n for (const { bin } of this.payloads) {\n buf = Buffer.concat([buf, bin]);\n }\n\n return buf;\n }\n}\n\nexport class RedHeader {\n payloads: RedHeaderPayload[] = [];\n\n static deSerialize(buf: Buffer) {\n let offset = 0;\n const header = new RedHeader();\n\n for (;;) {\n const payload: RedHeaderPayload = {} as any;\n header.payloads.push(payload);\n payload.fBit = getBit(buf[offset], 0);\n payload.blockPT = getBit(buf[offset], 1, 7);\n offset++;\n\n if (payload.fBit === 0) {\n break;\n }\n\n payload.timestampOffset =\n (buf[offset] << 6) + ((buf[offset + 1] & 0b11111100) >> 2);\n offset++;\n payload.blockLength = ((buf[offset] & 0b11) << 8) + buf[offset + 1];\n offset += 2;\n }\n\n return [header, offset] as const;\n }\n\n serialize() {\n let buf = Buffer.alloc(0);\n for (const payload of this.payloads) {\n if (payload.timestampOffset && payload.blockLength) {\n const a = new BitWriter2(8)\n .set(payload.fBit)\n .set(payload.blockPT, 7).buffer;\n const b = Buffer.alloc(3);\n b.writeUInt16BE(\n (payload.timestampOffset << 2) | (payload.blockLength >> 8)\n );\n b.writeUInt8(payload.blockLength & 0b11111111, 2);\n\n buf = Buffer.concat([buf, a, b]);\n } else {\n const chunk = new BitWriter2(8).set(0).set(payload.blockPT, 7).buffer;\n buf = Buffer.concat([buf, chunk]);\n }\n }\n return buf;\n }\n}\n\ninterface RedHeaderPayload {\n fBit: number;\n blockPT: number;\n /**14bit */\n timestampOffset?: number;\n /**10bit */\n blockLength?: number;\n}\n"]}