werift 0.18.1 → 0.18.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 (74) hide show
  1. package/lib/ice/src/ice.js +58 -37
  2. package/lib/ice/src/ice.js.map +1 -1
  3. package/lib/ice/src/index.d.ts +3 -3
  4. package/lib/ice/src/index.js +3 -5
  5. package/lib/ice/src/index.js.map +1 -1
  6. package/lib/ice/src/utils.d.ts +1 -1
  7. package/lib/ice/src/utils.js +3 -0
  8. package/lib/ice/src/utils.js.map +1 -1
  9. package/lib/rtp/src/index.d.ts +1 -0
  10. package/lib/rtp/src/index.js +1 -0
  11. package/lib/rtp/src/index.js.map +1 -1
  12. package/lib/rtp/src/processor/depacketizer.d.ts +8 -3
  13. package/lib/rtp/src/processor/depacketizer.js +18 -1
  14. package/lib/rtp/src/processor/depacketizer.js.map +1 -1
  15. package/lib/rtp/src/processor/depacketizerCallback.d.ts +2 -6
  16. package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -1
  17. package/lib/rtp/src/processor/depacketizerTransformer.d.ts +2 -6
  18. package/lib/rtp/src/processor/depacketizerTransformer.js.map +1 -1
  19. package/lib/rtp/src/processor/index.d.ts +4 -0
  20. package/lib/rtp/src/processor/index.js +4 -0
  21. package/lib/rtp/src/processor/index.js.map +1 -1
  22. package/lib/rtp/src/processor/nack.d.ts +29 -0
  23. package/lib/rtp/src/processor/nack.js +183 -0
  24. package/lib/rtp/src/processor/nack.js.map +1 -0
  25. package/lib/rtp/src/processor/nackHandlerCallback.d.ts +8 -0
  26. package/lib/rtp/src/processor/nackHandlerCallback.js +36 -0
  27. package/lib/rtp/src/processor/nackHandlerCallback.js.map +1 -0
  28. package/lib/rtp/src/processor/ntpTime.js +2 -1
  29. package/lib/rtp/src/processor/ntpTime.js.map +1 -1
  30. package/lib/rtp/src/processor/rtpTime.d.ts +22 -0
  31. package/lib/rtp/src/processor/rtpTime.js +51 -0
  32. package/lib/rtp/src/processor/rtpTime.js.map +1 -0
  33. package/lib/rtp/src/processor/rtpTimeCallback.d.ts +7 -0
  34. package/lib/rtp/src/processor/rtpTimeCallback.js +36 -0
  35. package/lib/rtp/src/processor/rtpTimeCallback.js.map +1 -0
  36. package/lib/rtp/src/processor/source/rtcpCallback.d.ts +2 -1
  37. package/lib/rtp/src/processor/source/rtcpCallback.js +11 -0
  38. package/lib/rtp/src/processor/source/rtcpCallback.js.map +1 -1
  39. package/lib/rtp/src/processor/source/rtpCallback.d.ts +2 -0
  40. package/lib/rtp/src/processor/source/rtpCallback.js +11 -0
  41. package/lib/rtp/src/processor/source/rtpCallback.js.map +1 -1
  42. package/lib/rtp/src/processor/webm.d.ts +8 -3
  43. package/lib/rtp/src/processor/webm.js +67 -10
  44. package/lib/rtp/src/processor/webm.js.map +1 -1
  45. package/lib/rtp/src/processor/webmCallback.js +2 -0
  46. package/lib/rtp/src/processor/webmCallback.js.map +1 -1
  47. package/lib/rtp/src/rtcp/rtcp.d.ts +1 -0
  48. package/lib/rtp/src/rtcp/rtcp.js +5 -1
  49. package/lib/rtp/src/rtcp/rtcp.js.map +1 -1
  50. package/lib/rtp/src/rtp/rtp.d.ts +2 -2
  51. package/lib/rtp/src/rtp/rtp.js +2 -2
  52. package/lib/rtp/src/rtp/rtp.js.map +1 -1
  53. package/lib/rtp/src/rtp/rtx.d.ts +3 -0
  54. package/lib/rtp/src/rtp/rtx.js +33 -0
  55. package/lib/rtp/src/rtp/rtx.js.map +1 -0
  56. package/lib/webrtc/src/media/receiver/nack.js +0 -1
  57. package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
  58. package/lib/webrtc/src/media/rtpReceiver.d.ts +0 -1
  59. package/lib/webrtc/src/media/rtpReceiver.js +2 -14
  60. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  61. package/lib/webrtc/src/media/rtpSender.d.ts +0 -1
  62. package/lib/webrtc/src/media/rtpSender.js +2 -18
  63. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  64. package/lib/webrtc/src/transport/dtls.js +1 -1
  65. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  66. package/lib/webrtc/src/utils.d.ts +0 -1
  67. package/lib/webrtc/src/utils.js +1 -5
  68. package/lib/webrtc/src/utils.js.map +1 -1
  69. package/package.json +1 -1
  70. package/src/media/receiver/nack.ts +1 -1
  71. package/src/media/rtpReceiver.ts +1 -16
  72. package/src/media/rtpSender.ts +1 -24
  73. package/src/transport/dtls.ts +2 -1
  74. package/src/utils.ts +0 -4
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DepacketizeBase = void 0;
7
7
  const debug_1 = __importDefault(require("debug"));
8
+ const rx_mini_1 = __importDefault(require("rx.mini"));
8
9
  const __1 = require("..");
9
10
  const codec_1 = require("../codec");
10
11
  const helper_1 = require("../helper");
@@ -42,12 +43,24 @@ class DepacketizeBase {
42
43
  writable: true,
43
44
  value: false
44
45
  });
46
+ Object.defineProperty(this, "keyframeReceived", {
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true,
50
+ value: false
51
+ });
45
52
  Object.defineProperty(this, "sequence", {
46
53
  enumerable: true,
47
54
  configurable: true,
48
55
  writable: true,
49
56
  value: 0
50
57
  });
58
+ Object.defineProperty(this, "onNeedKeyFrame", {
59
+ enumerable: true,
60
+ configurable: true,
61
+ writable: true,
62
+ value: new rx_mini_1.default()
63
+ });
51
64
  }
