werift 0.17.0 → 0.17.2

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 (108) hide show
  1. package/lib/ice/src/ice.d.ts +10 -1
  2. package/lib/ice/src/ice.js +15 -3
  3. package/lib/ice/src/ice.js.map +1 -1
  4. package/lib/rtp/src/container/ebml/ebml.d.ts +32 -0
  5. package/lib/rtp/src/container/ebml/ebml.js +115 -0
  6. package/lib/rtp/src/container/ebml/ebml.js.map +1 -0
  7. package/lib/rtp/src/container/ebml/id.d.ts +221 -0
  8. package/lib/rtp/src/container/ebml/id.js +225 -0
  9. package/lib/rtp/src/container/ebml/id.js.map +1 -0
  10. package/lib/rtp/src/container/ebml/index.d.ts +3 -0
  11. package/lib/rtp/src/container/ebml/index.js +20 -0
  12. package/lib/rtp/src/container/ebml/index.js.map +1 -0
  13. package/lib/rtp/src/container/ebml/typedArrayUtils.d.ts +7 -0
  14. package/lib/rtp/src/container/ebml/typedArrayUtils.js +109 -0
  15. package/lib/rtp/src/container/ebml/typedArrayUtils.js.map +1 -0
  16. package/lib/rtp/src/container/webm.d.ts +10 -4
  17. package/lib/rtp/src/container/webm.js +56 -7
  18. package/lib/rtp/src/container/webm.js.map +1 -1
  19. package/lib/rtp/src/index.d.ts +1 -0
  20. package/lib/rtp/src/index.js +1 -0
  21. package/lib/rtp/src/index.js.map +1 -1
  22. package/lib/rtp/src/processor/avBuffer.d.ts +28 -0
  23. package/lib/rtp/src/processor/avBuffer.js +91 -0
  24. package/lib/rtp/src/processor/avBuffer.js.map +1 -0
  25. package/lib/rtp/src/processor/avBufferCallback.d.ts +10 -0
  26. package/lib/rtp/src/processor/avBufferCallback.js +27 -0
  27. package/lib/rtp/src/processor/avBufferCallback.js.map +1 -0
  28. package/lib/rtp/src/processor/depacketizer.d.ts +1 -1
  29. package/lib/rtp/src/processor/depacketizer.js.map +1 -1
  30. package/lib/rtp/src/processor/depacketizerCallback.d.ts +1 -3
  31. package/lib/rtp/src/processor/depacketizerCallback.js +2 -2
  32. package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -1
  33. package/lib/rtp/src/processor/depacketizerTransformer.d.ts +1 -1
  34. package/lib/rtp/src/processor/index.d.ts +3 -0
  35. package/lib/rtp/src/processor/index.js +3 -0
  36. package/lib/rtp/src/processor/index.js.map +1 -1
  37. package/lib/rtp/src/processor/jitterBuffer.d.ts +1 -1
  38. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  39. package/lib/rtp/src/processor/jitterBufferCallback.d.ts +1 -3
  40. package/lib/rtp/src/processor/jitterBufferCallback.js +2 -2
  41. package/lib/rtp/src/processor/jitterBufferCallback.js.map +1 -1
  42. package/lib/rtp/src/processor/jitterBufferTransformer.d.ts +1 -1
  43. package/lib/rtp/src/processor/source/index.d.ts +2 -2
  44. package/lib/rtp/src/processor/source/index.js +16 -3
  45. package/lib/rtp/src/processor/source/index.js.map +1 -1
  46. package/lib/rtp/src/processor/source/rtpCallback.d.ts +17 -0
  47. package/lib/rtp/src/processor/source/rtpCallback.js +33 -0
  48. package/lib/rtp/src/processor/source/rtpCallback.js.map +1 -0
  49. package/lib/rtp/src/processor/source/{rtp.d.ts → rtpStream.d.ts} +2 -5
  50. package/lib/rtp/src/processor/source/{rtp.js → rtpStream.js} +12 -12
  51. package/lib/rtp/src/processor/source/rtpStream.js.map +1 -0
  52. package/lib/rtp/src/processor/webm.d.ts +17 -2
  53. package/lib/rtp/src/processor/webm.js +83 -33
  54. package/lib/rtp/src/processor/webm.js.map +1 -1
  55. package/lib/rtp/src/processor/webmCallback.d.ts +16 -0
  56. package/lib/rtp/src/processor/webmCallback.js +21 -0
  57. package/lib/rtp/src/processor/webmCallback.js.map +1 -0
  58. package/lib/rtp/src/processor/webmStream.d.ts +5 -16
  59. package/lib/rtp/src/processor/webmStream.js.map +1 -1
  60. package/lib/{webrtc/src/media/receiver/red.d.ts → rtp/src/rtp/red/handler.d.ts} +2 -2
  61. package/lib/{webrtc/src/media/receiver/red.js → rtp/src/rtp/red/handler.js} +10 -10
  62. package/lib/rtp/src/rtp/red/handler.js.map +1 -0
  63. package/lib/webrtc/src/const.d.ts +1 -1
  64. package/lib/webrtc/src/const.js +2 -2
  65. package/lib/webrtc/src/const.js.map +1 -1
  66. package/lib/webrtc/src/media/receiver/nack.d.ts +1 -0
  67. package/lib/webrtc/src/media/receiver/nack.js +29 -16
  68. package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
  69. package/lib/webrtc/src/media/router.js +17 -13
  70. package/lib/webrtc/src/media/router.js.map +1 -1
  71. package/lib/webrtc/src/media/rtpReceiver.d.ts +1 -1
  72. package/lib/webrtc/src/media/rtpReceiver.js +14 -9
  73. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  74. package/lib/webrtc/src/media/rtpTransceiver.d.ts +10 -6
  75. package/lib/webrtc/src/media/rtpTransceiver.js +23 -14
  76. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  77. package/lib/webrtc/src/media/track.js +3 -2
  78. package/lib/webrtc/src/media/track.js.map +1 -1
  79. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  80. package/lib/webrtc/src/nonstandard/userMedia.d.ts +20 -3
  81. package/lib/webrtc/src/nonstandard/userMedia.js +79 -8
  82. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  83. package/lib/webrtc/src/peerConnection.d.ts +5 -2
  84. package/lib/webrtc/src/peerConnection.js +72 -46
  85. package/lib/webrtc/src/peerConnection.js.map +1 -1
  86. package/lib/webrtc/src/sdp.js +2 -2
  87. package/lib/webrtc/src/sdp.js.map +1 -1
  88. package/lib/webrtc/src/transport/ice.js +10 -3
  89. package/lib/webrtc/src/transport/ice.js.map +1 -1
  90. package/lib/webrtc/src/utils.d.ts +0 -1
  91. package/lib/webrtc/src/utils.js +1 -3
  92. package/lib/webrtc/src/utils.js.map +1 -1
  93. package/package.json +1 -1
  94. package/src/const.ts +1 -1
  95. package/src/media/receiver/nack.ts +33 -17
  96. package/src/media/router.ts +16 -13
  97. package/src/media/rtpReceiver.ts +21 -9
  98. package/src/media/rtpTransceiver.ts +28 -15
  99. package/src/media/track.ts +3 -2
  100. package/src/nonstandard/recorder/writer/webm.ts +2 -2
  101. package/src/nonstandard/userMedia.ts +89 -7
  102. package/src/peerConnection.ts +88 -51
  103. package/src/sdp.ts +2 -2
  104. package/src/transport/ice.ts +13 -3
  105. package/src/utils.ts +0 -3
  106. package/lib/rtp/src/processor/source/rtp.js.map +0 -1
  107. package/lib/webrtc/src/media/receiver/red.js.map +0 -1
  108. package/src/media/receiver/red.ts +0 -70
@@ -1,16 +1,22 @@
1
1
  /// <reference types="node" />
