werift 0.16.0 → 0.16.1

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 (80) hide show
  1. package/lib/rtp/src/codec/index.d.ts +0 -4
  2. package/lib/rtp/src/codec/index.js +2 -6
  3. package/lib/rtp/src/codec/index.js.map +1 -1
  4. package/lib/rtp/src/index.d.ts +1 -6
  5. package/lib/rtp/src/index.js +1 -6
  6. package/lib/rtp/src/index.js.map +1 -1
  7. package/lib/rtp/src/processor/depacketizer.d.ts +26 -0
  8. package/lib/rtp/src/processor/depacketizer.js +114 -0
  9. package/lib/rtp/src/processor/depacketizer.js.map +1 -0
  10. package/lib/rtp/src/processor/depacketizerCallback.d.ts +13 -0
  11. package/lib/rtp/src/processor/depacketizerCallback.js +20 -0
  12. package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -0
  13. package/lib/rtp/src/processor/depacketizerTransformer.d.ts +8 -0
  14. package/lib/rtp/src/processor/depacketizerTransformer.js +20 -0
  15. package/lib/rtp/src/processor/depacketizerTransformer.js.map +1 -0
  16. package/lib/rtp/src/processor/index.d.ts +9 -0
  17. package/lib/rtp/src/{processor_v2 → processor}/index.js +6 -1
  18. package/lib/rtp/src/processor/index.js.map +1 -0
  19. package/lib/rtp/src/processor/jitterBuffer.d.ts +26 -11
  20. package/lib/rtp/src/processor/jitterBuffer.js +150 -42
  21. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  22. package/lib/rtp/src/processor/jitterBufferCallback.d.ts +10 -0
  23. package/lib/rtp/src/processor/jitterBufferCallback.js +21 -0
  24. package/lib/rtp/src/processor/jitterBufferCallback.js.map +1 -0
  25. package/lib/rtp/src/processor/jitterBufferTransformer.d.ts +9 -0
  26. package/lib/rtp/src/processor/jitterBufferTransformer.js +22 -0
  27. package/lib/rtp/src/processor/jitterBufferTransformer.js.map +1 -0
  28. package/lib/rtp/src/{processor_v2 → processor}/source/index.d.ts +0 -0
  29. package/lib/rtp/src/{processor_v2 → processor}/source/index.js +0 -0
  30. package/lib/rtp/src/processor/source/index.js.map +1 -0
  31. package/lib/rtp/src/processor/source/rtp.d.ts +20 -0
  32. package/lib/rtp/src/processor/source/rtp.js +32 -0
  33. package/lib/rtp/src/processor/source/rtp.js.map +1 -0
  34. package/lib/rtp/src/processor/webm.d.ts +24 -24
  35. package/lib/rtp/src/processor/webm.js +78 -89
  36. package/lib/rtp/src/processor/webm.js.map +1 -1
  37. package/lib/rtp/src/processor/webmStream.d.ts +31 -0
  38. package/lib/rtp/src/processor/webmStream.js +36 -0
  39. package/lib/rtp/src/processor/webmStream.js.map +1 -0
  40. package/lib/rtp/src/rtp/rtp.d.ts +1 -0
  41. package/lib/rtp/src/rtp/rtp.js +3 -0
  42. package/lib/rtp/src/rtp/rtp.js.map +1 -1
  43. package/lib/webrtc/src/media/rtpReceiver.d.ts +3 -2
  44. package/lib/webrtc/src/media/rtpReceiver.js +14 -6
  45. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  46. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +8 -6
  47. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  48. package/lib/webrtc/src/peerConnection.js +3 -1
  49. package/lib/webrtc/src/peerConnection.js.map +1 -1
  50. package/package.json +1 -1
  51. package/src/media/rtpReceiver.ts +23 -11
  52. package/src/nonstandard/recorder/writer/webm.ts +9 -7
  53. package/src/peerConnection.ts +3 -1
  54. package/lib/rtp/src/processor/base.d.ts +0 -18
  55. package/lib/rtp/src/processor/base.js +0 -39
  56. package/lib/rtp/src/processor/base.js.map +0 -1
  57. package/lib/rtp/src/processor/lipsync.d.ts +0 -30
  58. package/lib/rtp/src/processor/lipsync.js +0 -92
  59. package/lib/rtp/src/processor/lipsync.js.map +0 -1
  60. package/lib/rtp/src/processor/sampleBuilder.d.ts +0 -13
  61. package/lib/rtp/src/processor/sampleBuilder.js +0 -33
  62. package/lib/rtp/src/processor/sampleBuilder.js.map +0 -1
  63. package/lib/rtp/src/processor_v2/depacketizer.d.ts +0 -17
  64. package/lib/rtp/src/processor_v2/depacketizer.js +0 -84
  65. package/lib/rtp/src/processor_v2/depacketizer.js.map +0 -1
  66. package/lib/rtp/src/processor_v2/index.d.ts +0 -4
  67. package/lib/rtp/src/processor_v2/index.js.map +0 -1
  68. package/lib/rtp/src/processor_v2/jitterBuffer.d.ts +0 -33
  69. package/lib/rtp/src/processor_v2/jitterBuffer.js +0 -154
  70. package/lib/rtp/src/processor_v2/jitterBuffer.js.map +0 -1
  71. package/lib/rtp/src/processor_v2/source/base.d.ts +0 -8
  72. package/lib/rtp/src/processor_v2/source/base.js +0 -16
  73. package/lib/rtp/src/processor_v2/source/base.js.map +0 -1
  74. package/lib/rtp/src/processor_v2/source/index.js.map +0 -1
  75. package/lib/rtp/src/processor_v2/source/rtp.d.ts +0 -14
  76. package/lib/rtp/src/processor_v2/source/rtp.js +0 -24
  77. package/lib/rtp/src/processor_v2/source/rtp.js.map +0 -1
  78. package/lib/rtp/src/processor_v2/webmLive.d.ts +0 -51
  79. package/lib/rtp/src/processor_v2/webmLive.js +0 -154
  80. package/lib/rtp/src/processor_v2/webmLive.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"jitterBuffer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/jitterBuffer.ts"],"names":[],"mappings":";;;AAAA,iCAA8B;AAE9B,6CAAgD;AAGhD,iCAAkC;AAElC,MAAM,GAAG,GAAG,IAAA,aAAK,EAAC,qDAAqD,CAAC,CAAC;AAEzE,MAAa,YAAa,SAAQ,eAAQ;IAA1C;;QACU,UAAK,GAAG,CAAC,CAAC;QAEV,WAAM,GAA4C,EAAE,CAAC;QAE7D,aAAQ,GAAG,GAAG,CAAC;QAUP,UAAK,GAAG,CAAC,CAAY,EAAE,EAAE;YAC/B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAEzC,IAAI,IAAI,CAAC,IAAI,IAAI,SAAS,EAAE;gBAC1B,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC;aACrC;iBAAM,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,IAAA,eAAS,EAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE;gBAC7D,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE;oBACjC,IAAI,CAAC,IAAI,GAAG,IAAA,eAAS,EAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;iBACrC;qBAAM;oBACL,OAAO;iBACR;aACF;iBAAM;gBACL,IAAI,CAAC,IAAI,GAAG,IAAA,eAAS,EAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;aACrC;YAED,MAAM,OAAO,GAAgB,EAAE,CAAC;YAChC,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACrB,QAAS,IAAI,GAAG,IAAA,eAAS,EAAC,IAAI,EAAE,CAAC,CAAC,EAAE;gBAClC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC5B,IAAI,CAAC,EAAE;oBACL,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAChB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;iBAC1B;qBAAM;oBACL,MAAM;iBACP;aACF;YACD,IAAI,CAAC,IAAI,GAAG,IAAA,eAAS,EAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAEhC,IAAI,CAAC,QAAQ,EAAE,cAAc,EAAE,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC,CAAC;IACJ,CAAC;IAtCC,cAAc,CAAC,OAAoB;QACjC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,eAAe,CAAC,OAAqB;QACnC,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;CAgCF;AA7CD,oCA6CC","sourcesContent":["import { debug } from \"debug\";\n\nimport { uint16Add } from \"../../../common/src\";\nimport { RtpPacket } from \"..\";\nimport { RtcpPacket } from \"../rtcp/rtcp\";\nimport { Pipeline } from \"./base\";\n\nconst log = debug(\"werift : packages/rtp/src/processor/jitterBuffer.ts\");\n\nexport class JitterBuffer extends Pipeline {\n private retry = 0;\n private head?: number;\n private buffer: { [sequenceNumber: number]: RtpPacket } = {};\n\n maxRetry = 100;\n\n pushRtpPackets(packets: RtpPacket[]) {\n packets.forEach(this.onRtp);\n }\n\n pushRtcpPackets(packets: RtcpPacket[]) {\n this.children?.pushRtcpPackets?.(packets);\n }\n\n private onRtp = (p: RtpPacket) => {\n this.buffer[p.header.sequenceNumber] = p;\n\n if (this.head == undefined) {\n this.head = p.header.sequenceNumber;\n } else if (p.header.sequenceNumber != uint16Add(this.head, 1)) {\n if (this.retry++ >= this.maxRetry) {\n this.head = uint16Add(this.head, 2);\n } else {\n return;\n }\n } else {\n this.head = uint16Add(this.head, 1);\n }\n\n const packets: RtpPacket[] = [];\n let tail = this.head;\n for (; ; tail = uint16Add(tail, 1)) {\n const p = this.buffer[tail];\n if (p) {\n packets.push(p);\n delete this.buffer[tail];\n } else {\n break;\n }\n }\n this.head = uint16Add(tail, -1);\n\n this.children?.pushRtpPackets?.(packets);\n };\n}\n"]}
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 { 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 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"]}
@@ -0,0 +1,10 @@
1
+ import { JitterBufferBase, JitterBufferInput, JitterBufferOptions, JitterBufferOutput } from "./jitterBuffer";
2
+ export declare class JitterBufferCallback extends JitterBufferBase {
3
+ clockRate: number;
4
+ private cb;
5
+ constructor(clockRate: number, options?: Partial<JitterBufferOptions>);
6
+ pipe: (instance: {
7
+ input: (input: JitterBufferOutput) => void;
8
+ }) => this;
9
+ input: (input: JitterBufferInput) => void;
10
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JitterBufferCallback = void 0;
4
+ const jitterBuffer_1 = require("./jitterBuffer");
5
+ class JitterBufferCallback extends jitterBuffer_1.JitterBufferBase {
6
+ constructor(clockRate, options = {}) {
7
+ super(clockRate, options);
8
+ this.clockRate = clockRate;
9
+ this.pipe = (instance) => {
10
+ this.cb = instance.input;
11
+ return this;
12
+ };
13
+ this.input = (input) => {
14
+ for (const output of this.processInput(input)) {
15
+ this.cb(output);
16
+ }
17
+ };
18
+ }
19
+ }
20
+ exports.JitterBufferCallback = JitterBufferCallback;
21
+ //# sourceMappingURL=jitterBufferCallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jitterBufferCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/jitterBufferCallback.ts"],"names":[],"mappings":";;;AAAA,iDAKwB;AAExB,MAAa,oBAAqB,SAAQ,+BAAgB;IAExD,YACS,SAAiB,EACxB,UAAwC,EAAE;QAE1C,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAHnB,cAAS,GAAT,SAAS,CAAQ;QAM1B,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;AAnBD,oDAmBC","sourcesContent":["import {\n JitterBufferBase,\n JitterBufferInput,\n JitterBufferOptions,\n JitterBufferOutput,\n} from \"./jitterBuffer\";\n\nexport class JitterBufferCallback extends JitterBufferBase {\n private cb!: (input: JitterBufferOutput) => void;\n constructor(\n public clockRate: number,\n options: Partial<JitterBufferOptions> = {}\n ) {\n super(clockRate, options);\n }\n\n pipe = (instance: { input: (input: JitterBufferOutput) => void }) => {\n this.cb = instance.input;\n return this;\n };\n\n input = (input: JitterBufferInput) => {\n for (const output of this.processInput(input)) {\n this.cb(output);\n }\n };\n}\n"]}
@@ -0,0 +1,9 @@
1
+ /// <reference types="node" />
2
+ import { TransformStream } from "stream/web";
3
+ import { JitterBufferBase, JitterBufferInput, JitterBufferOptions, JitterBufferOutput } from "./jitterBuffer";
4
+ export declare const jitterBufferTransformer: (clockRate: number, options?: Partial<JitterBufferOptions> | undefined) => TransformStream<import("./source/rtp").RtpOutput, JitterBufferOutput>;
5
+ export declare class JitterBufferTransformer extends JitterBufferBase {
6
+ clockRate: number;
7
+ transform: TransformStream<JitterBufferInput, JitterBufferOutput>;
8
+ constructor(clockRate: number, options?: Partial<JitterBufferOptions>);
9
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JitterBufferTransformer = exports.jitterBufferTransformer = void 0;
4
+ const web_1 = require("stream/web");
5
+ const jitterBuffer_1 = require("./jitterBuffer");
6
+ const jitterBufferTransformer = (...args) => new JitterBufferTransformer(...args).transform;
7
+ exports.jitterBufferTransformer = jitterBufferTransformer;
8
+ class JitterBufferTransformer extends jitterBuffer_1.JitterBufferBase {
9
+ constructor(clockRate, options = {}) {
10
+ super(clockRate, options);
11
+ this.clockRate = clockRate;
12
+ this.transform = new web_1.TransformStream({
13
+ transform: (input, output) => {
14
+ for (const res of this.processInput(input)) {
15
+ output.enqueue(res);
16
+ }
17
+ },
18
+ });
19
+ }
20
+ }
21
+ exports.JitterBufferTransformer = JitterBufferTransformer;
22
+ //# sourceMappingURL=jitterBufferTransformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jitterBufferTransformer.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/jitterBufferTransformer.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAE7C,iDAKwB;AAEjB,MAAM,uBAAuB,GAAG,CACrC,GAAG,IAA2D,EAC9D,EAAE,CAAC,IAAI,uBAAuB,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC;AAFvC,QAAA,uBAAuB,2BAEgB;AAEpD,MAAa,uBAAwB,SAAQ,+BAAgB;IAG3D,YACS,SAAiB,EACxB,UAAwC,EAAE;QAE1C,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAHnB,cAAS,GAAT,SAAS,CAAQ;QAKxB,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;AAjBD,0DAiBC","sourcesContent":["import { TransformStream } from \"stream/web\";\n\nimport {\n JitterBufferBase,\n JitterBufferInput,\n JitterBufferOptions,\n JitterBufferOutput,\n} from \"./jitterBuffer\";\n\nexport const jitterBufferTransformer = (\n ...args: ConstructorParameters<typeof JitterBufferTransformer>\n) => new JitterBufferTransformer(...args).transform;\n\nexport class JitterBufferTransformer extends JitterBufferBase {\n transform: TransformStream<JitterBufferInput, JitterBufferOutput>;\n\n constructor(\n public clockRate: number,\n options: Partial<JitterBufferOptions> = {}\n ) {\n super(clockRate, 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"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../rtp/src/processor/source/index.ts"],"names":[],"mappings":";;;AAAA,+BAAwC;AAE/B,gGAFA,qBAAe,OAEA","sourcesContent":["import { RtpSourceStream } from \"./rtp\";\n\nexport { RtpSourceStream };\n"]}
@@ -0,0 +1,20 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { ReadableStream, ReadableStreamController } from "stream/web";
4
+ import { RtpPacket } from "../../rtp/rtp";
5
+ export interface RtpOutput {
6
+ rtp?: RtpPacket;
7
+ eol?: boolean;
8
+ }
9
+ export declare class RtpSourceStream {
10
+ private options;
11
+ readable: ReadableStream<RtpOutput>;
12
+ write: (chunk: RtpOutput) => void;
13
+ protected controller: ReadableStreamController<RtpOutput>;
14
+ constructor(options?: {
15
+ payloadType?: number;
16
+ clearInvalidPTPacket?: boolean;
17
+ });
18
+ push(packet: Buffer | RtpPacket): void;
19
+ stop(): void;
20
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RtpSourceStream = void 0;
4
+ const web_1 = require("stream/web");
5
+ const rtp_1 = require("../../rtp/rtp");
6
+ class RtpSourceStream {
7
+ constructor(options = {}) {
8
+ this.options = options;
9
+ options.clearInvalidPTPacket = options.clearInvalidPTPacket ?? true;
10
+ this.readable = new web_1.ReadableStream({
11
+ start: (controller) => {
12
+ this.controller = controller;
13
+ this.write = (chunk) => controller.enqueue(chunk);
14
+ },
15
+ });
16
+ }
17
+ push(packet) {
18
+ const rtp = packet instanceof rtp_1.RtpPacket ? packet : rtp_1.RtpPacket.deSerialize(packet);
19
+ if (this.options.payloadType != undefined &&
20
+ this.options.payloadType !== rtp.header.payloadType &&
21
+ this.options.clearInvalidPTPacket) {
22
+ rtp.clear();
23
+ return;
24
+ }
25
+ this.write({ rtp });
26
+ }
27
+ stop() {
28
+ this.controller.enqueue({ eol: true });
29
+ }
30
+ }
31
+ exports.RtpSourceStream = RtpSourceStream;
32
+ //# sourceMappingURL=rtp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtp.js","sourceRoot":"","sources":["../../../../../../rtp/src/processor/source/rtp.ts"],"names":[],"mappings":";;;AAAA,oCAAsE;AAEtE,uCAA0C;AAO1C,MAAa,eAAe;IAK1B,YACU,UAGJ,EAAE;QAHE,YAAO,GAAP,OAAO,CAGT;QAEN,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,IAAI,IAAI,CAAC;QAEpE,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAc,CAAC;YACjC,KAAK,EAAE,CAAC,UAAU,EAAE,EAAE;gBACpB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;gBAC7B,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpD,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,MAA0B;QAC7B,MAAM,GAAG,GACP,MAAM,YAAY,eAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAEvE,IACE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,SAAS;YACrC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW;YACnD,IAAI,CAAC,OAAO,CAAC,oBAAoB,EACjC;YACA,GAAG,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO;SACR;QAED,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;CACF;AAxCD,0CAwCC","sourcesContent":["import { ReadableStream, ReadableStreamController } from \"stream/web\";\n\nimport { RtpPacket } from \"../../rtp/rtp\";\n\nexport interface RtpOutput {\n rtp?: RtpPacket;\n eol?: boolean;\n}\n\nexport class RtpSourceStream {\n readable: ReadableStream<RtpOutput>;\n write!: (chunk: RtpOutput) => void;\n protected controller!: ReadableStreamController<RtpOutput>;\n\n constructor(\n private options: {\n payloadType?: number;\n clearInvalidPTPacket?: boolean;\n } = {}\n ) {\n options.clearInvalidPTPacket = options.clearInvalidPTPacket ?? true;\n\n this.readable = new ReadableStream({\n start: (controller) => {\n this.controller = controller;\n this.write = (chunk) => controller.enqueue(chunk);\n },\n });\n }\n\n push(packet: Buffer | RtpPacket) {\n const rtp =\n packet instanceof RtpPacket ? packet : RtpPacket.deSerialize(packet);\n\n if (\n this.options.payloadType != undefined &&\n this.options.payloadType !== rtp.header.payloadType &&\n this.options.clearInvalidPTPacket\n ) {\n rtp.clear();\n return;\n }\n\n this.write({ rtp });\n }\n\n stop() {\n this.controller.enqueue({ eol: true });\n }\n}\n"]}
@@ -1,48 +1,48 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
- import { BinaryLike } from "crypto";
4
- import Event from "rx.mini";
5
- import { RtpPacket } from "..";
6
2
  import { SupportedCodec } from "../container/webm";
7
- import { Output } from "./base";
8
- export interface FileIO {
9
- writeFile: (path: string, bin: BinaryLike) => Promise<void>;
10
- appendFile: (path: string, bin: BinaryLike) => Promise<void>;
11
- readFile: (path: string) => Promise<Buffer>;
3
+ import { DepacketizerOutput } from "./depacketizer";
4
+ export declare type WebmInput = DepacketizerOutput;
5
+ export declare type WebmOutput = {
6
+ saveToFile?: Buffer;
7
+ eol?: {
8
+ /**ms */
9
+ duration: number;
10
+ durationElement: Uint8Array;
11
+ };
12
+ };
13
+ export interface WebmOption {
14
+ /**ms */
15
+ duration?: number;
12
16
  }
13
- export declare class WebmOutput implements Output {
14
- private writer;
15
- path: string;
17
+ export declare class WebmBase {
16
18
  tracks: {
17
19
  width?: number;
18
20
  height?: number;
19
21
  kind: "audio" | "video";
20
22
  codec: SupportedCodec;
21
23
  clockRate: number;
22
- payloadType: number;
23
24
  trackNumber: number;
24
25
  }[];
26
+ private output;
27
+ private options;
25
28
  private builder;
26
- private queue;
27
29
  private relativeTimestamp;
28
30
  private timestamps;
29
- private disposer?;
30
31
  private cuePoints;
31
32
  private position;
32
33
  stopped: boolean;
33
- constructor(writer: FileIO, path: string, tracks: {
34
+ constructor(tracks: {
34
35
  width?: number;
35
36
  height?: number;
36
37
  kind: "audio" | "video";
37
38
  codec: SupportedCodec;
38
39
  clockRate: number;
39
- payloadType: number;
40
40
  trackNumber: number;
41
- }[], streams?: {
42
- rtpStream?: Event<[RtpPacket]>;
43
- });
44
- private init;
45
- stop(insertDuration?: boolean): Promise<void>;
46
- pushRtpPackets(packets: RtpPacket[]): void;
47
- private onRtpPackets;
41
+ }[], output: (output: WebmOutput) => void, options?: WebmOption);
42
+ private processInput;
43
+ processAudioInput(input: WebmInput): void;
44
+ processVideoInput(input: WebmInput): void;
45
+ start(): void;
46
+ private onFrameReceived;
47
+ private stop;
48
48
  }
@@ -1,15 +1,19 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebmOutput = void 0;
4
- const src_1 = require("../../../common/src");
5
- const codec_1 = require("../codec");
6
+ exports.WebmBase = void 0;
7
+ const debug_1 = __importDefault(require("debug"));
8
+ const __1 = require("..");
6
9
  const webm_1 = require("../container/webm");
7
- class WebmOutput {
8
- constructor(writer, path, tracks, streams) {
9
- this.writer = writer;
10
- this.path = path;
10
+ const sourcePath = `werift-rtp : packages/rtp/src/processor_v2/webmLive.ts`;
11
+ const log = (0, debug_1.default)(sourcePath);
12
+ class WebmBase {
13
+ constructor(tracks, output, options = {}) {
11
14
  this.tracks = tracks;
12
- this.queue = new src_1.PromiseQueue();
15
+ this.output = output;
16
+ this.options = options;
13
17
  this.relativeTimestamp = 0;
14
18
  this.timestamps = {};
15
19
  this.cuePoints = [];
@@ -17,122 +21,107 @@ class WebmOutput {
17
21
  this.stopped = false;
18
22
  this.builder = new webm_1.WEBMBuilder(tracks);
19
23
  tracks.forEach((t) => {
20
- this.timestamps[t.payloadType] = new TimestampManager(t.clockRate);
24
+ this.timestamps[t.trackNumber] = new ClusterTimestamp(t.clockRate);
21
25
  });
22
- this.queue.push(() => this.init());
23
- if (streams?.rtpStream) {
24
- const { unSubscribe } = streams.rtpStream.subscribe((packet) => {
25
- this.pushRtpPackets([packet]);
26
- });
27
- this.disposer = unSubscribe;
26
+ }
27
+ processInput(input, trackNumber) {
28
+ if (this.stopped)
29
+ return;
30
+ if (!input.frame) {
31
+ if (input.eol) {
32
+ this.stop();
33
+ }
34
+ return;
35
+ }
36
+ this.onFrameReceived({ ...input.frame, trackNumber });
37
+ }
38
+ processAudioInput(input) {
39
+ const track = this.tracks.find((t) => t.kind === "audio");
40
+ if (track) {
41
+ this.processInput(input, track.trackNumber);
42
+ }
43
+ }
44
+ processVideoInput(input) {
45
+ const track = this.tracks.find((t) => t.kind === "video");
46
+ if (track) {
47
+ this.processInput(input, track.trackNumber);
28
48
  }
29
49
  }
30
- async init() {
50
+ start() {
31
51
  const staticPart = Buffer.concat([
32
52
  this.builder.ebmlHeader,
33
- this.builder.createSegment(),
53
+ this.builder.createSegment(this.options.duration),
34
54
  ]);
35
- await this.writer.writeFile(this.path, staticPart);
55
+ this.output({ saveToFile: staticPart });
36
56
  this.position += staticPart.length;
37
57
  const video = this.tracks.find((t) => t.kind === "video");
38
58
  if (video) {
39
59
  this.cuePoints.push(new CuePoint(this.builder, video.trackNumber, 0.0, this.position));
40
60
  }
41
- const cluster = this.builder.createCluster(0.0);
42
- await this.writer.appendFile(this.path, cluster);
43
- this.position += cluster.length;
44
61
  }
45
- async stop(insertDuration = true) {
46
- this.stopped = true;
47
- if (this.disposer) {
48
- this.disposer();
49
- }
50
- if (!insertDuration) {
51
- return;
52
- }
53
- const originStaticPartOffset = Buffer.concat([
54
- this.builder.ebmlHeader,
55
- this.builder.createSegment(),
56
- ]).length;
57
- const clusters = (await this.writer.readFile(this.path)).slice(originStaticPartOffset);
58
- const latestTimestamp = Object.values(this.timestamps).sort((a, b) => a.relativeTimestamp - b.relativeTimestamp)[0].relativeTimestamp;
59
- const duration = this.relativeTimestamp + latestTimestamp;
60
- const staticPart = Buffer.concat([
61
- this.builder.ebmlHeader,
62
- this.builder.createSegment(duration),
63
- ]);
64
- // durationを挿入したことによるギャップの解消
65
- const staticPartGap = staticPart.length - originStaticPartOffset;
66
- this.cuePoints.forEach((c) => {
67
- c.position += staticPartGap;
68
- });
69
- let cuesSize = 0;
70
- let cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));
71
- // cuesの最終的なサイズを再帰的に求める
72
- while (cuesSize !== cues.length) {
73
- cuesSize = cues.length;
74
- this.cuePoints.forEach((cue) => {
75
- cue.cuesLength += cuesSize;
76
- });
77
- cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));
78
- }
79
- await this.writer.writeFile(this.path, staticPart);
80
- await this.writer.appendFile(this.path, cues);
81
- await this.writer.appendFile(this.path, clusters);
82
- }
83
- pushRtpPackets(packets) {
84
- if (this.stopped)
85
- return;
86
- this.queue.push(() => this.onRtpPackets(packets));
87
- }
88
- async onRtpPackets(packets) {
89
- const track = this.tracks.find((t) => t.payloadType === packets[0].header.payloadType);
62
+ onFrameReceived(frame) {
63
+ const track = this.tracks.find((t) => t.trackNumber === frame.trackNumber);
90
64
  if (!track) {
91
65
  return;
92
66
  }
93
- const timestampManager = this.timestamps[track.payloadType];
94
- const { data, isKeyframe } = (0, codec_1.dePacketizeRtpPackets)(track.codec, packets);
95
- const tailTimestamp = packets.slice(-1)[0].header.timestamp;
96
- timestampManager.update(tailTimestamp);
97
- if ((track.kind === "video" &&
98
- timestampManager.relativeTimestamp > 0 &&
99
- isKeyframe) ||
100
- timestampManager.relativeTimestamp > MaxSinged16Int) {
101
- this.relativeTimestamp += timestampManager.relativeTimestamp;
67
+ const timestampManager = this.timestamps[track.trackNumber];
68
+ let elapsed = timestampManager.update(frame.timestamp);
69
+ if ((track.kind === "video" && frame.isKeyframe) ||
70
+ elapsed > MaxSinged16Int) {
71
+ this.relativeTimestamp += elapsed;
102
72
  const cluster = this.builder.createCluster(this.relativeTimestamp);
103
- await this.writer.appendFile(this.path, cluster);
104
- this.cuePoints.push(new CuePoint(this.builder, track.trackNumber, this.relativeTimestamp, this.position));
73
+ this.output({ saveToFile: Buffer.from(cluster) });
74
+ if (elapsed !== 0) {
75
+ this.cuePoints.push(new CuePoint(this.builder, track.trackNumber, this.relativeTimestamp, this.position));
76
+ }
105
77
  this.position += cluster.length;
106
78
  Object.values(this.timestamps).forEach((t) => t.reset());
79
+ elapsed = timestampManager.update(frame.timestamp);
107
80
  }
108
- const block = this.builder.createSimpleBlock(data, isKeyframe, track.trackNumber, timestampManager.relativeTimestamp);
109
- await this.writer.appendFile(this.path, block);
81
+ const block = this.builder.createSimpleBlock(frame.data, frame.isKeyframe, track.trackNumber, elapsed);
82
+ this.output({ saveToFile: block });
110
83
  this.position += block.length;
111
84
  const [cuePoint] = this.cuePoints.slice(-1);
112
85
  if (cuePoint) {
113
86
  cuePoint.blockNumber++;
114
87
  }
115
88
  }
89
+ stop() {
90
+ if (this.stopped) {
91
+ return;
92
+ }
93
+ this.stopped = true;
94
+ log("stop");
95
+ const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));
96
+ this.output({ saveToFile: Buffer.from(cues) });
97
+ const latestTimestamp = Object.values(this.timestamps).sort((a, b) => a.elapsed - b.elapsed)[0].elapsed;
98
+ const duration = this.relativeTimestamp + latestTimestamp;
99
+ const durationElement = this.builder.createDuration(duration);
100
+ this.output({ eol: { duration, durationElement } });
101
+ }
116
102
  }
117
- exports.WebmOutput = WebmOutput;
118
- class TimestampManager {
103
+ exports.WebmBase = WebmBase;
104
+ class ClusterTimestamp {
119
105
  constructor(clockRate) {
120
106
  this.clockRate = clockRate;
121
- this.relativeTimestamp = 0;
107
+ this.elapsed = 0;
122
108
  }
123
109
  reset() {
124
110
  this.baseTimestamp = undefined;
125
- this.relativeTimestamp = 0;
126
111
  }
127
- update(tailTimestamp) {
112
+ update(timestamp) {
128
113
  if (this.baseTimestamp == undefined) {
129
- this.baseTimestamp = tailTimestamp;
114
+ this.baseTimestamp = timestamp;
115
+ }
116
+ const rotate = Math.abs(timestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;
117
+ if (rotate) {
118
+ log("rotate", { baseTimestamp: this.baseTimestamp, timestamp });
130
119
  }
131
- const rotate = Math.abs(tailTimestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;
132
120
  const elapsed = rotate
133
- ? tailTimestamp + Max32Uint - this.baseTimestamp
134
- : tailTimestamp - this.baseTimestamp;
135
- this.relativeTimestamp = (0, src_1.int)((elapsed / this.clockRate) * 1000);
121
+ ? timestamp + Max32Uint - this.baseTimestamp
122
+ : timestamp - this.baseTimestamp;
123
+ this.elapsed = (0, __1.int)((elapsed / this.clockRate) * 1000);
124
+ return this.elapsed;
136
125
  }
137
126
  }
138
127
  class CuePoint {
@@ -1 +1 @@
1
- {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import { BinaryLike } from \"crypto\";\nimport Event from \"rx.mini\";\n\nimport { int, PromiseQueue } from \"../../../common/src\";\nimport { RtpPacket } from \"..\";\nimport { dePacketizeRtpPackets } from \"../codec\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { Output } from \"./base\";\n\nexport interface FileIO {\n writeFile: (path: string, bin: BinaryLike) => Promise<void>;\n appendFile: (path: string, bin: BinaryLike) => Promise<void>;\n readFile: (path: string) => Promise<Buffer>;\n}\n\nexport class WebmOutput implements Output {\n private builder: WEBMBuilder;\n private queue = new PromiseQueue();\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: TimestampManager } = {};\n private disposer?: () => void;\n private cuePoints: CuePoint[] = [];\n private position = 0;\n stopped = false;\n\n constructor(\n private writer: FileIO,\n public path: string,\n public tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n payloadType: number;\n trackNumber: number;\n }[],\n streams?: {\n rtpStream?: Event<[RtpPacket]>;\n }\n ) {\n this.builder = new WEBMBuilder(tracks);\n\n tracks.forEach((t) => {\n this.timestamps[t.payloadType] = new TimestampManager(t.clockRate);\n });\n\n this.queue.push(() => this.init());\n\n if (streams?.rtpStream) {\n const { unSubscribe } = streams.rtpStream.subscribe((packet) => {\n this.pushRtpPackets([packet]);\n });\n this.disposer = unSubscribe;\n }\n }\n\n private async init() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(),\n ]);\n await this.writer.writeFile(this.path, staticPart);\n this.position += staticPart.length;\n\n const video = this.tracks.find((t) => t.kind === \"video\");\n if (video) {\n this.cuePoints.push(\n new CuePoint(this.builder, video.trackNumber, 0.0, this.position)\n );\n }\n\n const cluster = this.builder.createCluster(0.0);\n await this.writer.appendFile(this.path, cluster);\n this.position += cluster.length;\n }\n\n async stop(insertDuration = true) {\n this.stopped = true;\n if (this.disposer) {\n this.disposer();\n }\n\n if (!insertDuration) {\n return;\n }\n\n const originStaticPartOffset = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(),\n ]).length;\n const clusters = (await this.writer.readFile(this.path)).slice(\n originStaticPartOffset\n );\n\n const latestTimestamp = Object.values(this.timestamps).sort(\n (a, b) => a.relativeTimestamp - b.relativeTimestamp\n )[0].relativeTimestamp;\n const duration = this.relativeTimestamp + latestTimestamp;\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(duration),\n ]);\n // durationを挿入したことによるギャップの解消\n const staticPartGap = staticPart.length - originStaticPartOffset;\n this.cuePoints.forEach((c) => {\n c.position += staticPartGap;\n });\n\n let cuesSize = 0;\n let cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n // cuesの最終的なサイズを再帰的に求める\n while (cuesSize !== cues.length) {\n cuesSize = cues.length;\n this.cuePoints.forEach((cue) => {\n cue.cuesLength += cuesSize;\n });\n cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n }\n\n await this.writer.writeFile(this.path, staticPart);\n await this.writer.appendFile(this.path, cues);\n await this.writer.appendFile(this.path, clusters);\n }\n\n pushRtpPackets(packets: RtpPacket[]) {\n if (this.stopped) return;\n this.queue.push(() => this.onRtpPackets(packets));\n }\n\n private async onRtpPackets(packets: RtpPacket[]) {\n const track = this.tracks.find(\n (t) => t.payloadType === packets[0].header.payloadType\n );\n if (!track) {\n return;\n }\n\n const timestampManager = this.timestamps[track.payloadType];\n\n const { data, isKeyframe } = dePacketizeRtpPackets(track.codec, packets);\n\n const tailTimestamp = packets.slice(-1)[0].header.timestamp;\n timestampManager.update(tailTimestamp);\n\n if (\n (track.kind === \"video\" &&\n timestampManager.relativeTimestamp > 0 &&\n isKeyframe) ||\n timestampManager.relativeTimestamp > MaxSinged16Int\n ) {\n this.relativeTimestamp += timestampManager.relativeTimestamp;\n\n const cluster = this.builder.createCluster(this.relativeTimestamp);\n await this.writer.appendFile(this.path, cluster);\n this.cuePoints.push(\n new CuePoint(\n this.builder,\n track.trackNumber,\n this.relativeTimestamp,\n this.position\n )\n );\n this.position += cluster.length;\n Object.values(this.timestamps).forEach((t) => t.reset());\n }\n\n const block = this.builder.createSimpleBlock(\n data,\n isKeyframe,\n track.trackNumber,\n timestampManager.relativeTimestamp\n );\n await this.writer.appendFile(this.path, block);\n this.position += block.length;\n const [cuePoint] = this.cuePoints.slice(-1);\n if (cuePoint) {\n cuePoint.blockNumber++;\n }\n }\n}\n\nclass TimestampManager {\n private baseTimestamp?: number;\n relativeTimestamp = 0;\n\n constructor(public clockRate: number) {}\n\n reset() {\n this.baseTimestamp = undefined;\n this.relativeTimestamp = 0;\n }\n\n update(tailTimestamp: number) {\n if (this.baseTimestamp == undefined) {\n this.baseTimestamp = tailTimestamp;\n }\n const rotate =\n Math.abs(tailTimestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;\n\n const elapsed = rotate\n ? tailTimestamp + Max32Uint - this.baseTimestamp\n : tailTimestamp - this.baseTimestamp;\n\n this.relativeTimestamp = int((elapsed / this.clockRate) * 1000);\n }\n}\n\nclass CuePoint {\n /**\n * cuesの後のclusterのあるべき位置\n * cuesはclusterの前に挿入される\n */\n cuesLength = 0;\n blockNumber = 0;\n\n constructor(\n private readonly builder: WEBMBuilder,\n private readonly trackNumber: number,\n private readonly relativeTimestamp: number,\n public position: number\n ) {}\n\n build() {\n return this.builder.createCuePoint(\n this.relativeTimestamp,\n this.trackNumber,\n this.position - 48 + this.cuesLength,\n this.blockNumber\n );\n }\n}\n\n/**4294967295 */\nconst Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nconst MaxSinged16Int = (0x01 << 16) / 2 - 1;\n"]}
1
+ {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { int } from \"..\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { DepacketizerOutput } from \"./depacketizer\";\n\nconst sourcePath = `werift-rtp : packages/rtp/src/processor_v2/webmLive.ts`;\nconst log = debug(sourcePath);\n\nexport type WebmInput = DepacketizerOutput;\n\nexport type WebmOutput = {\n saveToFile?: Buffer;\n eol?: {\n /**ms */\n duration: number;\n durationElement: Uint8Array;\n };\n};\n\nexport interface WebmOption {\n /**ms */\n duration?: number;\n}\n\nexport class WebmBase {\n private builder: WEBMBuilder;\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: ClusterTimestamp } = {};\n private cuePoints: CuePoint[] = [];\n private position = 0;\n stopped = false;\n\n constructor(\n public tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n trackNumber: number;\n }[],\n private output: (output: WebmOutput) => void,\n private options: WebmOption = {}\n ) {\n this.builder = new WEBMBuilder(tracks);\n\n tracks.forEach((t) => {\n this.timestamps[t.trackNumber] = new ClusterTimestamp(t.clockRate);\n });\n }\n\n private processInput(input: WebmInput, trackNumber: number) {\n if (this.stopped) return;\n if (!input.frame) {\n if (input.eol) {\n this.stop();\n }\n return;\n }\n\n this.onFrameReceived({ ...input.frame, trackNumber });\n }\n\n processAudioInput(input: WebmInput) {\n const track = this.tracks.find((t) => t.kind === \"audio\");\n if (track) {\n this.processInput(input, track.trackNumber);\n }\n }\n\n processVideoInput(input: WebmInput) {\n const track = this.tracks.find((t) => t.kind === \"video\");\n if (track) {\n this.processInput(input, track.trackNumber);\n }\n }\n\n start() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(this.options.duration),\n ]);\n this.output({ saveToFile: staticPart });\n this.position += staticPart.length;\n\n const video = this.tracks.find((t) => t.kind === \"video\");\n if (video) {\n this.cuePoints.push(\n new CuePoint(this.builder, video.trackNumber, 0.0, this.position)\n );\n }\n }\n\n private onFrameReceived(frame: WebmInput[\"frame\"] & { trackNumber: number }) {\n const track = this.tracks.find((t) => t.trackNumber === frame.trackNumber);\n if (!track) {\n return;\n }\n\n const timestampManager = this.timestamps[track.trackNumber];\n let elapsed = timestampManager.update(frame.timestamp);\n\n if (\n (track.kind === \"video\" && frame.isKeyframe) ||\n elapsed > MaxSinged16Int\n ) {\n this.relativeTimestamp += elapsed;\n\n const cluster = this.builder.createCluster(this.relativeTimestamp);\n this.output({ saveToFile: Buffer.from(cluster) });\n\n if (elapsed !== 0) {\n this.cuePoints.push(\n new CuePoint(\n this.builder,\n track.trackNumber,\n this.relativeTimestamp,\n this.position\n )\n );\n }\n this.position += cluster.length;\n Object.values(this.timestamps).forEach((t) => t.reset());\n elapsed = timestampManager.update(frame.timestamp);\n }\n\n const block = this.builder.createSimpleBlock(\n frame.data,\n frame.isKeyframe,\n track.trackNumber,\n elapsed\n );\n this.output({ saveToFile: block });\n this.position += block.length;\n const [cuePoint] = this.cuePoints.slice(-1);\n if (cuePoint) {\n cuePoint.blockNumber++;\n }\n }\n\n private stop() {\n if (this.stopped) {\n return;\n }\n this.stopped = true;\n\n log(\"stop\");\n\n const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n this.output({ saveToFile: Buffer.from(cues) });\n\n const latestTimestamp = Object.values(this.timestamps).sort(\n (a, b) => a.elapsed - b.elapsed\n )[0].elapsed;\n const duration = this.relativeTimestamp + latestTimestamp;\n const durationElement = this.builder.createDuration(duration);\n this.output({ eol: { duration, durationElement } });\n }\n}\n\nclass ClusterTimestamp {\n baseTimestamp?: number;\n elapsed = 0;\n\n constructor(public clockRate: number) {}\n\n reset() {\n this.baseTimestamp = undefined;\n }\n\n 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 if (rotate) {\n log(\"rotate\", { baseTimestamp: this.baseTimestamp, timestamp });\n }\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\nclass CuePoint {\n /**\n * cuesの後のclusterのあるべき位置\n * cuesはclusterの前に挿入される\n */\n cuesLength = 0;\n blockNumber = 0;\n\n constructor(\n private readonly builder: WEBMBuilder,\n private readonly trackNumber: number,\n private readonly relativeTimestamp: number,\n public position: number\n ) {}\n\n build() {\n return this.builder.createCuePoint(\n this.relativeTimestamp,\n this.trackNumber,\n this.position - 48 + this.cuesLength,\n this.blockNumber\n );\n }\n}\n\n/**4294967295 */\nconst Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nconst MaxSinged16Int = (0x01 << 16) / 2 - 1;\n"]}
@@ -0,0 +1,31 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { ReadableStream, WritableStream } from "stream/web";
4
+ import { SupportedCodec } from "../container/webm";
5
+ import { WebmBase, WebmInput } from "./webm";
6
+ export declare type WebmLiveOutput = {
7
+ saveToFile?: Buffer;
8
+ eol?: {
9
+ /**ms */
10
+ duration: number;
11
+ durationElement: Uint8Array;
12
+ };
13
+ };
14
+ export interface WebmLiveOption {
15
+ /**ms */
16
+ duration?: number;
17
+ }
18
+ export declare class WebmStream extends WebmBase {
19
+ audioStream: WritableStream<WebmInput>;
20
+ videoStream: WritableStream<WebmInput>;
21
+ webmStream: ReadableStream<WebmLiveOutput>;
22
+ private controller;
23
+ constructor(tracks: {
24
+ width?: number;
25
+ height?: number;
26
+ kind: "audio" | "video";
27
+ codec: SupportedCodec;
28
+ clockRate: number;
29
+ trackNumber: number;
30
+ }[], options?: WebmLiveOption);
31
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebmStream = void 0;
4
+ const web_1 = require("stream/web");
5
+ const webm_1 = require("./webm");
6
+ class WebmStream extends webm_1.WebmBase {
7
+ constructor(tracks, options = {}) {
8
+ super(tracks, (output) => {
9
+ this.controller.enqueue(output);
10
+ }, options);
11
+ const audioTrack = tracks.find((t) => t.kind === "audio");
12
+ if (audioTrack) {
13
+ this.audioStream = new web_1.WritableStream({
14
+ write: (input) => {
15
+ this.processAudioInput(input);
16
+ },
17
+ });
18
+ }
19
+ const videoTrack = tracks.find((t) => t.kind === "video");
20
+ if (videoTrack) {
21
+ this.videoStream = new web_1.WritableStream({
22
+ write: (input) => {
23
+ this.processVideoInput(input);
24
+ },
25
+ });
26
+ }
27
+ this.webmStream = new web_1.ReadableStream({
28
+ start: (controller) => {
29
+ this.controller = controller;
30
+ },
31
+ });
32
+ this.start();
33
+ }
34
+ }
35
+ exports.WebmStream = WebmStream;
36
+ //# sourceMappingURL=webmStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webmStream.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webmStream.ts"],"names":[],"mappings":";;;AAAA,oCAIoB;AAGpB,iCAA6C;AAgB7C,MAAa,UAAW,SAAQ,eAAQ;IAMtC,YACE,MAOG,EACH,UAA0B,EAAE;QAE5B,KAAK,CACH,MAAM,EACN,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,EACD,OAAO,CACR,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC1D,IAAI,UAAU,EAAE;YACd,IAAI,CAAC,WAAW,GAAG,IAAI,oBAAc,CAAC;gBACpC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;aACF,CAAC,CAAC;SACJ;QAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC1D,IAAI,UAAU,EAAE;YACd,IAAI,CAAC,WAAW,GAAG,IAAI,oBAAc,CAAC;gBACpC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;aACF,CAAC,CAAC;SACJ;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,oBAAc,CAAiB;YACnD,KAAK,EAAE,CAAC,UAAU,EAAE,EAAE;gBACpB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC/B,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACF;AAnDD,gCAmDC","sourcesContent":["import {\n ReadableStream,\n ReadableStreamController,\n WritableStream,\n} from \"stream/web\";\n\nimport { SupportedCodec } from \"../container/webm\";\nimport { WebmBase, WebmInput } from \"./webm\";\n\nexport type WebmLiveOutput = {\n saveToFile?: Buffer;\n eol?: {\n /**ms */\n duration: number;\n durationElement: Uint8Array;\n };\n};\n\nexport interface WebmLiveOption {\n /**ms */\n duration?: number;\n}\n\nexport class WebmStream extends WebmBase {\n audioStream!: WritableStream<WebmInput>;\n videoStream!: WritableStream<WebmInput>;\n webmStream: ReadableStream<WebmLiveOutput>;\n private controller!: ReadableStreamController<WebmLiveOutput>;\n\n constructor(\n tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n trackNumber: number;\n }[],\n options: WebmLiveOption = {}\n ) {\n super(\n tracks,\n (output) => {\n this.controller.enqueue(output);\n },\n options\n );\n\n const audioTrack = tracks.find((t) => t.kind === \"audio\");\n if (audioTrack) {\n this.audioStream = new WritableStream({\n write: (input) => {\n this.processAudioInput(input);\n },\n });\n }\n\n const videoTrack = tracks.find((t) => t.kind === \"video\");\n if (videoTrack) {\n this.videoStream = new WritableStream({\n write: (input) => {\n this.processVideoInput(input);\n },\n });\n }\n\n this.webmStream = new ReadableStream<WebmLiveOutput>({\n start: (controller) => {\n this.controller = controller;\n },\n });\n\n this.start();\n }\n}\n"]}
@@ -40,5 +40,6 @@ export declare class RtpPacket {
40
40
  clone(): RtpPacket;
41
41
  serialize(): Buffer;
42
42
  static deSerialize(buf: Buffer): RtpPacket;
43
+ clear(): void;
43
44
  }
44
45
  export {};
@@ -263,6 +263,9 @@ class RtpPacket {
263
263
  const p = new RtpPacket(header, buf.subarray(header.payloadOffset, buf.length - header.paddingSize));
264
264
  return p;
265
265
  }
266
+ clear() {
267
+ this.payload = null;
268
+ }
266
269
  }
267
270
  exports.RtpPacket = RtpPacket;
268
271
  //# sourceMappingURL=rtp.js.map