52
65
  processInput(input) {
53
66
  const output = [];
@@ -63,7 +76,11 @@ class DepacketizeBase {
63
76
  try {
64
77
  const { data, isKeyframe, sequence, timestamp } = (0, codec_1.dePacketizeRtpPackets)(this.codec, this.buffering.map((b) => b.rtp));
65
78
  if (isKeyframe) {
66
- log("isKeyframe", this.codec);
79
+ this.keyframeReceived = true;
80
+ }
81
+ if (this.options.waitForKeyframe && this.keyframeReceived === false) {
82
+ this.onNeedKeyFrame.execute();
83
+ return [];
67
84
  }
68
85
  if (!this.frameBroken) {
69
86
  const time = this.buffering.at(-1)?.time ?? 0;
@@ -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, uint16Gt } from \"..\";\nimport { dePacketizeRtpPackets } from \"../codec\";\nimport { enumerate } from \"../helper\";\nimport { Processor } from \"./interface\";\n\nconst path = `werift-rtp : packages/rtp/src/processor/depacketizer.ts`;\nconst log = debug(path);\n\nexport type DepacketizerInput = {\n rtp?: RtpPacket;\n /**ms */\n time?: number;\n eol?: boolean;\n};\n\nexport interface DepacketizerOutput {\n frame?: CodecFrame;\n eol?: boolean;\n}\n\nexport interface CodecFrame {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n [key: string]: any;\n}\n\nexport class DepacketizeBase\n implements Processor<DepacketizerInput, DepacketizerOutput>\n{\n private buffering: DepacketizerInput[] = [];\n private lastSeqNum?: number;\n private frameBroken = false;\n sequence = 0;\n\n constructor(\n private codec: string,\n private options: {\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);\n if (isFinal) {\n try {\n const { data, isKeyframe, sequence, timestamp } =\n dePacketizeRtpPackets(\n this.codec,\n this.buffering.map((b) => b.rtp!)\n );\n\n if (isKeyframe) {\n log(\"isKeyframe\", this.codec);\n }\n\n if (!this.frameBroken) {\n const time = this.buffering.at(-1)?.time ?? 0;\n output.push({\n frame: {\n data,\n isKeyframe,\n time,\n sequence: this.sequence++,\n rtpSeq: sequence,\n timestamp,\n },\n });\n }\n\n if (this.frameBroken) {\n this.frameBroken = false;\n }\n\n this.clearBuffer();\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, sequence, timestamp } = dePacketizeRtpPackets(\n this.codec,\n [input.rtp]\n );\n output.push({\n frame: {\n data,\n isKeyframe,\n time: input.time!,\n sequence: this.sequence++,\n rtpSeq: sequence,\n 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.rtp!.clear());\n this.buffering = [];\n }\n\n private checkFinalPacket({ rtp, time }: DepacketizerInput): 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 (uint16Gt(expect, sequenceNumber)) {\n log(\"unexpect\", { expect, sequenceNumber });\n return false;\n }\n if (uint16Gt(sequenceNumber, expect)) {\n log(\"packet lost happened\", { expect, sequenceNumber });\n this.frameBroken = true;\n this.clearBuffer();\n }\n }\n\n this.buffering.push({ rtp, time });\n this.lastSeqNum = sequenceNumber;\n\n let finalPacket: number | undefined;\n for (const [i, { rtp }] of enumerate(this.buffering)) {\n if (this.options.isFinalPacketInSequence(rtp!.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\";\nimport Event from \"rx.mini\";\n\nimport { RtpHeader, RtpPacket, uint16Add, uint16Gt } from \"..\";\nimport { dePacketizeRtpPackets } from \"../codec\";\nimport { enumerate } from \"../helper\";\nimport { Processor } from \"./interface\";\n\nconst path = `werift-rtp : packages/rtp/src/processor/depacketizer.ts`;\nconst log = debug(path);\n\nexport type DepacketizerInput = {\n rtp?: RtpPacket;\n /**ms */\n time?: number;\n eol?: boolean;\n};\n\nexport interface DepacketizerOutput {\n frame?: CodecFrame;\n eol?: boolean;\n}\n\nexport interface CodecFrame {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n [key: string]: any;\n}\n\nexport interface DepacketizerOptions {\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n waitForKeyframe?: boolean;\n}\n\nexport class DepacketizeBase\n implements Processor<DepacketizerInput, DepacketizerOutput>\n{\n private buffering: DepacketizerInput[] = [];\n private lastSeqNum?: number;\n private frameBroken = false;\n private keyframeReceived = false;\n sequence = 0;\n readonly onNeedKeyFrame = new Event();\n\n constructor(\n private codec: string,\n private options: DepacketizerOptions = {}\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);\n if (isFinal) {\n try {\n const { data, isKeyframe, sequence, timestamp } =\n dePacketizeRtpPackets(\n this.codec,\n this.buffering.map((b) => b.rtp!)\n );\n\n if (isKeyframe) {\n this.keyframeReceived = true;\n }\n\n if (this.options.waitForKeyframe && this.keyframeReceived === false) {\n this.onNeedKeyFrame.execute();\n return [];\n }\n\n if (!this.frameBroken) {\n const time = this.buffering.at(-1)?.time ?? 0;\n output.push({\n frame: {\n data,\n isKeyframe,\n time,\n sequence: this.sequence++,\n rtpSeq: sequence,\n timestamp,\n },\n });\n }\n\n if (this.frameBroken) {\n this.frameBroken = false;\n }\n\n this.clearBuffer();\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, sequence, timestamp } = dePacketizeRtpPackets(\n this.codec,\n [input.rtp]\n );\n output.push({\n frame: {\n data,\n isKeyframe,\n time: input.time!,\n sequence: this.sequence++,\n rtpSeq: sequence,\n 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.rtp!.clear());\n this.buffering = [];\n }\n\n private checkFinalPacket({ rtp, time }: DepacketizerInput): 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 (uint16Gt(expect, sequenceNumber)) {\n log(\"unexpect\", { expect, sequenceNumber });\n return false;\n }\n if (uint16Gt(sequenceNumber, expect)) {\n log(\"packet lost happened\", { expect, sequenceNumber });\n this.frameBroken = true;\n this.clearBuffer();\n }\n }\n\n this.buffering.push({ rtp, time });\n this.lastSeqNum = sequenceNumber;\n\n let finalPacket: number | undefined;\n for (const [i, { rtp }] of enumerate(this.buffering)) {\n if (this.options.isFinalPacketInSequence(rtp!.header)) {\n finalPacket = i;\n break;\n }\n }\n if (finalPacket == undefined) {\n return false;\n }\n\n return true;\n }\n}\n"]}
@@ -1,11 +1,7 @@
1
- import { RtpHeader } from "..";
2
- import { DepacketizeBase, DepacketizerInput, DepacketizerOutput } from "./depacketizer";
1
+ import { DepacketizeBase, DepacketizerInput, DepacketizerOptions, DepacketizerOutput } from "./depacketizer";
3
2
  export declare class DepacketizeCallback extends DepacketizeBase {
4
3
  private cb;
5
- constructor(codec: string, options?: {
6
- waitForKeyframe?: boolean;
7
- isFinalPacketInSequence?: (header: RtpHeader) => boolean;
8
- });
4
+ constructor(codec: string, options?: DepacketizerOptions);
9
5
  pipe: (cb: (input: DepacketizerOutput) => void) => this;
10
6
  input: (input: DepacketizerInput) => void;
11
7
  }
@@ -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;QATxB;;;;;WAAiD;QAYjD;;;;mBAAO,CAAC,EAAuC,EAAE,EAAE;gBACjD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;WAAC;QAEF;;;;mBAAQ,CAAC,KAAwB,EAAE,EAAE;gBACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;oBAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;iBACjB;YACH,CAAC;WAAC;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"]}
1
+ {"version":3,"file":"depacketizerCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/depacketizerCallback.ts"],"names":[],"mappings":";;;AAAA,iDAKwB;AAExB,MAAa,mBAAoB,SAAQ,8BAAe;IAGtD,YAAY,KAAa,EAAE,UAA+B,EAAE;QAC1D,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAHxB;;;;;WAAiD;QAMjD;;;;mBAAO,CAAC,EAAuC,EAAE,EAAE;gBACjD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;WAAC;QAEF;;;;mBAAQ,CAAC,KAAwB,EAAE,EAAE;gBACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;oBAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;iBACjB;YACH,CAAC;WAAC;IAXF,CAAC;CAYF;AAjBD,kDAiBC","sourcesContent":["import {\n DepacketizeBase,\n DepacketizerInput,\n DepacketizerOptions,\n DepacketizerOutput,\n} from \"./depacketizer\";\n\nexport class DepacketizeCallback extends DepacketizeBase {\n private cb!: (input: DepacketizerOutput) => void;\n\n constructor(codec: string, options: DepacketizerOptions = {}) {\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"]}
@@ -1,8 +1,4 @@
1
1
  /// <reference types="node" />