2
- import * as EBML from "@shinyoshiaki/ebml-builder";
2
+ import * as EBML from "./ebml";
3
3
  export declare class WEBMBuilder {
4
4
  readonly ebmlHeader: Uint8Array;
5
5
  trackEntries: EBML.EBMLData[];
6
+ private trackIvs;
7
+ trackKeyIds: {
8
+ [trackNumber: number]: Buffer;
9
+ };
10
+ encryptionKey?: Buffer;
11
+ readonly encryptionKeyID: Buffer;
6
12
  constructor(tracks: {
7
13
  width?: number;
8
14
  height?: number;
9
15
  kind: "audio" | "video";
10
16
  codec: SupportedCodec;
11
17
  trackNumber: number;
12
- }[]);
13
- createTrackEntry(kind: string, trackNumber: number, codec: string, { width, height }: Partial<{
18
+ }[], encryptionKey?: Buffer);
19
+ createTrackEntry(kind: string, trackNumber: number, codec: string, { width, height, }?: Partial<{
14
20
  kind: string;
15
21
  width: number;
16
22
  height: number;
@@ -24,7 +30,7 @@ export declare class WEBMBuilder {
24
30
  createCuePoint(relativeTimestamp: number, trackNumber: number, clusterPosition: number, blockNumber: number): EBML.EBMLData;
25
31
  createCues(cuePoints: EBML.EBMLData[]): Uint8Array;
26
32
  createCluster(timecode: number): Uint8Array;
27
- createSimpleBlock(data: Buffer, isKeyframe: boolean, trackNumber: number, relativeTimestamp: number): Buffer;
33
+ createSimpleBlock(frame: Buffer, isKeyframe: boolean, trackNumber: number, relativeTimestamp: number): Buffer;
28
34
  }
29
35
  declare const supportedCodecs: readonly ["MPEG4/ISO/AVC", "VP8", "VP9", "AV1", "OPUS"];
30
36
  export declare type SupportedCodec = typeof supportedCodecs[number];
@@ -24,11 +24,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.WEBMBuilder = void 0;
27
- const EBML = __importStar(require("@shinyoshiaki/ebml-builder"));
27
+ const crypto_1 = require("crypto");
28
28
  const src_1 = require("../../../common/src");
29
29
  const __1 = require("..");
30
+ const EBML = __importStar(require("./ebml"));
30
31
  class WEBMBuilder {
31
- constructor(tracks) {
32
+ constructor(tracks, encryptionKey) {
32
33
  this.ebmlHeader = EBML.build(EBML.element(EBML.ID.EBML, [
33
34
  EBML.element(EBML.ID.EBMLVersion, EBML.number(1)),
34
35
  EBML.element(EBML.ID.EBMLReadVersion, EBML.number(1)),
@@ -39,16 +40,27 @@ class WEBMBuilder {
39
40
  EBML.element(EBML.ID.DocTypeReadVersion, EBML.number(2)),
40
41
  ]));
41
42
  this.trackEntries = [];
43
+ this.trackIvs = {};
44
+ this.trackKeyIds = {};
45
+ this.encryptionKeyID = (0, crypto_1.randomBytes)(16);
46
+ this.encryptionKey = encryptionKey;
42
47
  this.trackEntries = tracks.map(({ width, height, kind, codec, trackNumber }) => {
43
- return this.createTrackEntry(kind, trackNumber, codec, {
48
+ const track = this.createTrackEntry(kind, trackNumber, codec, {
44
49
  width,
45
50
  height,
46
51
  });
52
+ const ivCounter = new Uint32Array(2);
53
+ (0, crypto_1.randomFillSync)(ivCounter);
54
+ this.trackIvs[trackNumber] = ivCounter;
55
+ return track;
47
56
  });
48
57
  }
49
- createTrackEntry(kind, trackNumber, codec, { width, height }) {
58
+ createTrackEntry(kind, trackNumber, codec, { width, height, } = {}) {
50
59
  const trackElements = [];
51
60
  if (kind === "video") {
61
+ if (!width || !height) {
62
+ throw new Error();
63
+ }
52
64
  trackElements.push(EBML.element(EBML.ID.Video, [
53
65
  EBML.element(EBML.ID.PixelWidth, EBML.number(width)),
54
66
  EBML.element(EBML.ID.PixelHeight, EBML.number(height)),
@@ -62,6 +74,20 @@ class WEBMBuilder {
62
74
  // only support OPUS
63
75
  trackElements.push(EBML.element(EBML.ID.CodecPrivate, EBML.bytes(__1.OpusRtpPayload.createCodecPrivate())));
64
76
  }
77
+ if (this.encryptionKey) {
78
+ const encryptionKeyID = this.encryptionKeyID;
79
+ this.trackKeyIds[trackNumber] = encryptionKeyID;
80
+ trackElements.push(EBML.element(EBML.ID.ContentEncodings, EBML.element(EBML.ID.ContentEncoding, [
81
+ EBML.element(EBML.ID.ContentEncodingOrder, EBML.number(0)),
82
+ EBML.element(EBML.ID.ContentEncodingScope, EBML.number(1)),
83
+ EBML.element(EBML.ID.ContentEncodingType, EBML.number(1)),
84
+ EBML.element(EBML.ID.ContentEncryption, [
85
+ EBML.element(EBML.ID.EncryptionAlgorithm, EBML.number(5)),
86
+ EBML.element(EBML.ID.EncryptionKeyID, EBML.bytes(encryptionKeyID)),
87
+ EBML.element(EBML.ID.ContentEncAESSettings, EBML.element(EBML.ID.AESSettingsCipherMode, EBML.number(1))),
88
+ ]),
89
+ ])));
90
+ }
65
91
  const trackEntry = EBML.element(EBML.ID.TrackEntry, [
66
92
  EBML.element(EBML.ID.TrackNumber, EBML.number(trackNumber)),
67
93
  EBML.element(EBML.ID.TrackUID, EBML.number(trackNumber)),
@@ -112,9 +138,32 @@ class WEBMBuilder {
112
138
  EBML.element(EBML.ID.Timecode, EBML.number(timecode)),
113
139
  ]));
114
140
  }
115
- createSimpleBlock(data, isKeyframe, trackNumber, relativeTimestamp) {
141
+ createSimpleBlock(frame, isKeyframe, trackNumber, relativeTimestamp) {
116
142
  const elementId = Buffer.from([0xa3]);
117
- const contentSize = EBML.vintEncodedNumber(1 + 2 + 1 + data.length).bytes;
143
+ if (this.encryptionKey) {
144
+ // 4.7 Signal Byte Format
145
+ // 0 1 2 3 4 5 6 7
146
+ // +-+-+-+-+-+-+-+-+
147
+ // |X| RSV |P|E|
148
+ // +-+-+-+-+-+-+-+-+
149
+ const singleByte = new src_1.BitWriter2(8).set(0).set(0, 5).set(0).set(1);
150
+ const iv = Buffer.alloc(16);
151
+ const ivCounter = this.trackIvs[trackNumber];
152
+ iv.writeUInt32BE(ivCounter[0], 0);
153
+ iv.writeUInt32BE(ivCounter[1], 4);
154
+ ivCounter[1]++;
155
+ if (ivCounter[1] === 0) {
156
+ ivCounter[0]++;
157
+ }
158
+ const cipher = (0, crypto_1.createCipheriv)("AES-128-CTR", this.encryptionKey, iv);
159
+ frame = Buffer.concat([
160
+ singleByte.buffer,
161
+ iv.subarray(0, 8),
162
+ cipher.update(frame),
163
+ cipher.final(),
164
+ ]);
165
+ }
166
+ const contentSize = EBML.vintEncodedNumber(1 + 2 + 1 + frame.length).bytes;
118
167
  const keyframe = isKeyframe ? 1 : 0;
119
168
  const flags = new src_1.BitWriter2(8)
120
169
  .set(keyframe)
@@ -128,7 +177,7 @@ class WEBMBuilder {
128
177
  EBML.vintEncodedNumber(trackNumber).bytes,
129
178
  new src_1.BufferChain(2).writeInt16BE(relativeTimestamp).buffer,
130
179
  new src_1.BufferChain(1).writeUInt8(flags.value).buffer,
131
- data,
180
+ frame,
132
181
  ]);
133
182
  return simpleBlock;
134
183
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/container/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import * as EBML from \"@shinyoshiaki/ebml-builder\";\n\nimport { BitWriter2, BufferChain } from \"../../../common/src\";\nimport { OpusRtpPayload } from \"..\";\n\nexport class WEBMBuilder {\n readonly ebmlHeader = EBML.build(\n EBML.element(EBML.ID.EBML, [\n EBML.element(EBML.ID.EBMLVersion, EBML.number(1)),\n EBML.element(EBML.ID.EBMLReadVersion, EBML.number(1)),\n EBML.element(EBML.ID.EBMLMaxIDLength, EBML.number(4)),\n EBML.element(EBML.ID.EBMLMaxSizeLength, EBML.number(8)),\n EBML.element(EBML.ID.DocType, EBML.string(\"webm\")),\n EBML.element(EBML.ID.DocTypeVersion, EBML.number(2)),\n EBML.element(EBML.ID.DocTypeReadVersion, EBML.number(2)),\n ])\n );\n trackEntries: EBML.EBMLData[] = [];\n\n constructor(\n tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n trackNumber: number;\n }[]\n ) {\n this.trackEntries = tracks.map(\n ({ width, height, kind, codec, trackNumber }) => {\n return this.createTrackEntry(kind, trackNumber, codec, {\n width,\n height,\n });\n }\n );\n }\n\n createTrackEntry(\n kind: string,\n trackNumber: number,\n codec: string,\n { width, height }: Partial<{ kind: string; width: number; height: number }>\n ) {\n const trackElements: EBML.EBMLData[] = [];\n if (kind === \"video\") {\n trackElements.push(\n EBML.element(EBML.ID.Video, [\n EBML.element(EBML.ID.PixelWidth, EBML.number(width)),\n EBML.element(EBML.ID.PixelHeight, EBML.number(height)),\n ])\n );\n } else {\n trackElements.push(\n EBML.element(EBML.ID.Audio, [\n EBML.element(EBML.ID.SamplingFrequency, EBML.float(48000.0)),\n EBML.element(EBML.ID.Channels, EBML.number(2)),\n ])\n );\n // only support OPUS\n trackElements.push(\n EBML.element(\n EBML.ID.CodecPrivate,\n EBML.bytes(OpusRtpPayload.createCodecPrivate())\n )\n );\n }\n\n const trackEntry = EBML.element(EBML.ID.TrackEntry, [\n EBML.element(EBML.ID.TrackNumber, EBML.number(trackNumber)),\n EBML.element(EBML.ID.TrackUID, EBML.number(trackNumber)),\n EBML.element(EBML.ID.CodecName, EBML.string(codec)),\n EBML.element(EBML.ID.TrackType, EBML.number(kind === \"video\" ? 1 : 2)),\n EBML.element(\n EBML.ID.CodecID,\n EBML.string(`${kind === \"video\" ? \"V\" : \"A\"}_${codec}`)\n ),\n ...trackElements,\n ]);\n return trackEntry;\n }\n\n createSegment(\n /**ms */\n duration?: number\n ) {\n const elements = [\n EBML.element(EBML.ID.TimecodeScale, EBML.number(millisecond)),\n EBML.element(EBML.ID.MuxingApp, EBML.string(\"webrtc\")),\n EBML.element(EBML.ID.WritingApp, EBML.string(\"webrtc\")),\n ];\n if (duration != undefined) {\n elements.push(EBML.element(EBML.ID.Duration, EBML.float(duration)));\n }\n return EBML.build(\n EBML.unknownSizeElement(EBML.ID.Segment, [\n EBML.element(EBML.ID.SeekHead, []),\n EBML.element(EBML.ID.Info, elements),\n EBML.element(EBML.ID.Tracks, this.trackEntries),\n ])\n );\n }\n\n createDuration(\n /**ms */\n duration: number\n ) {\n return EBML.build(EBML.element(EBML.ID.Duration, EBML.float(duration)));\n }\n\n createCuePoint(\n relativeTimestamp: number,\n trackNumber: number,\n clusterPosition: number,\n blockNumber: number\n ) {\n return EBML.element(EBML.ID.CuePoint, [\n EBML.element(EBML.ID.CueTime, EBML.number(relativeTimestamp)),\n EBML.element(EBML.ID.CueTrackPositions, [\n EBML.element(EBML.ID.CueTrack, EBML.number(trackNumber)),\n EBML.element(EBML.ID.CueClusterPosition, EBML.number(clusterPosition)),\n EBML.element(EBML.ID.CueBlockNumber, EBML.number(blockNumber)),\n ]),\n ]);\n }\n\n createCues(cuePoints: EBML.EBMLData[]) {\n return EBML.build(EBML.element(EBML.ID.Cues, cuePoints));\n }\n\n createCluster(timecode: number) {\n return EBML.build(\n EBML.unknownSizeElement(EBML.ID.Cluster, [\n EBML.element(EBML.ID.Timecode, EBML.number(timecode)),\n ])\n );\n }\n\n createSimpleBlock(\n data: Buffer,\n isKeyframe: boolean,\n trackNumber: number,\n relativeTimestamp: number\n ) {\n const elementId = Buffer.from([0xa3]);\n const contentSize: Uint8Array = EBML.vintEncodedNumber(\n 1 + 2 + 1 + data.length\n ).bytes;\n\n const keyframe = isKeyframe ? 1 : 0;\n const flags = new BitWriter2(8)\n .set(keyframe)\n .set(0, 3)\n .set(0)\n .set(0, 2)\n .set(0);\n\n const simpleBlock = Buffer.concat([\n elementId,\n contentSize,\n EBML.vintEncodedNumber(trackNumber).bytes,\n new BufferChain(2).writeInt16BE(relativeTimestamp).buffer,\n new BufferChain(1).writeUInt8(flags.value).buffer,\n data,\n ]);\n return simpleBlock;\n }\n}\n\nconst supportedCodecs = [\"MPEG4/ISO/AVC\", \"VP8\", \"VP9\", \"AV1\", \"OPUS\"] as const;\nexport type SupportedCodec = typeof supportedCodecs[number];\nconst millisecond = 1000000;\n"]}
1
+ {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/container/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, randomBytes, randomFillSync } from \"crypto\";\n\nimport { BitWriter2, BufferChain } from \"../../../common/src\";\nimport { OpusRtpPayload } from \"..\";\nimport * as EBML from \"./ebml\";\n\nexport class WEBMBuilder {\n readonly ebmlHeader = EBML.build(\n EBML.element(EBML.ID.EBML, [\n EBML.element(EBML.ID.EBMLVersion, EBML.number(1)),\n EBML.element(EBML.ID.EBMLReadVersion, EBML.number(1)),\n EBML.element(EBML.ID.EBMLMaxIDLength, EBML.number(4)),\n EBML.element(EBML.ID.EBMLMaxSizeLength, EBML.number(8)),\n EBML.element(EBML.ID.DocType, EBML.string(\"webm\")),\n EBML.element(EBML.ID.DocTypeVersion, EBML.number(2)),\n EBML.element(EBML.ID.DocTypeReadVersion, EBML.number(2)),\n ])\n );\n trackEntries: EBML.EBMLData[] = [];\n private trackIvs: { [trackNumber: number]: Uint32Array } = {};\n trackKeyIds: { [trackNumber: number]: Buffer } = {};\n encryptionKey?: Buffer;\n readonly encryptionKeyID = randomBytes(16);\n\n constructor(\n tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n trackNumber: number;\n }[],\n encryptionKey?: Buffer\n ) {\n this.encryptionKey = encryptionKey;\n\n this.trackEntries = tracks.map(\n ({ width, height, kind, codec, trackNumber }) => {\n const track = this.createTrackEntry(kind, trackNumber, codec, {\n width,\n height,\n });\n const ivCounter = new Uint32Array(2);\n randomFillSync(ivCounter);\n this.trackIvs[trackNumber] = ivCounter;\n\n return track;\n }\n );\n }\n\n createTrackEntry(\n kind: string,\n trackNumber: number,\n codec: string,\n {\n width,\n height,\n }: Partial<{\n kind: string;\n width: number;\n height: number;\n }> = {}\n ) {\n const trackElements: EBML.EBMLData[] = [];\n\n if (kind === \"video\") {\n if (!width || !height) {\n throw new Error();\n }\n trackElements.push(\n EBML.element(EBML.ID.Video, [\n EBML.element(EBML.ID.PixelWidth, EBML.number(width)),\n EBML.element(EBML.ID.PixelHeight, EBML.number(height)),\n ])\n );\n } else {\n trackElements.push(\n EBML.element(EBML.ID.Audio, [\n EBML.element(EBML.ID.SamplingFrequency, EBML.float(48000.0)),\n EBML.element(EBML.ID.Channels, EBML.number(2)),\n ])\n );\n // only support OPUS\n trackElements.push(\n EBML.element(\n EBML.ID.CodecPrivate,\n EBML.bytes(OpusRtpPayload.createCodecPrivate())\n )\n );\n }\n\n if (this.encryptionKey) {\n const encryptionKeyID = this.encryptionKeyID;\n this.trackKeyIds[trackNumber] = encryptionKeyID;\n\n trackElements.push(\n EBML.element(\n EBML.ID.ContentEncodings,\n EBML.element(EBML.ID.ContentEncoding, [\n EBML.element(EBML.ID.ContentEncodingOrder, EBML.number(0)),\n EBML.element(EBML.ID.ContentEncodingScope, EBML.number(1)),\n EBML.element(EBML.ID.ContentEncodingType, EBML.number(1)),\n EBML.element(EBML.ID.ContentEncryption, [\n EBML.element(EBML.ID.EncryptionAlgorithm, EBML.number(5)),\n EBML.element(\n EBML.ID.EncryptionKeyID,\n EBML.bytes(encryptionKeyID)\n ),\n EBML.element(\n EBML.ID.ContentEncAESSettings,\n EBML.element(EBML.ID.AESSettingsCipherMode, EBML.number(1))\n ),\n ]),\n ])\n )\n );\n }\n\n const trackEntry = EBML.element(EBML.ID.TrackEntry, [\n EBML.element(EBML.ID.TrackNumber, EBML.number(trackNumber)),\n EBML.element(EBML.ID.TrackUID, EBML.number(trackNumber)),\n EBML.element(EBML.ID.CodecName, EBML.string(codec)),\n EBML.element(EBML.ID.TrackType, EBML.number(kind === \"video\" ? 1 : 2)),\n EBML.element(\n EBML.ID.CodecID,\n EBML.string(`${kind === \"video\" ? \"V\" : \"A\"}_${codec}`)\n ),\n ...trackElements,\n ]);\n return trackEntry;\n }\n\n createSegment(\n /**ms */\n duration?: number\n ) {\n const elements = [\n EBML.element(EBML.ID.TimecodeScale, EBML.number(millisecond)),\n EBML.element(EBML.ID.MuxingApp, EBML.string(\"webrtc\")),\n EBML.element(EBML.ID.WritingApp, EBML.string(\"webrtc\")),\n ];\n if (duration != undefined) {\n elements.push(EBML.element(EBML.ID.Duration, EBML.float(duration)));\n }\n return EBML.build(\n EBML.unknownSizeElement(EBML.ID.Segment, [\n EBML.element(EBML.ID.SeekHead, []),\n EBML.element(EBML.ID.Info, elements),\n EBML.element(EBML.ID.Tracks, this.trackEntries),\n ])\n );\n }\n\n createDuration(\n /**ms */\n duration: number\n ) {\n return EBML.build(EBML.element(EBML.ID.Duration, EBML.float(duration)));\n }\n\n createCuePoint(\n relativeTimestamp: number,\n trackNumber: number,\n clusterPosition: number,\n blockNumber: number\n ) {\n return EBML.element(EBML.ID.CuePoint, [\n EBML.element(EBML.ID.CueTime, EBML.number(relativeTimestamp)),\n EBML.element(EBML.ID.CueTrackPositions, [\n EBML.element(EBML.ID.CueTrack, EBML.number(trackNumber)),\n EBML.element(EBML.ID.CueClusterPosition, EBML.number(clusterPosition)),\n EBML.element(EBML.ID.CueBlockNumber, EBML.number(blockNumber)),\n ]),\n ]);\n }\n\n createCues(cuePoints: EBML.EBMLData[]) {\n return EBML.build(EBML.element(EBML.ID.Cues, cuePoints));\n }\n\n createCluster(timecode: number) {\n return EBML.build(\n EBML.unknownSizeElement(EBML.ID.Cluster, [\n EBML.element(EBML.ID.Timecode, EBML.number(timecode)),\n ])\n );\n }\n\n createSimpleBlock(\n frame: Buffer,\n isKeyframe: boolean,\n trackNumber: number,\n relativeTimestamp: number\n ) {\n const elementId = Buffer.from([0xa3]);\n\n if (this.encryptionKey) {\n // 4.7 Signal Byte Format\n // 0 1 2 3 4 5 6 7\n // +-+-+-+-+-+-+-+-+\n // |X| RSV |P|E|\n // +-+-+-+-+-+-+-+-+\n const singleByte = new BitWriter2(8).set(0).set(0, 5).set(0).set(1);\n\n const iv = Buffer.alloc(16);\n const ivCounter = this.trackIvs[trackNumber];\n iv.writeUInt32BE(ivCounter[0], 0);\n iv.writeUInt32BE(ivCounter[1], 4);\n ivCounter[1]++;\n if (ivCounter[1] === 0) {\n ivCounter[0]++;\n }\n\n const cipher = createCipheriv(\"AES-128-CTR\", this.encryptionKey, iv);\n\n frame = Buffer.concat([\n singleByte.buffer,\n iv.subarray(0, 8),\n cipher.update(frame),\n cipher.final(),\n ]);\n }\n\n const contentSize: Uint8Array = EBML.vintEncodedNumber(\n 1 + 2 + 1 + frame.length\n ).bytes;\n\n const keyframe = isKeyframe ? 1 : 0;\n const flags = new BitWriter2(8)\n .set(keyframe)\n .set(0, 3)\n .set(0)\n .set(0, 2)\n .set(0);\n\n const simpleBlock = Buffer.concat([\n elementId,\n contentSize,\n EBML.vintEncodedNumber(trackNumber).bytes,\n new BufferChain(2).writeInt16BE(relativeTimestamp).buffer,\n new BufferChain(1).writeUInt8(flags.value).buffer,\n frame,\n ]);\n return simpleBlock;\n }\n}\n\nconst supportedCodecs = [\"MPEG4/ISO/AVC\", \"VP8\", \"VP9\", \"AV1\", \"OPUS\"] as const;\nexport type SupportedCodec = typeof supportedCodecs[number];\nconst millisecond = 1000000;\n"]}
@@ -14,6 +14,7 @@ export * from "./rtcp/rtpfb/twcc";
14
14
  export * from "./rtcp/sdes";
15
15
  export * from "./rtcp/sr";
16
16
  export * from "./rtp/red/encoder";
17
+ export * from "./rtp/red/handler";
17
18
  export * from "./rtp/red/packet";
18
19
  export * from "./rtp/rtp";
19
20
  export * from "./srtp/srtcp";
@@ -30,6 +30,7 @@ __exportStar(require("./rtcp/rtpfb/twcc"), exports);
30
30
  __exportStar(require("./rtcp/sdes"), exports);
31
31
  __exportStar(require("./rtcp/sr"), exports);
32
32
  __exportStar(require("./rtp/red/encoder"), exports);
33
+ __exportStar(require("./rtp/red/handler"), exports);
33
34
  __exportStar(require("./rtp/red/packet"), exports);
34
35
  __exportStar(require("./rtp/rtp"), exports);
35
36
  __exportStar(require("./srtp/srtcp"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../rtp/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kBAAgB;AAChB,mDAAiC;AACjC,0CAAwB;AACxB,8CAA4B;AAC5B,gDAA8B;AAC9B,8CAA4B;AAC5B,oEAAkD;AAClD,mDAAiC;AACjC,4CAA0B;AAC1B,8CAA4B;AAC5B,+CAA6B;AAC7B,oDAAkC;AAClC,oDAAkC;AAClC,8CAA4B;AAC5B,4CAA0B;AAC1B,oDAAkC;AAClC,mDAAiC;AACjC,4CAA0B;AAC1B,+CAA6B;AAC7B,8CAA4B","sourcesContent":["import \"buffer\";\nexport * from \"../../common/src\";\nexport * from \"./codec\";\nexport * from \"./processor\";\nexport * from \"./rtcp/header\";\nexport * from \"./rtcp/psfb\";\nexport * from \"./rtcp/psfb/pictureLossIndication\";\nexport * from \"./rtcp/psfb/remb\";\nexport * from \"./rtcp/rr\";\nexport * from \"./rtcp/rtcp\";\nexport * from \"./rtcp/rtpfb\";\nexport * from \"./rtcp/rtpfb/nack\";\nexport * from \"./rtcp/rtpfb/twcc\";\nexport * from \"./rtcp/sdes\";\nexport * from \"./rtcp/sr\";\nexport * from \"./rtp/red/encoder\";\nexport * from \"./rtp/red/packet\";\nexport * from \"./rtp/rtp\";\nexport * from \"./srtp/srtcp\";\nexport * from \"./srtp/srtp\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../rtp/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kBAAgB;AAChB,mDAAiC;AACjC,0CAAwB;AACxB,8CAA4B;AAC5B,gDAA8B;AAC9B,8CAA4B;AAC5B,oEAAkD;AAClD,mDAAiC;AACjC,4CAA0B;AAC1B,8CAA4B;AAC5B,+CAA6B;AAC7B,oDAAkC;AAClC,oDAAkC;AAClC,8CAA4B;AAC5B,4CAA0B;AAC1B,oDAAkC;AAClC,oDAAkC;AAClC,mDAAiC;AACjC,4CAA0B;AAC1B,+CAA6B;AAC7B,8CAA4B","sourcesContent":["import \"buffer\";\nexport * from \"../../common/src\";\nexport * from \"./codec\";\nexport * from \"./processor\";\nexport * from \"./rtcp/header\";\nexport * from \"./rtcp/psfb\";\nexport * from \"./rtcp/psfb/pictureLossIndication\";\nexport * from \"./rtcp/psfb/remb\";\nexport * from \"./rtcp/rr\";\nexport * from \"./rtcp/rtcp\";\nexport * from \"./rtcp/rtpfb\";\nexport * from \"./rtcp/rtpfb/nack\";\nexport * from \"./rtcp/rtpfb/twcc\";\nexport * from \"./rtcp/sdes\";\nexport * from \"./rtcp/sr\";\nexport * from \"./rtp/red/encoder\";\nexport * from \"./rtp/red/handler\";\nexport * from \"./rtp/red/packet\";\nexport * from \"./rtp/rtp\";\nexport * from \"./srtp/srtcp\";\nexport * from \"./srtp/srtp\";\n"]}
@@ -0,0 +1,28 @@
1
+ import { DepacketizerOutput } from "./depacketizer";
2
+ export declare type AVBufferInput = DepacketizerOutput;
3
+ export declare type AVBufferOutput = AVBufferInput;
4
+ export declare class AVBufferBase {
5
+ private audioOutput;
6
+ private videoOutput;
7
+ private options;
8
+ bufferLength: number;
9
+ baseAudioTimestamp?: number;
10
+ baseVideoTimestamp?: number;
11
+ audioBuffer: (AVBufferInput & {
12
+ elapsed: number;
13
+ kind: string;
14
+ })[][];
15
+ videoBuffer: (AVBufferInput & {
16
+ elapsed: number;
17
+ kind: string;
18
+ })[][];
19
+ stopped: boolean;
20
+ private interval;
21
+ constructor(audioOutput: (output: AVBufferOutput) => void, videoOutput: (output: AVBufferOutput) => void, options?: Partial<AvBufferOptions>);
22
+ processAudioInput: (input: AVBufferInput) => void;
23
+ processVideoInput: (input: AVBufferInput) => void;
24
+ private calcElapsed;
25
+ }
26
+ export interface AvBufferOptions {
27
+ interval: number;
28
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AVBufferBase = void 0;
4
+ const src_1 = require("../../../common/src");
5
+ const webm_1 = require("./webm");
6
+ class AVBufferBase {
7
+ constructor(audioOutput, videoOutput, options = {}) {
8
+ this.audioOutput = audioOutput;
9
+ this.videoOutput = videoOutput;
10
+ this.options = options;
11
+ this.bufferLength = 50;
12
+ this.audioBuffer = [
13
+ ...new Array(this.bufferLength),
14
+ ].map(() => []);
15
+ this.videoBuffer = [
16
+ ...new Array(this.bufferLength),
17
+ ].map(() => []);
18
+ this.stopped = false;
19
+ this.interval = this.options.interval ?? 500;
20
+ this.processAudioInput = (input) => {
21
+ if (!input.frame) {
22
+ this.stopped = true;
23
+ this.audioOutput(input);
24
+ return;
25
+ }
26
+ if (this.stopped) {
27
+ return;
28
+ }
29
+ if (this.baseAudioTimestamp == undefined) {
30
+ this.baseAudioTimestamp = input.frame?.timestamp;
31
+ }
32
+ const { elapsed, rotate } = this.calcElapsed(this.baseAudioTimestamp, input.frame.timestamp, 48000);
33
+ if (rotate) {
34
+ this.baseAudioTimestamp = input.frame?.timestamp;
35
+ }
36
+ const index = (0, src_1.int)(elapsed / this.interval) % this.bufferLength;
37
+ this.audioBuffer[index].push({ ...input, elapsed, kind: "audio" });
38
+ };
39
+ this.processVideoInput = (input) => {
40
+ if (!input.frame) {
41
+ this.stopped = true;
42
+ this.videoOutput(input);
43
+ return;
44
+ }
45
+ if (this.stopped) {
46
+ return;
47
+ }
48
+ if (this.baseVideoTimestamp == undefined) {
49
+ this.baseVideoTimestamp = input.frame?.timestamp;
50
+ }
51
+ const { elapsed, rotate } = this.calcElapsed(this.baseVideoTimestamp, input.frame.timestamp, 90000);
52
+ if (rotate) {
53
+ this.baseVideoTimestamp = input.frame?.timestamp;
54
+ }
55
+ const index = (0, src_1.int)(elapsed / this.interval) % this.bufferLength;
56
+ this.videoBuffer[index].push({ ...input, elapsed, kind: "video" });
57
+ };
58
+ let index = 0;
59
+ setInterval(() => {
60
+ const joined = [...this.audioBuffer[index], ...this.videoBuffer[index]];
61
+ const sorted = joined.sort((a, b) => a.elapsed - b.elapsed);
62
+ this.audioBuffer[index] = [];
63
+ this.videoBuffer[index] = [];
64
+ // console.log(sorted.map((v) => ({ elapsed: v.elapsed, kind: v.kind })));
65
+ for (const output of sorted) {
66
+ if (output.kind === "audio") {
67
+ audioOutput(output);
68
+ }
69
+ else {
70
+ videoOutput(output);
71
+ }
72
+ }
73
+ index++;
74
+ if (index === this.bufferLength) {
75
+ index = 0;
76
+ }
77
+ }, this.interval);
78
+ }
79
+ calcElapsed(base, timestamp, clockRate) {
80
+ const rotate = Math.abs(timestamp - base) > (webm_1.Max32Uint / 4) * 3;
81
+ if (rotate) {
82
+ console.log(rotate);
83
+ }
84
+ const diff = rotate ? timestamp + webm_1.Max32Uint - base : timestamp - base;
85
+ /**ms */
86
+ const elapsed = (0, src_1.int)((diff / clockRate) * 1000);
87
+ return { elapsed, rotate };
88
+ }
89
+ }
90
+ exports.AVBufferBase = AVBufferBase;
91
+ //# sourceMappingURL=avBuffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avBuffer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/avBuffer.ts"],"names":[],"mappings":"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","sourcesContent":["import { int } from \"../../../common/src\";\nimport { DepacketizerOutput } from \"./depacketizer\";\nimport { Max32Uint } from \"./webm\";\n\nexport type AVBufferInput = DepacketizerOutput;\n\nexport type AVBufferOutput = AVBufferInput;\n\nexport class AVBufferBase {\n bufferLength = 50;\n baseAudioTimestamp?: number;\n baseVideoTimestamp?: number;\n audioBuffer: (AVBufferInput & { elapsed: number; kind: string })[][] = [\n ...new Array(this.bufferLength),\n ].map(() => []);\n videoBuffer: (AVBufferInput & { elapsed: number; kind: string })[][] = [\n ...new Array(this.bufferLength),\n ].map(() => []);\n stopped = false;\n private interval = this.options.interval ?? 500;\n\n constructor(\n private audioOutput: (output: AVBufferOutput) => void,\n private videoOutput: (output: AVBufferOutput) => void,\n private options: Partial<AvBufferOptions> = {}\n ) {\n let index = 0;\n setInterval(() => {\n const joined = [...this.audioBuffer[index], ...this.videoBuffer[index]];\n const sorted = joined.sort((a, b) => a.elapsed - b.elapsed);\n this.audioBuffer[index] = [];\n this.videoBuffer[index] = [];\n\n // console.log(sorted.map((v) => ({ elapsed: v.elapsed, kind: v.kind })));\n\n for (const output of sorted) {\n if (output.kind === \"audio\") {\n audioOutput(output);\n } else {\n videoOutput(output);\n }\n }\n\n index++;\n if (index === this.bufferLength) {\n index = 0;\n }\n }, this.interval);\n }\n\n processAudioInput = (input: AVBufferInput) => {\n if (!input.frame) {\n this.stopped = true;\n this.audioOutput(input);\n return;\n }\n if (this.stopped) {\n return;\n }\n\n if (this.baseAudioTimestamp == undefined) {\n this.baseAudioTimestamp = input.frame?.timestamp;\n }\n\n const { elapsed, rotate } = this.calcElapsed(\n this.baseAudioTimestamp,\n input.frame.timestamp,\n 48000\n );\n if (rotate) {\n this.baseAudioTimestamp = input.frame?.timestamp;\n }\n\n const index = int(elapsed / this.interval) % this.bufferLength;\n this.audioBuffer[index].push({ ...input, elapsed, kind: \"audio\" });\n };\n\n processVideoInput = (input: AVBufferInput) => {\n if (!input.frame) {\n this.stopped = true;\n this.videoOutput(input);\n return;\n }\n if (this.stopped) {\n return;\n }\n\n if (this.baseVideoTimestamp == undefined) {\n this.baseVideoTimestamp = input.frame?.timestamp;\n }\n\n const { elapsed, rotate } = this.calcElapsed(\n this.baseVideoTimestamp,\n input.frame.timestamp,\n 90000\n );\n if (rotate) {\n this.baseVideoTimestamp = input.frame?.timestamp;\n }\n\n const index = int(elapsed / this.interval) % this.bufferLength;\n this.videoBuffer[index].push({ ...input, elapsed, kind: \"video\" });\n };\n\n private calcElapsed(base: number, timestamp: number, clockRate: number) {\n const rotate = Math.abs(timestamp - base) > (Max32Uint / 4) * 3;\n if (rotate) {\n console.log(rotate);\n }\n\n const diff = rotate ? timestamp + Max32Uint - base : timestamp - base;\n /**ms */\n const elapsed = int((diff / clockRate) * 1000);\n return { elapsed, rotate };\n }\n}\n\nexport interface AvBufferOptions {\n interval: number;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { AVBufferBase, AvBufferOptions, AVBufferOutput } from "./avBuffer";
2
+ export declare class AvBufferCallback extends AVBufferBase {
3
+ private audioCb;
4
+ private videoCb;
5
+ constructor(options?: Partial<AvBufferOptions>);
6
+ pipeAudio: (cb: (input: AVBufferOutput) => void) => void;
7
+ pipeVideo: (cb: (input: AVBufferOutput) => void) => void;
8
+ inputAudio: (input: import("./depacketizer").DepacketizerOutput) => void;
9
+ inputVideo: (input: import("./depacketizer").DepacketizerOutput) => void;
10
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AvBufferCallback = void 0;
4
+ const avBuffer_1 = require("./avBuffer");
5
+ class AvBufferCallback extends avBuffer_1.AVBufferBase {
6
+ constructor(options = {}) {
7
+ super((output) => {
8
+ if (this.audioCb) {
9
+ this.audioCb(output);
10
+ }
11
+ }, (output) => {
12
+ if (this.videoCb) {
13
+ this.videoCb(output);
14
+ }
15
+ }, options);
16
+ this.pipeAudio = (cb) => {
17
+ this.audioCb = cb;
18
+ };
19
+ this.pipeVideo = (cb) => {
20
+ this.videoCb = cb;
21
+ };
22
+ this.inputAudio = this.processAudioInput;
23
+ this.inputVideo = this.processVideoInput;
24
+ }
25
+ }
26
+ exports.AvBufferCallback = AvBufferCallback;
27
+ //# sourceMappingURL=avBufferCallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avBufferCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/avBufferCallback.ts"],"names":[],"mappings":";;;AAAA,yCAA2E;AAE3E,MAAa,gBAAiB,SAAQ,uBAAY;IAGhD,YAAY,UAAoC,EAAE;QAChD,KAAK,CACH,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;aACtB;QACH,CAAC,EACD,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;aACtB;QACH,CAAC,EACD,OAAO,CACR,CAAC;QAGJ,cAAS,GAAG,CAAC,EAAmC,EAAE,EAAE;YAClD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QACpB,CAAC,CAAC;QACF,cAAS,GAAG,CAAC,EAAmC,EAAE,EAAE;YAClD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QACpB,CAAC,CAAC;QAEF,eAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpC,eAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC;IAVpC,CAAC;CAWF;AA5BD,4CA4BC","sourcesContent":["import { AVBufferBase, AvBufferOptions, AVBufferOutput } from \"./avBuffer\";\n\nexport class AvBufferCallback extends AVBufferBase {\n private audioCb!: (input: AVBufferOutput) => void;\n private videoCb!: (input: AVBufferOutput) => void;\n constructor(options: Partial<AvBufferOptions> = {}) {\n super(\n (output) => {\n if (this.audioCb) {\n this.audioCb(output);\n }\n },\n (output) => {\n if (this.videoCb) {\n this.videoCb(output);\n }\n },\n options\n );\n }\n\n pipeAudio = (cb: (input: AVBufferOutput) => void) => {\n this.audioCb = cb;\n };\n pipeVideo = (cb: (input: AVBufferOutput) => void) => {\n this.videoCb = cb;\n };\n\n inputAudio = this.processAudioInput;\n inputVideo = this.processVideoInput;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { RtpHeader } from "..";
3
3
  import { Processor } from "./interface";
4
- import { RtpOutput } from "./source/rtp";
4
+ import { RtpOutput } from "./source";
5
5
  export declare type DepacketizerInput = RtpOutput;
6
6
  export interface DepacketizerOutput {
7
7
  frame?: {
@@ -1 +1 @@
1
- {"version":3,"file":"depacketizer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/depacketizer.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { RtpHeader, RtpPacket, uint16Add } from \"..\";\nimport { dePacketizeRtpPackets } from \"../codec\";\nimport { enumerate } from \"../helper\";\nimport { Processor } from \"./interface\";\nimport { RtpOutput } from \"./source/rtp\";\n\nconst srcPath = `werift-rtp : packages/rtp/src/processor_v2/depacketizer.ts`;\nconst log = debug(srcPath);\n\nexport type DepacketizerInput = RtpOutput;\n\nexport interface DepacketizerOutput {\n frame?: { data: Buffer; isKeyframe: boolean; timestamp: number };\n eol?: boolean;\n}\n\nexport class DepacketizeBase\n implements Processor<DepacketizerInput, DepacketizerOutput>\n{\n private buffering: RtpPacket[] = [];\n private lastSeqNum?: number;\n private packetLostHappened = false;\n\n constructor(\n private codec: string,\n private options: {\n waitForKeyframe?: boolean;\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n } = {}\n ) {}\n\n processInput(input: DepacketizerInput): DepacketizerOutput[] {\n const output: DepacketizerOutput[] = [];\n if (!input.rtp) {\n if (input.eol) {\n output.push({ eol: true });\n }\n return output;\n }\n\n if (this.options.isFinalPacketInSequence) {\n const isFinal = this.checkFinalPacket(input.rtp);\n if (isFinal) {\n try {\n const { timestamp } = this.buffering[0].header;\n const { data, isKeyframe } = dePacketizeRtpPackets(\n this.codec,\n this.buffering\n );\n this.clearBuffer();\n\n if (this.packetLostHappened) {\n if (isKeyframe) {\n this.packetLostHappened = false;\n } else if (this.options.waitForKeyframe) {\n return [];\n }\n }\n\n output.push({\n frame: {\n data,\n isKeyframe,\n timestamp,\n },\n });\n return output;\n } catch (error) {\n log(\"error\", error, input);\n this.clearBuffer();\n }\n }\n } else {\n try {\n const { data, isKeyframe } = dePacketizeRtpPackets(this.codec, [\n input.rtp,\n ]);\n output.push({\n frame: {\n data,\n isKeyframe,\n timestamp: input.rtp.header.timestamp,\n },\n });\n return output;\n } catch (error) {\n log(\"error\", error, input);\n }\n }\n return [];\n }\n\n private clearBuffer() {\n this.buffering.forEach((b) => b.clear());\n this.buffering = [];\n }\n\n private checkFinalPacket(rtp: RtpPacket): boolean {\n if (!this.options.isFinalPacketInSequence) {\n throw new Error(\"isFinalPacketInSequence not exist\");\n }\n\n const { sequenceNumber } = rtp.header;\n if (this.lastSeqNum != undefined) {\n const expect = uint16Add(this.lastSeqNum, 1);\n if (sequenceNumber < expect) {\n return false;\n }\n if (sequenceNumber > expect) {\n log(\"packet lost happened\", { expect, sequenceNumber });\n this.packetLostHappened = true;\n this.clearBuffer();\n }\n }\n\n this.buffering.push(rtp);\n this.lastSeqNum = sequenceNumber;\n\n let finalPacket: number | undefined;\n for (const [i, p] of enumerate(this.buffering)) {\n if (this.options.isFinalPacketInSequence(p.header)) {\n finalPacket = i;\n break;\n }\n }\n if (finalPacket == undefined) {\n return false;\n }\n\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"depacketizer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/depacketizer.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { RtpHeader, RtpPacket, uint16Add } from \"..\";\nimport { dePacketizeRtpPackets } from \"../codec\";\nimport { enumerate } from \"../helper\";\nimport { Processor } from \"./interface\";\nimport { RtpOutput } from \"./source\";\n\nconst srcPath = `werift-rtp : packages/rtp/src/processor_v2/depacketizer.ts`;\nconst log = debug(srcPath);\n\nexport type DepacketizerInput = RtpOutput;\n\nexport interface DepacketizerOutput {\n frame?: { data: Buffer; isKeyframe: boolean; timestamp: number };\n eol?: boolean;\n}\n\nexport class DepacketizeBase\n implements Processor<DepacketizerInput, DepacketizerOutput>\n{\n private buffering: RtpPacket[] = [];\n private lastSeqNum?: number;\n private packetLostHappened = false;\n\n constructor(\n private codec: string,\n private options: {\n waitForKeyframe?: boolean;\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n } = {}\n ) {}\n\n processInput(input: DepacketizerInput): DepacketizerOutput[] {\n const output: DepacketizerOutput[] = [];\n if (!input.rtp) {\n if (input.eol) {\n output.push({ eol: true });\n }\n return output;\n }\n\n if (this.options.isFinalPacketInSequence) {\n const isFinal = this.checkFinalPacket(input.rtp);\n if (isFinal) {\n try {\n const { timestamp } = this.buffering[0].header;\n const { data, isKeyframe } = dePacketizeRtpPackets(\n this.codec,\n this.buffering\n );\n this.clearBuffer();\n\n if (this.packetLostHappened) {\n if (isKeyframe) {\n this.packetLostHappened = false;\n } else if (this.options.waitForKeyframe) {\n return [];\n }\n }\n\n output.push({\n frame: {\n data,\n isKeyframe,\n timestamp,\n },\n });\n return output;\n } catch (error) {\n log(\"error\", error, input);\n this.clearBuffer();\n }\n }\n } else {\n try {\n const { data, isKeyframe } = dePacketizeRtpPackets(this.codec, [\n input.rtp,\n ]);\n output.push({\n frame: {\n data,\n isKeyframe,\n timestamp: input.rtp.header.timestamp,\n },\n });\n return output;\n } catch (error) {\n log(\"error\", error, input);\n }\n }\n return [];\n }\n\n private clearBuffer() {\n this.buffering.forEach((b) => b.clear());\n this.buffering = [];\n }\n\n private checkFinalPacket(rtp: RtpPacket): boolean {\n if (!this.options.isFinalPacketInSequence) {\n throw new Error(\"isFinalPacketInSequence not exist\");\n }\n\n const { sequenceNumber } = rtp.header;\n if (this.lastSeqNum != undefined) {\n const expect = uint16Add(this.lastSeqNum, 1);\n if (sequenceNumber < expect) {\n return false;\n }\n if (sequenceNumber > expect) {\n log(\"packet lost happened\", { expect, sequenceNumber });\n this.packetLostHappened = true;\n this.clearBuffer();\n }\n }\n\n this.buffering.push(rtp);\n this.lastSeqNum = sequenceNumber;\n\n let finalPacket: number | undefined;\n for (const [i, p] of enumerate(this.buffering)) {\n if (this.options.isFinalPacketInSequence(p.header)) {\n finalPacket = i;\n break;\n }\n }\n if (finalPacket == undefined) {\n return false;\n }\n\n return true;\n }\n}\n"]}
@@ -6,8 +6,6 @@ export declare class DepacketizeCallback extends DepacketizeBase {
6
6
  waitForKeyframe?: boolean;
7
7
  isFinalPacketInSequence?: (header: RtpHeader) => boolean;
8
8
  });
9
- pipe: (instance: {
10
- input: (input: DepacketizerOutput) => void;
11
- }) => this;
9
+ pipe: (cb: (input: DepacketizerOutput) => void) => this;
12
10
  input: (input: DepacketizerInput) => void;
13
11
  }
@@ -5,8 +5,8 @@ const depacketizer_1 = require("./depacketizer");
5
5
  class DepacketizeCallback extends depacketizer_1.DepacketizeBase {
6
6
  constructor(codec, options = {}) {
7
7
  super(codec, options);
8
- this.pipe = (instance) => {
9
- this.cb = instance.input;
8
+ this.pipe = (cb) => {
9
+ this.cb = cb;
10
10
  return this;
11
11
  };
12
12
  this.input = (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"depacketizerCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/depacketizerCallback.ts"],"names":[],"mappings":";;;AACA,iDAIwB;AAExB,MAAa,mBAAoB,SAAQ,8BAAe;IAGtD,YACE,KAAa,EACb,UAGI,EAAE;QAEN,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAGxB,SAAI,GAAG,CAAC,QAAwD,EAAE,EAAE;YAClE,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,UAAK,GAAG,CAAC,KAAwB,EAAE,EAAE;YACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;gBAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;aACjB;QACH,CAAC,CAAC;IAXF,CAAC;CAYF;AAvBD,kDAuBC","sourcesContent":["import { RtpHeader } from \"..\";\nimport {\n DepacketizeBase,\n DepacketizerInput,\n DepacketizerOutput,\n} from \"./depacketizer\";\n\nexport class DepacketizeCallback extends DepacketizeBase {\n private cb!: (input: DepacketizerOutput) => void;\n\n constructor(\n codec: string,\n options: {\n waitForKeyframe?: boolean;\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n } = {}\n ) {\n super(codec, options);\n }\n\n pipe = (instance: { input: (input: DepacketizerOutput) => void }) => {\n this.cb = instance.input;\n return this;\n };\n\n input = (input: DepacketizerInput) => {\n for (const output of this.processInput(input)) {\n this.cb(output);\n }\n };\n}\n"]}
1
+ {"version":3,"file":"depacketizerCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/depacketizerCallback.ts"],"names":[],"mappings":";;;AACA,iDAIwB;AAExB,MAAa,mBAAoB,SAAQ,8BAAe;IAGtD,YACE,KAAa,EACb,UAGI,EAAE;QAEN,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAGxB,SAAI,GAAG,CAAC,EAAuC,EAAE,EAAE;YACjD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,UAAK,GAAG,CAAC,KAAwB,EAAE,EAAE;YACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;gBAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;aACjB;QACH,CAAC,CAAC;IAXF,CAAC;CAYF;AAvBD,kDAuBC","sourcesContent":["import { RtpHeader } from \"..\";\nimport {\n DepacketizeBase,\n DepacketizerInput,\n DepacketizerOutput,\n} from \"./depacketizer\";\n\nexport class DepacketizeCallback extends DepacketizeBase {\n private cb!: (input: DepacketizerOutput) => void;\n\n constructor(\n codec: string,\n options: {\n waitForKeyframe?: boolean;\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n } = {}\n ) {\n super(codec, options);\n }\n\n pipe = (cb: (input: DepacketizerOutput) => void) => {\n this.cb = cb;\n return this;\n };\n\n input = (input: DepacketizerInput) => {\n for (const output of this.processInput(input)) {\n this.cb(output);\n }\n };\n}\n"]}
@@ -5,4 +5,4 @@ import { DepacketizerOutput } from "./depacketizer";
5
5
  export declare const depacketizeTransformer: (codec: string, options?: {
6
6
  waitForKeyframe?: boolean | undefined;
7
7
  isFinalPacketInSequence?: ((header: RtpHeader) => boolean) | undefined;
8
- } | undefined) => TransformStream<import("./source/rtp").RtpOutput, DepacketizerOutput>;
8
+ } | undefined) => TransformStream<import("..").RtpOutput, DepacketizerOutput>;
@@ -1,3 +1,5 @@
1
+ export * from "./avBuffer";
2
+ export * from "./avBufferCallback";
1
3
  export * from "./depacketizer";
2
4
  export * from "./depacketizerCallback";
3
5
  export * from "./depacketizerTransformer";
@@ -6,4 +8,5 @@ export * from "./jitterBufferCallback";
6
8
  export * from "./jitterBufferTransformer";
7
9
  export * from "./source";
8
10
  export * from "./webm";
11
+ export * from "./webmCallback";
9
12
  export * from "./webmStream";
@@ -14,6 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./avBuffer"), exports);
18
+ __exportStar(require("./avBufferCallback"), exports);
17
19
  __exportStar(require("./depacketizer"), exports);
18
20
  __exportStar(require("./depacketizerCallback"), exports);
19
21
  __exportStar(require("./depacketizerTransformer"), exports);
@@ -22,5 +24,6 @@ __exportStar(require("./jitterBufferCallback"), exports);
22
24
  __exportStar(require("./jitterBufferTransformer"), exports);
23
25
  __exportStar(require("./source"), exports);
24
26
  __exportStar(require("./webm"), exports);
27
+ __exportStar(require("./webmCallback"), exports);
25
28
  __exportStar(require("./webmStream"), exports);
26
29
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,yDAAuC;AACvC,4DAA0C;AAC1C,iDAA+B;AAC/B,yDAAuC;AACvC,4DAA0C;AAC1C,2CAAyB;AACzB,yCAAuB;AACvB,+CAA6B","sourcesContent":["export * from \"./depacketizer\";\nexport * from \"./depacketizerCallback\";\nexport * from \"./depacketizerTransformer\";\nexport * from \"./jitterBuffer\";\nexport * from \"./jitterBufferCallback\";\nexport * from \"./jitterBufferTransformer\";\nexport * from \"./source\";\nexport * from \"./webm\";\nexport * from \"./webmStream\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,qDAAmC;AACnC,iDAA+B;AAC/B,yDAAuC;AACvC,4DAA0C;AAC1C,iDAA+B;AAC/B,yDAAuC;AACvC,4DAA0C;AAC1C,2CAAyB;AACzB,yCAAuB;AACvB,iDAA+B;AAC/B,+CAA6B","sourcesContent":["export * from \"./avBuffer\";\nexport * from \"./avBufferCallback\";\nexport * from \"./depacketizer\";\nexport * from \"./depacketizerCallback\";\nexport * from \"./depacketizerTransformer\";\nexport * from \"./jitterBuffer\";\nexport * from \"./jitterBufferCallback\";\nexport * from \"./jitterBufferTransformer\";\nexport * from \"./source\";\nexport * from \"./webm\";\nexport * from \"./webmCallback\";\nexport * from \"./webmStream\";\n"]}
@@ -1,5 +1,5 @@
1
1
  import { Processor } from "./interface";
2
- import { RtpOutput } from "./source/rtp";
2
+ import { RtpOutput } from "./source";
3
3
  export declare type JitterBufferInput = RtpOutput;
4
4
  export interface JitterBufferOutput extends RtpOutput {
5
5
  isPacketLost?: {
@@ -1 +1 @@
1
- {"version":3,"file":"jitterBuffer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/jitterBuffer.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport {\n RequireAtLeastOne,\n RtpPacket,\n uint16Add,\n uint32Add,\n uint32Gt,\n} from \"..\";\nimport { Processor } from \"./interface\";\nimport { RtpOutput } from \"./source/rtp\";\n\nconst srcPath = `werift-rtp : packages/rtp/src/processor_v2/jitterBuffer.ts`;\nconst log = debug(srcPath);\n\nexport type JitterBufferInput = RtpOutput;\n\nexport interface JitterBufferOutput extends RtpOutput {\n isPacketLost?: { from: number; to: number };\n}\n\nexport class JitterBufferBase\n implements Processor<JitterBufferInput, JitterBufferOutput>\n{\n private options: JitterBufferOptions;\n private presentSeqNum?: number;\n private rtpBuffer: { [sequenceNumber: number]: RtpPacket } = {};\n private get expectNextSeqNum() {\n return uint16Add(this.presentSeqNum!, 1);\n }\n\n constructor(\n public clockRate: number,\n options: Partial<JitterBufferOptions> = {}\n ) {\n this.options = {\n latency: options.latency ?? 200,\n bufferSize: options.bufferSize ?? 10000,\n };\n }\n\n processInput(input: JitterBufferInput): JitterBufferOutput[] {\n const output: JitterBufferOutput[] = [];\n\n if (!input.rtp) {\n if (input.eol) {\n const packets = this.sortAndClearBuffer(this.rtpBuffer);\n for (const rtp of packets) {\n output.push({ rtp });\n }\n output.push({ eol: true });\n }\n return output;\n }\n\n const { packets, timeoutSeqNum } = this.processRtp(input.rtp);\n\n if (timeoutSeqNum != undefined) {\n const isPacketLost = {\n from: this.expectNextSeqNum,\n to: timeoutSeqNum,\n };\n this.presentSeqNum = input.rtp.header.sequenceNumber;\n output.push({ isPacketLost });\n if (packets) {\n for (const rtp of [...packets, input.rtp]) {\n output.push({ rtp });\n }\n }\n return output;\n } else {\n if (packets) {\n for (const rtp of packets) {\n output.push({ rtp });\n }\n return output;\n }\n return [];\n }\n }\n\n private processRtp(rtp: RtpPacket): RequireAtLeastOne<{\n packets: RtpPacket[];\n timeoutSeqNum: number;\n nothing: undefined;\n }> {\n const { sequenceNumber, timestamp } = rtp.header;\n\n // init\n if (this.presentSeqNum == undefined) {\n this.presentSeqNum = sequenceNumber;\n return { packets: [rtp] };\n }\n\n // duplicate\n if (sequenceNumber <= this.presentSeqNum) {\n return { nothing: undefined };\n }\n\n // expect\n if (sequenceNumber === this.expectNextSeqNum) {\n this.presentSeqNum = sequenceNumber;\n\n const rtpBuffer = this.resolveBuffer(uint16Add(sequenceNumber, 1));\n this.presentSeqNum =\n rtpBuffer.at(-1)?.header.sequenceNumber ?? this.presentSeqNum;\n\n return { packets: [rtp, ...rtpBuffer] };\n }\n\n this.pushRtpBuffer(rtp);\n\n const { latestTimeoutSeqNum, sorted } =\n this.disposeTimeoutPackets(timestamp);\n\n if (latestTimeoutSeqNum) {\n return { timeoutSeqNum: latestTimeoutSeqNum, packets: sorted };\n } else {\n return { nothing: undefined };\n }\n }\n\n private pushRtpBuffer(rtp: RtpPacket) {\n if (Object.values(this.rtpBuffer).length > this.options.bufferSize) {\n return;\n }\n this.rtpBuffer[rtp.header.sequenceNumber] = rtp;\n }\n\n private resolveBuffer(seqNumFrom: number) {\n const resolve: RtpPacket[] = [];\n\n for (let index = seqNumFrom; ; index = uint16Add(index, 1)) {\n const rtp = this.rtpBuffer[index];\n if (rtp) {\n resolve.push(rtp);\n delete this.rtpBuffer[index];\n } else {\n break;\n }\n }\n return resolve;\n }\n\n private sortAndClearBuffer(rtpBuffer: {\n [sequenceNumber: number]: RtpPacket;\n }) {\n const buffer: RtpPacket[] = [];\n for (let index = this.presentSeqNum ?? 0; ; index = uint16Add(index, 1)) {\n const rtp = rtpBuffer[index];\n if (rtp) {\n buffer.push(rtp);\n delete rtpBuffer[index];\n }\n if (Object.values(rtpBuffer).length === 0) {\n break;\n }\n }\n return buffer;\n }\n\n private disposeTimeoutPackets(baseTimestamp: number) {\n let latestTimeoutSeqNum: number | undefined;\n\n const packets = Object.values(this.rtpBuffer)\n .map((rtp) => {\n const { timestamp, sequenceNumber } = rtp.header;\n\n if (uint32Gt(timestamp, baseTimestamp)) {\n log(\"gap\", { timestamp, baseTimestamp });\n return;\n }\n\n const elapsedSec =\n uint32Add(baseTimestamp, -timestamp) / this.clockRate;\n\n if (elapsedSec * 1000 > this.options.latency) {\n log(\"timeout packet\", {\n sequenceNumber,\n elapsedSec,\n baseTimestamp,\n timestamp,\n });\n\n if (latestTimeoutSeqNum == undefined) {\n latestTimeoutSeqNum = sequenceNumber;\n }\n // 現在のSeqNumとの差が最も大きいSeqNumを探す\n if (\n uint16Add(sequenceNumber, -this.presentSeqNum!) >\n uint16Add(latestTimeoutSeqNum, -this.presentSeqNum!)\n ) {\n latestTimeoutSeqNum = sequenceNumber;\n }\n\n const packet = this.rtpBuffer[sequenceNumber];\n delete this.rtpBuffer[sequenceNumber];\n return packet;\n }\n })\n .flatMap((p): RtpPacket => p as RtpPacket)\n .filter((p) => p);\n\n const sorted = this.sortAndClearBuffer(\n packets.reduce((acc, cur) => {\n acc[cur.header.sequenceNumber] = cur;\n return acc;\n }, {})\n );\n\n return { latestTimeoutSeqNum, sorted };\n }\n}\n\nexport interface JitterBufferOptions {\n /**milliseconds */\n latency: number;\n bufferSize: number;\n}\n"]}
1
+ {"version":3,"file":"jitterBuffer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/jitterBuffer.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,0BAMY;AAIZ,MAAM,OAAO,GAAG,4DAA4D,CAAC;AAC7E,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,OAAO,CAAC,CAAC;AAQ3B,MAAa,gBAAgB;IAU3B,YACS,SAAiB,EACxB,UAAwC,EAAE;QADnC,cAAS,GAAT,SAAS,CAAQ;QANlB,cAAS,GAA4C,EAAE,CAAC;QAS9D,IAAI,CAAC,OAAO,GAAG;YACb,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,GAAG;YAC/B,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;SACxC,CAAC;IACJ,CAAC;IAZD,IAAY,gBAAgB;QAC1B,OAAO,IAAA,aAAS,EAAC,IAAI,CAAC,aAAc,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;IAYD,YAAY,CAAC,KAAwB;QACnC,MAAM,MAAM,GAAyB,EAAE,CAAC;QAExC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACd,IAAI,KAAK,CAAC,GAAG,EAAE;gBACb,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;oBACzB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;iBACtB;gBACD,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;aAC5B;YACD,OAAO,MAAM,CAAC;SACf;QAED,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE9D,IAAI,aAAa,IAAI,SAAS,EAAE;YAC9B,MAAM,YAAY,GAAG;gBACnB,IAAI,EAAE,IAAI,CAAC,gBAAgB;gBAC3B,EAAE,EAAE,aAAa;aAClB,CAAC;YACF,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YAC9B,IAAI,OAAO,EAAE;gBACX,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;oBACzC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;iBACtB;aACF;YACD,OAAO,MAAM,CAAC;SACf;aAAM;YACL,IAAI,OAAO,EAAE;gBACX,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;oBACzB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;iBACtB;gBACD,OAAO,MAAM,CAAC;aACf;YACD,OAAO,EAAE,CAAC;SACX;IACH,CAAC;IAEO,UAAU,CAAC,GAAc;QAK/B,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;QAEjD,OAAO;QACP,IAAI,IAAI,CAAC,aAAa,IAAI,SAAS,EAAE;YACnC,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC;YACpC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;SAC3B;QAED,YAAY;QACZ,IAAI,cAAc,IAAI,IAAI,CAAC,aAAa,EAAE;YACxC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;SAC/B;QAED,SAAS;QACT,IAAI,cAAc,KAAK,IAAI,CAAC,gBAAgB,EAAE;YAC5C,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC;YAEpC,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,IAAA,aAAS,EAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,aAAa;gBAChB,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,cAAc,IAAI,IAAI,CAAC,aAAa,CAAC;YAEhE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;SACzC;QAED,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAExB,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,GACnC,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAExC,IAAI,mBAAmB,EAAE;YACvB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;SAChE;aAAM;YACL,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;SAC/B;IACH,CAAC;IAEO,aAAa,CAAC,GAAc;QAClC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YAClE,OAAO;SACR;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC;IAClD,CAAC;IAEO,aAAa,CAAC,UAAkB;QACtC,MAAM,OAAO,GAAgB,EAAE,CAAC;QAEhC,KAAK,IAAI,KAAK,GAAG,UAAU,GAAI,KAAK,GAAG,IAAA,aAAS,EAAC,KAAK,EAAE,CAAC,CAAC,EAAE;YAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,GAAG,EAAE;gBACP,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;aAC9B;iBAAM;gBACL,MAAM;aACP;SACF;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,kBAAkB,CAAC,SAE1B;QACC,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,GAAI,KAAK,GAAG,IAAA,aAAS,EAAC,KAAK,EAAE,CAAC,CAAC,EAAE;YACvE,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,GAAG,EAAE;gBACP,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjB,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;aACzB;YACD,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;gBACzC,MAAM;aACP;SACF;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,qBAAqB,CAAC,aAAqB;QACjD,IAAI,mBAAuC,CAAC;QAE5C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;aAC1C,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACX,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;YAEjD,IAAI,IAAA,YAAQ,EAAC,SAAS,EAAE,aAAa,CAAC,EAAE;gBACtC,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;gBACzC,OAAO;aACR;YAED,MAAM,UAAU,GACd,IAAA,aAAS,EAAC,aAAa,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;YAExD,IAAI,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;gBAC5C,GAAG,CAAC,gBAAgB,EAAE;oBACpB,cAAc;oBACd,UAAU;oBACV,aAAa;oBACb,SAAS;iBACV,CAAC,CAAC;gBAEH,IAAI,mBAAmB,IAAI,SAAS,EAAE;oBACpC,mBAAmB,GAAG,cAAc,CAAC;iBACtC;gBACD,8BAA8B;gBAC9B,IACE,IAAA,aAAS,EAAC,cAAc,EAAE,CAAC,IAAI,CAAC,aAAc,CAAC;oBAC/C,IAAA,aAAS,EAAC,mBAAmB,EAAE,CAAC,IAAI,CAAC,aAAc,CAAC,EACpD;oBACA,mBAAmB,GAAG,cAAc,CAAC;iBACtC;gBAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;gBAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;gBACtC,OAAO,MAAM,CAAC;aACf;QACH,CAAC,CAAC;aACD,OAAO,CAAC,CAAC,CAAC,EAAa,EAAE,CAAC,CAAc,CAAC;aACzC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CACpC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC1B,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC;YACrC,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAAE,CAAC,CACP,CAAC;QAEF,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC;IACzC,CAAC;CACF;AA/LD,4CA+LC","sourcesContent":["import debug from \"debug\";\n\nimport {\n RequireAtLeastOne,\n RtpPacket,\n uint16Add,\n uint32Add,\n uint32Gt,\n} from \"..\";\nimport { Processor } from \"./interface\";\nimport { RtpOutput } from \"./source\";\n\nconst srcPath = `werift-rtp : packages/rtp/src/processor_v2/jitterBuffer.ts`;\nconst log = debug(srcPath);\n\nexport type JitterBufferInput = RtpOutput;\n\nexport interface JitterBufferOutput extends RtpOutput {\n isPacketLost?: { from: number; to: number };\n}\n\nexport class JitterBufferBase\n implements Processor<JitterBufferInput, JitterBufferOutput>\n{\n private options: JitterBufferOptions;\n private presentSeqNum?: number;\n private rtpBuffer: { [sequenceNumber: number]: RtpPacket } = {};\n private get expectNextSeqNum() {\n return uint16Add(this.presentSeqNum!, 1);\n }\n\n constructor(\n public clockRate: number,\n options: Partial<JitterBufferOptions> = {}\n ) {\n this.options = {\n latency: options.latency ?? 200,\n bufferSize: options.bufferSize ?? 10000,\n };\n }\n\n processInput(input: JitterBufferInput): JitterBufferOutput[] {\n const output: JitterBufferOutput[] = [];\n\n if (!input.rtp) {\n if (input.eol) {\n const packets = this.sortAndClearBuffer(this.rtpBuffer);\n for (const rtp of packets) {\n output.push({ rtp });\n }\n output.push({ eol: true });\n }\n return output;\n }\n\n const { packets, timeoutSeqNum } = this.processRtp(input.rtp);\n\n if (timeoutSeqNum != undefined) {\n const isPacketLost = {\n from: this.expectNextSeqNum,\n to: timeoutSeqNum,\n };\n this.presentSeqNum = input.rtp.header.sequenceNumber;\n output.push({ isPacketLost });\n if (packets) {\n for (const rtp of [...packets, input.rtp]) {\n output.push({ rtp });\n }\n }\n return output;\n } else {\n if (packets) {\n for (const rtp of packets) {\n output.push({ rtp });\n }\n return output;\n }\n return [];\n }\n }\n\n private processRtp(rtp: RtpPacket): RequireAtLeastOne<{\n packets: RtpPacket[];\n timeoutSeqNum: number;\n nothing: undefined;\n }> {\n const { sequenceNumber, timestamp } = rtp.header;\n\n // init\n if (this.presentSeqNum == undefined) {\n this.presentSeqNum = sequenceNumber;\n return { packets: [rtp] };\n }\n\n // duplicate\n if (sequenceNumber <= this.presentSeqNum) {\n return { nothing: undefined };\n }\n\n // expect\n if (sequenceNumber === this.expectNextSeqNum) {\n this.presentSeqNum = sequenceNumber;\n\n const rtpBuffer = this.resolveBuffer(uint16Add(sequenceNumber, 1));\n this.presentSeqNum =\n rtpBuffer.at(-1)?.header.sequenceNumber ?? this.presentSeqNum;\n\n return { packets: [rtp, ...rtpBuffer] };\n }\n\n this.pushRtpBuffer(rtp);\n\n const { latestTimeoutSeqNum, sorted } =\n this.disposeTimeoutPackets(timestamp);\n\n if (latestTimeoutSeqNum) {\n return { timeoutSeqNum: latestTimeoutSeqNum, packets: sorted };\n } else {\n return { nothing: undefined };\n }\n }\n\n private pushRtpBuffer(rtp: RtpPacket) {\n if (Object.values(this.rtpBuffer).length > this.options.bufferSize) {\n return;\n }\n this.rtpBuffer[rtp.header.sequenceNumber] = rtp;\n }\n\n private resolveBuffer(seqNumFrom: number) {\n const resolve: RtpPacket[] = [];\n\n for (let index = seqNumFrom; ; index = uint16Add(index, 1)) {\n const rtp = this.rtpBuffer[index];\n if (rtp) {\n resolve.push(rtp);\n delete this.rtpBuffer[index];\n } else {\n break;\n }\n }\n return resolve;\n }\n\n private sortAndClearBuffer(rtpBuffer: {\n [sequenceNumber: number]: RtpPacket;\n }) {\n const buffer: RtpPacket[] = [];\n for (let index = this.presentSeqNum ?? 0; ; index = uint16Add(index, 1)) {\n const rtp = rtpBuffer[index];\n if (rtp) {\n buffer.push(rtp);\n delete rtpBuffer[index];\n }\n if (Object.values(rtpBuffer).length === 0) {\n break;\n }\n }\n return buffer;\n }\n\n private disposeTimeoutPackets(baseTimestamp: number) {\n let latestTimeoutSeqNum: number | undefined;\n\n const packets = Object.values(this.rtpBuffer)\n .map((rtp) => {\n const { timestamp, sequenceNumber } = rtp.header;\n\n if (uint32Gt(timestamp, baseTimestamp)) {\n log(\"gap\", { timestamp, baseTimestamp });\n return;\n }\n\n const elapsedSec =\n uint32Add(baseTimestamp, -timestamp) / this.clockRate;\n\n if (elapsedSec * 1000 > this.options.latency) {\n log(\"timeout packet\", {\n sequenceNumber,\n elapsedSec,\n baseTimestamp,\n timestamp,\n });\n\n if (latestTimeoutSeqNum == undefined) {\n latestTimeoutSeqNum = sequenceNumber;\n }\n // 現在のSeqNumとの差が最も大きいSeqNumを探す\n if (\n uint16Add(sequenceNumber, -this.presentSeqNum!) >\n uint16Add(latestTimeoutSeqNum, -this.presentSeqNum!)\n ) {\n latestTimeoutSeqNum = sequenceNumber;\n }\n\n const packet = this.rtpBuffer[sequenceNumber];\n delete this.rtpBuffer[sequenceNumber];\n return packet;\n }\n })\n .flatMap((p): RtpPacket => p as RtpPacket)\n .filter((p) => p);\n\n const sorted = this.sortAndClearBuffer(\n packets.reduce((acc, cur) => {\n acc[cur.header.sequenceNumber] = cur;\n return acc;\n }, {})\n );\n\n return { latestTimeoutSeqNum, sorted };\n }\n}\n\nexport interface JitterBufferOptions {\n /**milliseconds */\n latency: number;\n bufferSize: number;\n}\n"]}
@@ -3,8 +3,6 @@ export declare class JitterBufferCallback extends JitterBufferBase {
3
3
  clockRate: number;
4
4
  private cb;
5
5
  constructor(clockRate: number, options?: Partial<JitterBufferOptions>);
6
- pipe: (instance: {
7
- input: (input: JitterBufferOutput) => void;
8
- }) => this;
6
+ pipe: (cb: (input: JitterBufferOutput) => void) => this;
9
7
  input: (input: JitterBufferInput) => void;
10
8
  }