2
2
  import { TransformStream } from "stream/web";
3
- import { RtpHeader } from "..";
4
- import { DepacketizerInput, DepacketizerOutput } from "./depacketizer";
5
- export declare const depacketizeTransformer: (codec: string, options?: {
6
- waitForKeyframe?: boolean | undefined;
7
- isFinalPacketInSequence?: ((header: RtpHeader) => boolean) | undefined;
8
- } | undefined) => TransformStream<DepacketizerInput, DepacketizerOutput>;
3
+ import { DepacketizerInput, DepacketizerOptions, DepacketizerOutput } from "./depacketizer";
4
+ export declare const depacketizeTransformer: (codec: string, options?: DepacketizerOptions | undefined) => TransformStream<DepacketizerInput, DepacketizerOutput>;
@@ -1 +1 @@
1
- {"version":3,"file":"depacketizerTransformer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/depacketizerTransformer.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAG7C,iDAIwB;AAEjB,MAAM,sBAAsB,GAAG,CACpC,GAAG,IAA0D,EAC7D,EAAE,CAAC,IAAI,sBAAsB,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC;AAFtC,QAAA,sBAAsB,0BAEgB;AAEnD,MAAM,sBAAuB,SAAQ,8BAAe;IAGlD,YACE,KAAa,EACb,UAGI,EAAE;QAEN,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QATxB;;;;;WAAkE;QAWhE,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAe,CAAC;YACnC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;oBAC1C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;iBACrB;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { TransformStream } from \"stream/web\";\n\nimport { RtpHeader } from \"..\";\nimport {\n DepacketizeBase,\n DepacketizerInput,\n DepacketizerOutput,\n} from \"./depacketizer\";\n\nexport const depacketizeTransformer = (\n ...args: ConstructorParameters<typeof DepacketizeTransformer>\n) => new DepacketizeTransformer(...args).transform;\n\nclass DepacketizeTransformer extends DepacketizeBase {\n transform: TransformStream<DepacketizerInput, DepacketizerOutput>;\n\n constructor(\n codec: string,\n options: {\n waitForKeyframe?: boolean;\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n } = {}\n ) {\n super(codec, options);\n\n this.transform = new TransformStream({\n transform: (input, output) => {\n for (const res of this.processInput(input)) {\n output.enqueue(res);\n }\n },\n });\n }\n}\n"]}
1
+ {"version":3,"file":"depacketizerTransformer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/depacketizerTransformer.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAE7C,iDAKwB;AAEjB,MAAM,sBAAsB,GAAG,CACpC,GAAG,IAA0D,EAC7D,EAAE,CAAC,IAAI,sBAAsB,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC;AAFtC,QAAA,sBAAsB,0BAEgB;AAEnD,MAAM,sBAAuB,SAAQ,8BAAe;IAGlD,YAAY,KAAa,EAAE,UAA+B,EAAE;QAC1D,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAHxB;;;;;WAAkE;QAKhE,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAe,CAAC;YACnC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;oBAC1C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;iBACrB;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { TransformStream } from \"stream/web\";\n\nimport {\n DepacketizeBase,\n DepacketizerInput,\n DepacketizerOptions,\n DepacketizerOutput,\n} from \"./depacketizer\";\n\nexport const depacketizeTransformer = (\n ...args: ConstructorParameters<typeof DepacketizeTransformer>\n) => new DepacketizeTransformer(...args).transform;\n\nclass DepacketizeTransformer extends DepacketizeBase {\n transform: TransformStream<DepacketizerInput, DepacketizerOutput>;\n\n constructor(codec: string, options: DepacketizerOptions = {}) {\n super(codec, options);\n\n this.transform = new TransformStream({\n transform: (input, output) => {\n for (const res of this.processInput(input)) {\n output.enqueue(res);\n }\n },\n });\n }\n}\n"]}
@@ -6,8 +6,12 @@ export * from "./jitterBufferCallback";
6
6
  export * from "./jitterBufferTransformer";
7
7
  export * from "./lipsync";
8
8
  export * from "./lipsyncCallback";
9
+ export * from "./nack";
10
+ export * from "./nackHandlerCallback";
9
11
  export * from "./ntpTime";
10
12
  export * from "./ntpTimeCallback";
13
+ export * from "./rtpTime";
14
+ export * from "./rtpTimeCallback";
11
15
  export * from "./source";
12
16
  export * from "./webm";
13
17
  export * from "./webmCallback";
@@ -22,8 +22,12 @@ __exportStar(require("./jitterBufferCallback"), exports);
22
22
  __exportStar(require("./jitterBufferTransformer"), exports);
23
23
  __exportStar(require("./lipsync"), exports);
24
24
  __exportStar(require("./lipsyncCallback"), exports);
25
+ __exportStar(require("./nack"), exports);
26
+ __exportStar(require("./nackHandlerCallback"), exports);
25
27
  __exportStar(require("./ntpTime"), exports);
26
28
  __exportStar(require("./ntpTimeCallback"), exports);
29
+ __exportStar(require("./rtpTime"), exports);
30
+ __exportStar(require("./rtpTimeCallback"), exports);
27
31
  __exportStar(require("./source"), exports);
28
32
  __exportStar(require("./webm"), exports);
29
33
  __exportStar(require("./webmCallback"), exports);
@@ -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,4CAA0B;AAC1B,oDAAkC;AAClC,4CAA0B;AAC1B,oDAAkC;AAClC,2CAAyB;AACzB,yCAAuB;AACvB,iDAA+B;AAC/B,+CAA6B","sourcesContent":["export * from \"./depacketizer\";\nexport * from \"./depacketizerCallback\";\nexport * from \"./depacketizerTransformer\";\nexport * from \"./jitterBuffer\";\nexport * from \"./jitterBufferCallback\";\nexport * from \"./jitterBufferTransformer\";\nexport * from \"./lipsync\";\nexport * from \"./lipsyncCallback\";\nexport * from \"./ntpTime\";\nexport * from \"./ntpTimeCallback\";\nexport * from \"./source\";\nexport * from \"./webm\";\nexport * from \"./webmCallback\";\nexport * from \"./webmStream\";\n"]}
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,4CAA0B;AAC1B,oDAAkC;AAClC,yCAAuB;AACvB,wDAAsC;AACtC,4CAA0B;AAC1B,oDAAkC;AAClC,4CAA0B;AAC1B,oDAAkC;AAClC,2CAAyB;AACzB,yCAAuB;AACvB,iDAA+B;AAC/B,+CAA6B","sourcesContent":["export * from \"./depacketizer\";\nexport * from \"./depacketizerCallback\";\nexport * from \"./depacketizerTransformer\";\nexport * from \"./jitterBuffer\";\nexport * from \"./jitterBufferCallback\";\nexport * from \"./jitterBufferTransformer\";\nexport * from \"./lipsync\";\nexport * from \"./lipsyncCallback\";\nexport * from \"./nack\";\nexport * from \"./nackHandlerCallback\";\nexport * from \"./ntpTime\";\nexport * from \"./ntpTimeCallback\";\nexport * from \"./rtpTime\";\nexport * from \"./rtpTimeCallback\";\nexport * from \"./source\";\nexport * from \"./webm\";\nexport * from \"./webmCallback\";\nexport * from \"./webmStream\";\n"]}
@@ -0,0 +1,29 @@
1
+ import Event from "rx.mini";
2
+ import { RtcpTransportLayerFeedback } from "../rtcp/rtpfb";
3
+ import { GenericNack } from "../rtcp/rtpfb/nack";
4
+ import { Processor } from "./interface";
5
+ import { RtpOutput } from "./source";
6
+ export type NackHandlerInput = RtpOutput;
7
+ export type NackHandlerOutput = RtpOutput;
8
+ export declare class NackHandlerBase implements Processor<NackHandlerInput, NackHandlerOutput> {
9
+ private senderSsrc;
10
+ private onNack;
11
+ private newEstSeqNum;
12
+ private _lost;
13
+ private nackLoop;
14
+ readonly onPacketLost: Event<[GenericNack]>;
15
+ mediaSourceSsrc?: number;
16
+ retryCount: number;
17
+ closed: boolean;
18
+ constructor(senderSsrc: number, onNack: (rtcp: RtcpTransportLayerFeedback) => Promise<void>);
19
+ private get lostSeqNumbers();
20
+ private getLost;
21
+ private setLost;
22
+ private removeLost;
23
+ processInput: (input: RtpOutput) => RtpOutput[];
24
+ private addPacket;
25
+ private pruneLost;
26
+ private close;
27
+ private updateRetryCount;
28
+ private sendNack;
29
+ }
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NackHandlerBase = void 0;
7
+ const debug_1 = __importDefault(require("debug"));
8
+ const range_1 = __importDefault(require("lodash/range"));
9
+ const rx_mini_1 = __importDefault(require("rx.mini"));
10
+ const src_1 = require("../../../common/src");
11
+ const rtpfb_1 = require("../rtcp/rtpfb");
12
+ const nack_1 = require("../rtcp/rtpfb/nack");
13
+ const log = (0, debug_1.default)("werift-rtp : packages/rtp/src/processor/nack.ts");
14
+ const LOST_SIZE = 30 * 5;
15
+ class NackHandlerBase {
16
+ constructor(senderSsrc, onNack) {
17
+ Object.defineProperty(this, "senderSsrc", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: senderSsrc
22
+ });
23
+ Object.defineProperty(this, "onNack", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: onNack
28
+ });
29
+ Object.defineProperty(this, "newEstSeqNum", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: 0
34
+ });
35
+ Object.defineProperty(this, "_lost", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: {}
40
+ });
41
+ Object.defineProperty(this, "nackLoop", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: void 0
46
+ });
47
+ Object.defineProperty(this, "onPacketLost", {
48
+ enumerable: true,
49
+ configurable: true,
50
+ writable: true,
51
+ value: new rx_mini_1.default()
52
+ });
53
+ Object.defineProperty(this, "mediaSourceSsrc", {
54
+ enumerable: true,
55
+ configurable: true,
56
+ writable: true,
57
+ value: void 0
58
+ });
59
+ Object.defineProperty(this, "retryCount", {
60
+ enumerable: true,
61
+ configurable: true,
62
+ writable: true,
63
+ value: 10
64
+ });
65
+ Object.defineProperty(this, "closed", {
66
+ enumerable: true,
67
+ configurable: true,
68
+ writable: true,
69
+ value: false
70
+ });
71
+ Object.defineProperty(this, "processInput", {
72
+ enumerable: true,
73
+ configurable: true,
74
+ writable: true,
75
+ value: (input) => {
76
+ if (input.rtp) {
77
+ this.addPacket(input.rtp);
78
+ return [input];
79
+ }
80
+ this.close();
81
+ return [input];
82
+ }
83
+ });
84
+ Object.defineProperty(this, "sendNack", {
85
+ enumerable: true,
86
+ configurable: true,
87
+ writable: true,
88
+ value: () => new Promise((r, f) => {
89
+ if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {
90
+ const nack = new nack_1.GenericNack({
91
+ senderSsrc: this.senderSsrc,
92
+ mediaSourceSsrc: this.mediaSourceSsrc,
93
+ lost: this.lostSeqNumbers,
94
+ });
95
+ const rtcp = new rtpfb_1.RtcpTransportLayerFeedback({
96
+ feedback: nack,
97
+ });
98
+ this.onNack(rtcp).then(r).catch(f);
99
+ this.updateRetryCount();
100
+ this.onPacketLost.execute(nack);
101
+ }
102
+ })
103
+ });
104
+ }
105
+ get lostSeqNumbers() {
106
+ return Object.keys(this._lost).map(Number).sort();
107
+ }
108
+ getLost(seq) {
109
+ return this._lost[seq];
110
+ }
111
+ setLost(seq, count) {
112
+ this._lost[seq] = count;
113
+ if (this.nackLoop || this.closed) {
114
+ return;
115
+ }
116
+ this.nackLoop = setInterval(async () => {
117
+ try {
118
+ await this.sendNack();
119
+ if (!Object.keys(this._lost).length) {
120
+ clearInterval(this.nackLoop);
121
+ this.nackLoop = undefined;
122
+ }
123
+ }
124
+ catch (error) {
125
+ log("failed to send nack", error);
126
+ }
127
+ }, 5);
128
+ }
129
+ removeLost(sequenceNumber) {
130
+ delete this._lost[sequenceNumber];
131
+ }
132
+ addPacket(packet) {
133
+ const { sequenceNumber, ssrc } = packet.header;
134
+ this.mediaSourceSsrc = ssrc;
135
+ if (this.newEstSeqNum === 0) {
136
+ this.newEstSeqNum = sequenceNumber;
137
+ return;
138
+ }
139
+ if (this.getLost(sequenceNumber)) {
140
+ // log("packetLoss resolved", { sequenceNumber });
141
+ this.removeLost(sequenceNumber);
142
+ return;
143
+ }
144
+ if (sequenceNumber === (0, src_1.uint16Add)(this.newEstSeqNum, 1)) {
145
+ this.newEstSeqNum = sequenceNumber;
146
+ }
147
+ else if (sequenceNumber > (0, src_1.uint16Add)(this.newEstSeqNum, 1)) {
148
+ // packet lost detected
149
+ (0, range_1.default)((0, src_1.uint16Add)(this.newEstSeqNum, 1), sequenceNumber).forEach((seq) => {
150
+ this.setLost(seq, 1);
151
+ });
152
+ // this.receiver.sendRtcpPLI(this.mediaSourceSsrc);
153
+ this.newEstSeqNum = sequenceNumber;
154
+ this.pruneLost();
155
+ }
156
+ }
157
+ pruneLost() {
158
+ if (this.lostSeqNumbers.length > LOST_SIZE) {
159
+ this._lost = Object.entries(this._lost)
160
+ .slice(-LOST_SIZE)
161
+ .reduce((acc, [key, v]) => {
162
+ acc[key] = v;
163
+ return acc;
164
+ }, {});
165
+ }
166
+ }
167
+ close() {
168
+ this.closed = true;
169
+ clearInterval(this.nackLoop);
170
+ this._lost = {};
171
+ }
172
+ updateRetryCount() {
173
+ this.lostSeqNumbers.forEach((seq) => {
174
+ const count = this._lost[seq]++;
175
+ if (count > this.retryCount) {
176
+ this.removeLost(seq);
177
+ return seq;
178
+ }
179
+ });
180
+ }
181
+ }
182
+ exports.NackHandlerBase = NackHandlerBase;
183
+ //# sourceMappingURL=nack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nack.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/nack.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport range from \"lodash/range\";\nimport Event from \"rx.mini\";\n\nimport { uint16Add } from \"../../../common/src\";\nimport { RtcpTransportLayerFeedback } from \"../rtcp/rtpfb\";\nimport { GenericNack } from \"../rtcp/rtpfb/nack\";\nimport { RtpPacket } from \"../rtp/rtp\";\nimport { Processor } from \"./interface\";\nimport { RtpOutput } from \"./source\";\n\nconst log = debug(\"werift-rtp : packages/rtp/src/processor/nack.ts\");\n\nconst LOST_SIZE = 30 * 5;\n\nexport type NackHandlerInput = RtpOutput;\n\nexport type NackHandlerOutput = RtpOutput;\n\nexport class NackHandlerBase\n implements Processor<NackHandlerInput, NackHandlerOutput>\n{\n private newEstSeqNum = 0;\n private _lost: { [seqNum: number]: number } = {};\n private nackLoop: any;\n\n readonly onPacketLost = new Event<[GenericNack]>();\n mediaSourceSsrc?: number;\n retryCount = 10;\n closed = false;\n\n constructor(\n private senderSsrc: number,\n private onNack: (rtcp: RtcpTransportLayerFeedback) => Promise<void>\n ) {}\n\n private get lostSeqNumbers() {\n return Object.keys(this._lost).map(Number).sort();\n }\n\n private getLost(seq: number) {\n return this._lost[seq];\n }\n\n private setLost(seq: number, count: number) {\n this._lost[seq] = count;\n\n if (this.nackLoop || this.closed) {\n return;\n }\n this.nackLoop = setInterval(async () => {\n try {\n await this.sendNack();\n if (!Object.keys(this._lost).length) {\n clearInterval(this.nackLoop);\n this.nackLoop = undefined;\n }\n } catch (error) {\n log(\"failed to send nack\", error);\n }\n }, 5);\n }\n\n private removeLost(sequenceNumber: number) {\n delete this._lost[sequenceNumber];\n }\n\n processInput = (input: RtpOutput) => {\n if (input.rtp) {\n this.addPacket(input.rtp);\n return [input];\n }\n this.close();\n return [input];\n };\n\n private addPacket(packet: RtpPacket) {\n const { sequenceNumber, ssrc } = packet.header;\n this.mediaSourceSsrc = ssrc;\n\n if (this.newEstSeqNum === 0) {\n this.newEstSeqNum = sequenceNumber;\n return;\n }\n\n if (this.getLost(sequenceNumber)) {\n // log(\"packetLoss resolved\", { sequenceNumber });\n this.removeLost(sequenceNumber);\n return;\n }\n\n if (sequenceNumber === uint16Add(this.newEstSeqNum, 1)) {\n this.newEstSeqNum = sequenceNumber;\n } else if (sequenceNumber > uint16Add(this.newEstSeqNum, 1)) {\n // packet lost detected\n range(uint16Add(this.newEstSeqNum, 1), sequenceNumber).forEach((seq) => {\n this.setLost(seq, 1);\n });\n // this.receiver.sendRtcpPLI(this.mediaSourceSsrc);\n\n this.newEstSeqNum = sequenceNumber;\n this.pruneLost();\n }\n }\n\n private pruneLost() {\n if (this.lostSeqNumbers.length > LOST_SIZE) {\n this._lost = Object.entries(this._lost)\n .slice(-LOST_SIZE)\n .reduce((acc, [key, v]) => {\n acc[key] = v;\n return acc;\n }, {} as { [seqNum: number]: number });\n }\n }\n\n private close() {\n this.closed = true;\n clearInterval(this.nackLoop);\n this._lost = {};\n }\n\n private updateRetryCount() {\n this.lostSeqNumbers.forEach((seq) => {\n const count = this._lost[seq]++;\n if (count > this.retryCount) {\n this.removeLost(seq);\n return seq;\n }\n });\n }\n\n private sendNack = () =>\n new Promise((r, f) => {\n if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {\n const nack = new GenericNack({\n senderSsrc: this.senderSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lostSeqNumbers,\n });\n\n const rtcp = new RtcpTransportLayerFeedback({\n feedback: nack,\n });\n this.onNack(rtcp).then(r).catch(f);\n\n this.updateRetryCount();\n this.onPacketLost.execute(nack);\n }\n });\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { RtcpTransportLayerFeedback } from "../rtcp/rtpfb";
2
+ import { NackHandlerBase, NackHandlerInput, NackHandlerOutput } from "./nack";
3
+ export declare class NackHandlerCallback extends NackHandlerBase {
4
+ private cb;
5
+ constructor(senderSsrc: number, onNack: (rtcp: RtcpTransportLayerFeedback) => Promise<void>);
6
+ pipe: (cb: (input: NackHandlerOutput) => void) => this;
7
+ input: (input: NackHandlerInput) => void;
8
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NackHandlerCallback = void 0;
4
+ const nack_1 = require("./nack");
5
+ class NackHandlerCallback extends nack_1.NackHandlerBase {
6
+ constructor(senderSsrc, onNack) {
7
+ super(senderSsrc, onNack);
8
+ Object.defineProperty(this, "cb", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: void 0
13
+ });
14
+ Object.defineProperty(this, "pipe", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: (cb) => {
19
+ this.cb = cb;
20
+ return this;
21
+ }
22
+ });
23
+ Object.defineProperty(this, "input", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: (input) => {
28
+ for (const output of this.processInput(input)) {
29
+ this.cb(output);
30
+ }
31
+ }
32
+ });
33
+ }
34
+ }
35
+ exports.NackHandlerCallback = NackHandlerCallback;
36
+ //# sourceMappingURL=nackHandlerCallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nackHandlerCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/nackHandlerCallback.ts"],"names":[],"mappings":";;;AACA,iCAA8E;AAE9E,MAAa,mBAAoB,SAAQ,sBAAe;IAEtD,YACE,UAAkB,EAClB,MAA2D;QAE3D,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAL5B;;;;;WAAgD;QAQhD;;;;mBAAO,CAAC,EAAsC,EAAE,EAAE;gBAChD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;WAAC;QAEF;;;;mBAAQ,CAAC,KAAuB,EAAE,EAAE;gBAClC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;oBAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;iBACjB;YACH,CAAC;WAAC;IAXF,CAAC;CAYF;AAnBD,kDAmBC","sourcesContent":["import { RtcpTransportLayerFeedback } from \"../rtcp/rtpfb\";\nimport { NackHandlerBase, NackHandlerInput, NackHandlerOutput } from \"./nack\";\n\nexport class NackHandlerCallback extends NackHandlerBase {\n private cb!: (input: NackHandlerOutput) => void;\n constructor(\n senderSsrc: number,\n onNack: (rtcp: RtcpTransportLayerFeedback) => Promise<void>\n ) {\n super(senderSsrc, onNack);\n }\n\n pipe = (cb: (input: NackHandlerOutput) => void) => {\n this.cb = cb;\n return this;\n };\n\n input = (input: NackHandlerInput) => {\n for (const output of this.processInput(input)) {\n this.cb(output);\n }\n };\n}\n"]}
@@ -51,7 +51,8 @@ class syncRtpBase {
51
51
  .map((rtp) => {
52
52
  const ntp = this.calcNtp(rtp.header.timestamp);
53
53
  if (ntp) {
54
- res.push({ rtp, time: ntp * 1000 });
54
+ const ms = ntp * 1000;
55
+ res.push({ rtp, time: ms });
55
56
  return undefined;
56
57
  }
57
58
  return rtp;
@@ -1 +1 @@
1
- {"version":3,"file":"ntpTime.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/ntpTime.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport {\n bufferReader,\n bufferWriter,\n RtcpPacket,\n RtcpSrPacket,\n RtpPacket,\n} from \"..\";\nimport { Max32bit } from \"../processor_old/lipsync\";\nimport { Processor } from \"./interface\";\n\nconst log = debug(\"werift-rtp : packages/rtp/src/processor/ntpTime.ts\");\n\nexport type NtpTimeInput = {\n rtp?: RtpPacket;\n eol?: boolean;\n rtcp?: RtcpPacket;\n};\n\nexport interface NtpTimeOutput {\n rtp?: RtpPacket;\n /**ms */\n time?: number;\n eol?: boolean;\n}\n\nexport class syncRtpBase implements Processor<NtpTimeInput, NtpTimeOutput> {\n ntpTimestamp?: bigint;\n rtpTimestamp?: number;\n\n buffer: RtpPacket[] = [];\n\n constructor(public clockRate: number) {}\n\n processInput({ rtcp, rtp, eol }: NtpTimeInput): NtpTimeOutput[] {\n if (eol) {\n return [{ eol: true }];\n }\n\n if (rtcp && rtcp instanceof RtcpSrPacket && !this.ntpTimestamp) {\n const { ntpTimestamp, rtpTimestamp } = rtcp.senderInfo;\n this.ntpTimestamp = ntpTimestamp;\n this.rtpTimestamp = rtpTimestamp;\n }\n\n if (rtp) {\n this.buffer.push(rtp);\n\n const res: NtpTimeOutput[] = [];\n\n this.buffer = this.buffer\n .map((rtp) => {\n const ntp = this.calcNtp(rtp.header.timestamp);\n if (ntp) {\n res.push({ rtp, time: ntp * 1000 });\n return undefined;\n }\n return rtp;\n })\n .filter((r): r is NonNullable<typeof r> => r != undefined);\n return res;\n }\n\n return [];\n }\n\n /**sec */\n private calcNtp(rtpTimestamp: number) {\n if (this.rtpTimestamp == undefined || this.ntpTimestamp == undefined) {\n return;\n }\n\n // base rtpTimestamp is rollover\n if (rtpTimestamp - this.rtpTimestamp > Max32bit - this.clockRate * 60) {\n this.rtpTimestamp += Max32bit;\n log(\"base rtpTimestamp is rollover\");\n }\n\n // target rtpTimestamp is rollover\n else if (\n rtpTimestamp + (Max32bit - this.clockRate * 60) - this.rtpTimestamp <\n 0\n ) {\n rtpTimestamp += Max32bit;\n log(\"target rtpTimestamp is rollover\");\n }\n\n const elapsed = (rtpTimestamp - this.rtpTimestamp) / this.clockRate;\n\n const ntp = ntpTime2Time(this.ntpTimestamp) + elapsed;\n\n return ntp;\n }\n}\n\nexport const ntpTime2Time = (ntp: bigint) => {\n const [ntpSec, ntpMsec] = bufferReader(bufferWriter([8], [ntp]), [4, 4]);\n\n return Number(`${ntpSec}.${ntpMsec}`);\n};\n"]}
1
+ {"version":3,"file":"ntpTime.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/ntpTime.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport {\n bufferReader,\n bufferWriter,\n RtcpPacket,\n RtcpSrPacket,\n RtpPacket,\n} from \"..\";\nimport { Max32bit } from \"../processor_old/lipsync\";\nimport { Processor } from \"./interface\";\n\nconst log = debug(\"werift-rtp : packages/rtp/src/processor/ntpTime.ts\");\n\nexport type NtpTimeInput = {\n rtp?: RtpPacket;\n eol?: boolean;\n rtcp?: RtcpPacket;\n};\n\nexport interface NtpTimeOutput {\n rtp?: RtpPacket;\n /**ms */\n time?: number;\n eol?: boolean;\n}\n\nexport class syncRtpBase implements Processor<NtpTimeInput, NtpTimeOutput> {\n ntpTimestamp?: bigint;\n rtpTimestamp?: number;\n\n buffer: RtpPacket[] = [];\n\n constructor(public clockRate: number) {}\n\n processInput({ rtcp, rtp, eol }: NtpTimeInput): NtpTimeOutput[] {\n if (eol) {\n return [{ eol: true }];\n }\n\n if (rtcp && rtcp instanceof RtcpSrPacket && !this.ntpTimestamp) {\n const { ntpTimestamp, rtpTimestamp } = rtcp.senderInfo;\n this.ntpTimestamp = ntpTimestamp;\n this.rtpTimestamp = rtpTimestamp;\n }\n\n if (rtp) {\n this.buffer.push(rtp);\n\n const res: NtpTimeOutput[] = [];\n\n this.buffer = this.buffer\n .map((rtp) => {\n const ntp = this.calcNtp(rtp.header.timestamp);\n if (ntp) {\n const ms = ntp * 1000;\n res.push({ rtp, time: ms });\n return undefined;\n }\n return rtp;\n })\n .filter((r): r is NonNullable<typeof r> => r != undefined);\n return res;\n }\n\n return [];\n }\n\n /**sec */\n private calcNtp(rtpTimestamp: number) {\n if (this.rtpTimestamp == undefined || this.ntpTimestamp == undefined) {\n return;\n }\n\n // base rtpTimestamp is rollover\n if (rtpTimestamp - this.rtpTimestamp > Max32bit - this.clockRate * 60) {\n this.rtpTimestamp += Max32bit;\n log(\"base rtpTimestamp is rollover\");\n }\n\n // target rtpTimestamp is rollover\n else if (\n rtpTimestamp + (Max32bit - this.clockRate * 60) - this.rtpTimestamp <\n 0\n ) {\n rtpTimestamp += Max32bit;\n log(\"target rtpTimestamp is rollover\");\n }\n\n const elapsed = (rtpTimestamp - this.rtpTimestamp) / this.clockRate;\n\n const ntp = ntpTime2Time(this.ntpTimestamp) + elapsed;\n\n return ntp;\n }\n}\n\nexport const ntpTime2Time = (ntp: bigint) => {\n const [ntpSec, ntpMsec] = bufferReader(bufferWriter([8], [ntp]), [4, 4]);\n\n return Number(`${ntpSec}.${ntpMsec}`);\n};\n"]}
@@ -0,0 +1,22 @@
1
+ import { RtpPacket } from "..";
2
+ import { Processor } from "./interface";
3
+ export type RtpTimeInput = {
4
+ rtp?: RtpPacket;
5
+ eol?: boolean;
6
+ };
7
+ export interface RtpTimeOutput {
8
+ rtp?: RtpPacket;
9
+ /**ms */
10
+ time?: number;
11
+ eol?: boolean;
12
+ }
13
+ export declare class RtpTimeBase implements Processor<RtpTimeInput, RtpTimeOutput> {
14
+ clockRate: number;
15
+ baseTimestamp?: number;
16
+ /**ms */
17
+ elapsed: number;
18
+ constructor(clockRate: number);
19
+ processInput({ rtp, eol }: RtpTimeInput): RtpTimeOutput[];
20
+ /**ms */
21
+ private update;
22
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RtpTimeBase = void 0;
4
+ const __1 = require("..");
5
+ class RtpTimeBase {
6
+ constructor(clockRate) {
7
+ Object.defineProperty(this, "clockRate", {
8
+ enumerable: true,
9
+ configurable: true,
10
+ writable: true,
11
+ value: clockRate
12
+ });
13
+ Object.defineProperty(this, "baseTimestamp", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: void 0
18
+ });
19
+ /**ms */
20
+ Object.defineProperty(this, "elapsed", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: 0
25
+ });
26
+ }
27
+ processInput({ rtp, eol }) {
28
+ if (eol) {
29
+ return [{ eol: true }];
30
+ }
31
+ if (rtp) {
32
+ const elapsed = this.update(rtp.header.timestamp);
33
+ return [{ rtp, time: elapsed }];
34
+ }
35
+ return [];
36
+ }
37
+ /**ms */
38
+ update(timestamp) {
39
+ if (this.baseTimestamp == undefined) {
40
+ this.baseTimestamp = timestamp;
41
+ }
42
+ const rotate = Math.abs(timestamp - this.baseTimestamp) > (__1.Max32Uint / 4) * 3;
43
+ const elapsed = rotate
44
+ ? timestamp + __1.Max32Uint - this.baseTimestamp
45
+ : timestamp - this.baseTimestamp;
46
+ this.elapsed = (0, __1.int)((elapsed / this.clockRate) * 1000);
47
+ return this.elapsed;
48
+ }
49
+ }
50
+ exports.RtpTimeBase = RtpTimeBase;
51
+ //# sourceMappingURL=rtpTime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtpTime.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/rtpTime.ts"],"names":[],"mappings":";;;AAAA,0BAA+C;AAe/C,MAAa,WAAW;IAKtB,YAAmB,SAAiB;;;;;mBAAjB;;QAJnB;;;;;WAAuB;QACvB,QAAQ;QACR;;;;mBAAU,CAAC;WAAC;IAE2B,CAAC;IAExC,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAgB;QACrC,IAAI,GAAG,EAAE;YACP,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;SACxB;QAED,IAAI,GAAG,EAAE;YACP,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAClD,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;SACjC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,QAAQ;IACA,MAAM,CAAC,SAAiB;QAC9B,IAAI,IAAI,CAAC,aAAa,IAAI,SAAS,EAAE;YACnC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;SAChC;QACD,MAAM,MAAM,GACV,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,aAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAEjE,MAAM,OAAO,GAAG,MAAM;YACpB,CAAC,CAAC,SAAS,GAAG,aAAS,GAAG,IAAI,CAAC,aAAa;YAC5C,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC;QAEnC,IAAI,CAAC,OAAO,GAAG,IAAA,OAAG,EAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF;AAnCD,kCAmCC","sourcesContent":["import { int, Max32Uint, RtpPacket } from \"..\";\nimport { Processor } from \"./interface\";\n\nexport type RtpTimeInput = {\n rtp?: RtpPacket;\n eol?: boolean;\n};\n\nexport interface RtpTimeOutput {\n rtp?: RtpPacket;\n /**ms */\n time?: number;\n eol?: boolean;\n}\n\nexport class RtpTimeBase implements Processor<RtpTimeInput, RtpTimeOutput> {\n baseTimestamp?: number;\n /**ms */\n elapsed = 0;\n\n constructor(public clockRate: number) {}\n\n processInput({ rtp, eol }: RtpTimeInput): RtpTimeOutput[] {\n if (eol) {\n return [{ eol: true }];\n }\n\n if (rtp) {\n const elapsed = this.update(rtp.header.timestamp);\n return [{ rtp, time: elapsed }];\n }\n\n return [];\n }\n\n /**ms */\n private update(timestamp: number) {\n if (this.baseTimestamp == undefined) {\n this.baseTimestamp = timestamp;\n }\n const rotate =\n Math.abs(timestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;\n\n const elapsed = rotate\n ? timestamp + Max32Uint - this.baseTimestamp\n : timestamp - this.baseTimestamp;\n\n this.elapsed = int((elapsed / this.clockRate) * 1000);\n return this.elapsed;\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import { RtpTimeBase, RtpTimeInput, RtpTimeOutput } from "./rtpTime";
2
+ export declare class RtpTimeCallback extends RtpTimeBase {
3
+ private cb;
4
+ constructor(clockRate: number);
5
+ pipe: (cb: (input: RtpTimeOutput) => void) => this;
6
+ input: (input: RtpTimeInput) => void;
7
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RtpTimeCallback = void 0;
4
+ const rtpTime_1 = require("./rtpTime");
5
+ class RtpTimeCallback extends rtpTime_1.RtpTimeBase {
6
+ constructor(clockRate) {
7
+ super(clockRate);
8
+ Object.defineProperty(this, "cb", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: void 0
13
+ });
14
+ Object.defineProperty(this, "pipe", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: (cb) => {
19
+ this.cb = cb;
20
+ return this;
21
+ }
22
+ });
23
+ Object.defineProperty(this, "input", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: (input) => {
28
+ for (const output of this.processInput(input)) {
29
+ this.cb(output);
30
+ }
31
+ }
32
+ });
33
+ }
34
+ }
35
+ exports.RtpTimeCallback = RtpTimeCallback;
36
+ //# sourceMappingURL=rtpTimeCallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtpTimeCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/rtpTimeCallback.ts"],"names":[],"mappings":";;;AAAA,uCAAqE;AAErE,MAAa,eAAgB,SAAQ,qBAAW;IAG9C,YAAY,SAAiB;QAC3B,KAAK,CAAC,SAAS,CAAC,CAAC;QAHnB;;;;;WAA4C;QAM5C;;;;mBAAO,CAAC,EAAkC,EAAE,EAAE;gBAC5C,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;WAAC;QAEF;;;;mBAAQ,CAAC,KAAmB,EAAE,EAAE;gBAC9B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;oBAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;iBACjB;YACH,CAAC;WAAC;IAXF,CAAC;CAYF;AAjBD,0CAiBC","sourcesContent":["import { RtpTimeBase, RtpTimeInput, RtpTimeOutput } from \"./rtpTime\";\n\nexport class RtpTimeCallback extends RtpTimeBase {\n private cb!: (input: RtpTimeOutput) => void;\n\n constructor(clockRate: number) {\n super(clockRate);\n }\n\n pipe = (cb: (input: RtpTimeOutput) => void) => {\n this.cb = cb;\n return this;\n };\n\n input = (input: RtpTimeInput) => {\n for (const output of this.processInput(input)) {\n this.cb(output);\n }\n };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import Event from "rx.mini";
1
2
  import { RtcpPacket } from "../../rtcp/rtcp";
2
3
  export interface RtcpOutput {
3
4
  rtcp?: RtcpPacket;
@@ -5,7 +6,7 @@ export interface RtcpOutput {
5
6
  }
6
7
  export declare class RtcpSourceCallback {
7
8
  private cb?;
8
- constructor();
9
+ onStopped: Event<any[]>;
9
10
  pipe(cb: (chunk: RtcpOutput) => void): void;
10
11
  input: (rtcp: RtcpPacket) => void;
11
12
  stop(): void;