werift 0.18.3 → 0.18.4

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 (97) hide show
  1. package/lib/dtls/src/flight/server/flight2.js +1 -1
  2. package/lib/dtls/src/flight/server/flight2.js.map +1 -1
  3. package/lib/rtp/src/container/ebml/ebml.d.ts +5 -6
  4. package/lib/rtp/src/container/ebml/ebml.js +14 -13
  5. package/lib/rtp/src/container/ebml/ebml.js.map +1 -1
  6. package/lib/rtp/src/container/ebml/typedArrayUtils.d.ts +3 -4
  7. package/lib/rtp/src/container/ebml/typedArrayUtils.js +9 -10
  8. package/lib/rtp/src/container/ebml/typedArrayUtils.js.map +1 -1
  9. package/lib/rtp/src/container/index.d.ts +2 -0
  10. package/lib/rtp/src/{processor/source → container}/index.js +2 -3
  11. package/lib/rtp/src/container/index.js.map +1 -0
  12. package/lib/rtp/src/helper.d.ts +4 -0
  13. package/lib/rtp/src/helper.js +14 -1
  14. package/lib/rtp/src/helper.js.map +1 -1
  15. package/lib/rtp/src/index.d.ts +2 -0
  16. package/lib/rtp/src/index.js +2 -0
  17. package/lib/rtp/src/index.js.map +1 -1
  18. package/lib/rtp/src/processor/depacketizer.d.ts +1 -1
  19. package/lib/rtp/src/processor/depacketizer.js +16 -9
  20. package/lib/rtp/src/processor/depacketizer.js.map +1 -1
  21. package/lib/rtp/src/processor/depacketizerCallback.d.ts +14 -6
  22. package/lib/rtp/src/processor/depacketizerCallback.js +2 -35
  23. package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -1
  24. package/lib/rtp/src/processor/dtx.d.ts +1 -0
  25. package/lib/rtp/src/processor/dtx.js +10 -1
  26. package/lib/rtp/src/processor/dtx.js.map +1 -1
  27. package/lib/rtp/src/processor/dtxCallback.d.ts +14 -5
  28. package/lib/rtp/src/processor/dtxCallback.js +2 -35
  29. package/lib/rtp/src/processor/dtxCallback.js.map +1 -1
  30. package/lib/rtp/src/processor/index.d.ts +3 -1
  31. package/lib/rtp/src/processor/index.js +3 -1
  32. package/lib/rtp/src/processor/index.js.map +1 -1
  33. package/lib/rtp/src/processor/interface.d.ts +17 -0
  34. package/lib/rtp/src/processor/interface.js +57 -0
  35. package/lib/rtp/src/processor/interface.js.map +1 -1
  36. package/lib/rtp/src/processor/jitterBuffer.d.ts +1 -2
  37. package/lib/rtp/src/processor/jitterBuffer.js +3 -1
  38. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  39. package/lib/rtp/src/processor/jitterBufferCallback.d.ts +14 -5
  40. package/lib/rtp/src/processor/jitterBufferCallback.js +2 -35
  41. package/lib/rtp/src/processor/jitterBufferCallback.js.map +1 -1
  42. package/lib/rtp/src/processor/jitterBufferTransformer.d.ts +1 -1
  43. package/lib/rtp/src/processor/lipsync.d.ts +19 -8
  44. package/lib/rtp/src/processor/lipsync.js +131 -83
  45. package/lib/rtp/src/processor/lipsync.js.map +1 -1
  46. package/lib/rtp/src/processor/lipsyncCallback.d.ts +8 -5
  47. package/lib/rtp/src/processor/lipsyncCallback.js +39 -4
  48. package/lib/rtp/src/processor/lipsyncCallback.js.map +1 -1
  49. package/lib/rtp/src/processor/mute.d.ts +17 -4
  50. package/lib/rtp/src/processor/mute.js +121 -40
  51. package/lib/rtp/src/processor/mute.js.map +1 -1
  52. package/lib/rtp/src/processor/muteCallback.d.ts +5 -2
  53. package/lib/rtp/src/processor/muteCallback.js +23 -7
  54. package/lib/rtp/src/processor/muteCallback.js.map +1 -1
  55. package/lib/rtp/src/processor/nack.d.ts +6 -6
  56. package/lib/rtp/src/processor/nack.js +23 -17
  57. package/lib/rtp/src/processor/nack.js.map +1 -1
  58. package/lib/rtp/src/processor/nackHandlerCallback.d.ts +14 -7
  59. package/lib/rtp/src/processor/nackHandlerCallback.js +2 -29
  60. package/lib/rtp/src/processor/nackHandlerCallback.js.map +1 -1
  61. package/lib/rtp/src/processor/ntpTime.d.ts +7 -7
  62. package/lib/rtp/src/processor/ntpTime.js +27 -29
  63. package/lib/rtp/src/processor/ntpTime.js.map +1 -1
  64. package/lib/rtp/src/processor/ntpTimeCallback.d.ts +13 -4
  65. package/lib/rtp/src/processor/ntpTimeCallback.js +2 -29
  66. package/lib/rtp/src/processor/ntpTimeCallback.js.map +1 -1
  67. package/lib/rtp/src/processor/rtcpCallback.d.ts +18 -0
  68. package/lib/rtp/src/processor/{source/rtcpCallback.js → rtcpCallback.js} +25 -3
  69. package/lib/rtp/src/processor/rtcpCallback.js.map +1 -0
  70. package/lib/rtp/src/processor/rtpCallback.d.ts +28 -0
  71. package/lib/rtp/src/processor/rtpCallback.js +125 -0
  72. package/lib/rtp/src/processor/rtpCallback.js.map +1 -0
  73. package/lib/rtp/src/processor/{source/rtpStream.d.ts → rtpStream.d.ts} +1 -1
  74. package/lib/rtp/src/processor/{source/rtpStream.js → rtpStream.js} +1 -1
  75. package/lib/rtp/src/processor/rtpStream.js.map +1 -0
  76. package/lib/rtp/src/processor/rtpTimeCallback.d.ts +13 -5
  77. package/lib/rtp/src/processor/rtpTimeCallback.js +2 -29
  78. package/lib/rtp/src/processor/rtpTimeCallback.js.map +1 -1
  79. package/lib/rtp/src/processor/webm.d.ts +8 -4
  80. package/lib/rtp/src/processor/webm.js +41 -8
  81. package/lib/rtp/src/processor/webm.js.map +1 -1
  82. package/lib/rtp/src/processor/webmCallback.d.ts +6 -5
  83. package/lib/rtp/src/processor/webmCallback.js +21 -7
  84. package/lib/rtp/src/processor/webmCallback.js.map +1 -1
  85. package/lib/webrtc/src/nonstandard/userMedia.d.ts +32 -23
  86. package/lib/webrtc/src/nonstandard/userMedia.js +49 -131
  87. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  88. package/package.json +1 -1
  89. package/src/nonstandard/userMedia.ts +69 -75
  90. package/lib/rtp/src/processor/source/index.d.ts +0 -3
  91. package/lib/rtp/src/processor/source/index.js.map +0 -1
  92. package/lib/rtp/src/processor/source/rtcpCallback.d.ts +0 -13
  93. package/lib/rtp/src/processor/source/rtcpCallback.js.map +0 -1
  94. package/lib/rtp/src/processor/source/rtpCallback.d.ts +0 -19
  95. package/lib/rtp/src/processor/source/rtpCallback.js +0 -62
  96. package/lib/rtp/src/processor/source/rtpCallback.js.map +0 -1
  97. package/lib/rtp/src/processor/source/rtpStream.js.map +0 -1
@@ -1,8 +1,11 @@
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
6
  exports.replaceSegmentSize = exports.SegmentSizePosition = exports.DurationPosition = exports.MaxSinged16Int = exports.Max32Uint = exports.WebmBase = void 0;
4
- const ebml_1 = require("../container/ebml");
5
- const webm_1 = require("../container/webm");
7
+ const rx_mini_1 = __importDefault(require("rx.mini"));
8
+ const __1 = require("..");
6
9
  class WebmBase {
7
10
  constructor(tracks, output, options = {}) {
8
11
  Object.defineProperty(this, "tracks", {
@@ -59,6 +62,7 @@ class WebmBase {
59
62
  writable: true,
60
63
  value: 0
61
64
  });
65
+ /**ms */
62
66
  Object.defineProperty(this, "elapsed", {
63
67
  enumerable: true,
64
68
  configurable: true,
@@ -95,6 +99,12 @@ class WebmBase {
95
99
  writable: true,
96
100
  value: {}
97
101
  });
102
+ Object.defineProperty(this, "onStopped", {
103
+ enumerable: true,
104
+ configurable: true,
105
+ writable: true,
106
+ value: new rx_mini_1.default()
107
+ });
98
108
  Object.defineProperty(this, "processAudioInput", {
99
109
  enumerable: true,
100
110
  configurable: true,
@@ -115,6 +125,9 @@ class WebmBase {
115
125
  if (input.frame?.isKeyframe) {
116
126
  this.videoKeyframeReceived = true;
117
127
  }
128
+ if (!this.videoKeyframeReceived && input?.frame?.isKeyframe !== true) {
129
+ return;
130
+ }
118
131
  const track = this.tracks.find((t) => t.kind === "video");
119
132
  if (track) {
120
133
  this.internalStats["processVideoInput"] = new Date().toISOString();
@@ -122,17 +135,24 @@ class WebmBase {
122
135
  }
123
136
  }
124
137
  });
125
- this.builder = new webm_1.WEBMBuilder(tracks, options.encryptionKey);
138
+ this.builder = new __1.WEBMBuilder(tracks, options.encryptionKey);
126
139
  tracks.forEach((t) => {
127
140
  this.timestamps[t.trackNumber] = new ClusterTimestamp();
128
141
  });
129
142
  }
130
143
  toJSON() {
131
- return { ...this.internalStats };
144
+ return {
145
+ ...this.internalStats,
146
+ videoKeyframeReceived: this.videoKeyframeReceived,
147
+ videoStopped: this.videoStopped,
148
+ audioStopped: this.audioStopped,
149
+ stopped: this.stopped,
150
+ };
132
151
  }
133
152
  processInput(input, trackNumber) {
134
- if (this.stopped)
153
+ if (this.stopped) {
135
154
  return;
155
+ }
136
156
  const track = this.tracks.find((t) => t.trackNumber === trackNumber);
137
157
  if (!track) {
138
158
  throw new Error("track not found");
@@ -155,7 +175,6 @@ class WebmBase {
155
175
  }
156
176
  }
157
177
  else if (input.eol) {
158
- this.internalStats["input.eol"] = new Date().toISOString();
159
178
  this.stop();
160
179
  }
161
180
  return;
@@ -254,6 +273,16 @@ class WebmBase {
254
273
  };
255
274
  return;
256
275
  }
276
+ if (elapsed > this.elapsed + 1000) {
277
+ const key = "maybe_packetLost-" + trackNumber;
278
+ this.internalStats[key] = {
279
+ elapsed,
280
+ present: this.elapsed,
281
+ trackNumber,
282
+ timestamp: new Date().toISOString(),
283
+ count: (this.internalStats[key]?.count ?? 0) + 1,
284
+ };
285
+ }
257
286
  this.elapsed = elapsed;
258
287
  const block = this.builder.createSimpleBlock(frame.data, frame.isKeyframe, trackNumber, elapsed);
259
288
  this.internalStats["createSimpleBlock_trackNumber" + trackNumber] =
@@ -269,7 +298,10 @@ class WebmBase {
269
298
  if (this.stopped) {
270
299
  return;
271
300
  }
301
+ this.videoStopped = true;
302
+ this.audioStopped = true;
272
303
  this.stopped = true;
304
+ this.internalStats["stopped"] = new Date().toISOString();
273
305
  const latestTimestamp = Object.values(this.timestamps)
274
306
  .sort((a, b) => a.elapsed - b.elapsed)
275
307
  .reverse()[0].elapsed;
@@ -290,6 +322,7 @@ class WebmBase {
290
322
  this.cuePoints = [];
291
323
  this.internalStats = {};
292
324
  this.output = undefined;
325
+ this.onStopped.execute();
293
326
  }
294
327
  }
295
328
  exports.WebmBase = WebmBase;
@@ -387,13 +420,13 @@ exports.SegmentSizePosition = 40;
387
420
  function replaceSegmentSize(totalFileSize) {
388
421
  const bodySize = totalFileSize - exports.SegmentSizePosition;
389
422
  const resize = [
390
- ...(0, ebml_1.vintEncode)((0, ebml_1.numberToByteArray)(bodySize, (0, ebml_1.getEBMLByteLength)(bodySize))),
423
+ ...(0, __1.vintEncode)((0, __1.numberToByteArray)(bodySize, (0, __1.getEBMLByteLength)(bodySize))),
391
424
  ];
392
425
  const todoFill = 8 - resize.length - 2;
393
426
  if (todoFill > 0) {
394
427
  resize.push(0xec);
395
428
  if (todoFill > 1) {
396
- const voidSize = (0, ebml_1.vintEncode)((0, ebml_1.numberToByteArray)(todoFill, (0, ebml_1.getEBMLByteLength)(todoFill)));
429
+ const voidSize = (0, __1.vintEncode)((0, __1.numberToByteArray)(todoFill, (0, __1.getEBMLByteLength)(todoFill)));
397
430
  [...voidSize].forEach((i) => resize.push(i));
398
431
  }
399
432
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getEBMLByteLength,\n numberToByteArray,\n vintEncode,\n} from \"../container/ebml\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { AVProcessor } from \"./interface\";\n\nexport type WebmInput = {\n frame?: {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n };\n eol?: boolean;\n};\n\nexport interface WebmOutput {\n saveToFile?: Buffer;\n kind?: \"initial\" | \"cluster\" | \"block\" | \"cuePoints\";\n /**ms */\n previousDuration?: number;\n eol?: {\n /**ms */\n duration: number;\n durationElement: Uint8Array;\n header: Buffer;\n };\n}\n\nexport interface WebmOption {\n /**ms */\n duration?: number;\n encryptionKey?: Buffer;\n strictTimestamp?: boolean;\n}\n\nexport class WebmBase implements AVProcessor<WebmInput> {\n private builder: WEBMBuilder;\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: ClusterTimestamp } = {};\n private cuePoints: CuePoint[] = [];\n private position = 0;\n private clusterCounts = 0;\n elapsed?: number;\n audioStopped = false;\n videoStopped = false;\n stopped = false;\n videoKeyframeReceived = false;\n internalStats = {};\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, options.encryptionKey);\n\n tracks.forEach((t) => {\n this.timestamps[t.trackNumber] = new ClusterTimestamp();\n });\n }\n\n toJSON(): Record<string, any> {\n return { ...this.internalStats };\n }\n\n private processInput(input: WebmInput, trackNumber: number) {\n if (this.stopped) return;\n\n const track = this.tracks.find((t) => t.trackNumber === trackNumber);\n if (!track) {\n throw new Error(\"track not found\");\n }\n\n if (!input.frame) {\n if (this.tracks.length === 2) {\n if (track.kind === \"audio\") {\n this.audioStopped = true;\n this.internalStats[\"audioStopped\"] = new Date().toISOString();\n if (this.videoStopped) {\n this.stop();\n }\n } else {\n this.videoStopped = true;\n this.internalStats[\"videoStopped\"] = new Date().toISOString();\n if (this.audioStopped) {\n this.stop();\n }\n }\n } else if (input.eol) {\n this.internalStats[\"input.eol\"] = new Date().toISOString();\n this.stop();\n }\n\n return;\n }\n\n if (track.kind === \"audio\") {\n this.audioStopped = false;\n } else {\n this.videoStopped = false;\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.internalStats[\"processAudioInput\"] = new Date().toISOString();\n this.processInput(input, track.trackNumber);\n }\n };\n\n processVideoInput = (input: WebmInput) => {\n if (input.frame?.isKeyframe) {\n this.videoKeyframeReceived = true;\n }\n\n const track = this.tracks.find((t) => t.kind === \"video\");\n if (track) {\n this.internalStats[\"processVideoInput\"] = new Date().toISOString();\n this.processInput(input, track.trackNumber);\n }\n };\n\n protected start() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(this.options.duration),\n ]);\n this.output({ saveToFile: staticPart, kind: \"initial\" });\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 this.internalStats[\"onFrameReceived_trackNumber\" + frame.trackNumber] =\n new Date().toISOString();\n this.internalStats[\"onFrameReceived_count\"] =\n (this.internalStats[\"onFrameReceived_count\"] ?? 0) + 1;\n\n const timestampManager = this.timestamps[track.trackNumber];\n if (timestampManager.baseTime == undefined) {\n for (const t of Object.values(this.timestamps)) {\n t.baseTime = frame.time;\n }\n }\n\n // clusterの経過時間 ms\n let elapsed = timestampManager.update(frame.time);\n\n if (this.clusterCounts === 0) {\n this.createCluster(0.0, 0);\n } else if (\n (track.kind === \"video\" && frame.isKeyframe) ||\n // simpleBlockのタイムスタンプはsigned 16bitだから\n elapsed > MaxSinged16Int\n ) {\n this.relativeTimestamp += elapsed;\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.createCluster(this.relativeTimestamp, elapsed);\n Object.values(this.timestamps).forEach((t) => t.shift(elapsed));\n elapsed = timestampManager.update(frame.time);\n }\n }\n\n if (elapsed >= 0) {\n this.createSimpleBlock({\n frame,\n trackNumber: track.trackNumber,\n elapsed,\n });\n } else {\n this.internalStats[\"delayed_frame\"] = {\n elapsed,\n trackNumber: track.trackNumber,\n timestamp: new Date().toISOString(),\n count: (this.internalStats[\"delayed_frame\"]?.count ?? 0) + 1,\n };\n }\n }\n\n private createCluster(\n timestamp: number,\n /**ms */\n duration: number\n ) {\n const cluster = this.builder.createCluster(timestamp);\n this.clusterCounts++;\n this.output({\n saveToFile: Buffer.from(cluster),\n kind: \"cluster\",\n previousDuration: duration,\n });\n this.position += cluster.length;\n this.elapsed = undefined;\n }\n\n private createSimpleBlock({\n frame,\n trackNumber,\n elapsed,\n }: {\n frame: NonNullable<WebmInput[\"frame\"]>;\n trackNumber: number;\n elapsed: number;\n }) {\n if (this.elapsed == undefined) {\n this.elapsed = elapsed;\n }\n if (elapsed < this.elapsed && this.options.strictTimestamp) {\n this.internalStats[\"previous_timestamp\"] = {\n elapsed,\n present: this.elapsed,\n trackNumber,\n timestamp: new Date().toISOString(),\n count: (this.internalStats[\"previous_timestamp\"]?.count ?? 0) + 1,\n };\n return;\n }\n this.elapsed = elapsed;\n\n const block = this.builder.createSimpleBlock(\n frame.data,\n frame.isKeyframe,\n trackNumber,\n elapsed\n );\n\n this.internalStats[\"createSimpleBlock_trackNumber\" + trackNumber] =\n new Date().toISOString();\n\n this.output({ saveToFile: block, kind: \"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 const latestTimestamp = Object.values(this.timestamps)\n .sort((a, b) => a.elapsed - b.elapsed)\n .reverse()[0].elapsed;\n const duration = this.relativeTimestamp + latestTimestamp;\n\n const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n this.output({\n saveToFile: Buffer.from(cues),\n kind: \"cuePoints\",\n previousDuration: duration,\n });\n\n const durationElement = this.builder.createDuration(duration);\n const header = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(duration),\n ]);\n\n this.output({ eol: { duration, durationElement, header } });\n\n this.timestamps = {};\n this.cuePoints = [];\n this.internalStats = {};\n this.output = undefined as any;\n }\n}\n\nclass ClusterTimestamp {\n /**ms */\n baseTime?: number;\n /**ms */\n elapsed = 0;\n private offset = 0;\n\n shift(\n /**ms */\n elapsed: number\n ) {\n this.offset += elapsed;\n }\n\n update(\n /**ms */\n time: number\n ) {\n if (this.baseTime == undefined) {\n throw new Error(\"baseTime not exist\");\n }\n\n this.elapsed = time - this.baseTime - this.offset;\n\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 */\nexport const Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nexport const MaxSinged16Int = (0x01 << 16) / 2 - 1;\n\nexport const DurationPosition = 83;\n\nexport const SegmentSizePosition = 40;\n\nexport function replaceSegmentSize(totalFileSize: number) {\n const bodySize = totalFileSize - SegmentSizePosition;\n const resize = [\n ...vintEncode(numberToByteArray(bodySize, getEBMLByteLength(bodySize))),\n ];\n const todoFill = 8 - resize.length - 2;\n if (todoFill > 0) {\n resize.push(0xec);\n if (todoFill > 1) {\n const voidSize = vintEncode(\n numberToByteArray(todoFill, getEBMLByteLength(todoFill))\n );\n [...voidSize].forEach((i) => resize.push(i));\n }\n }\n return Buffer.from(resize);\n}\n"]}
1
+ {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import Event from \"rx.mini\";\n\nimport {\n getEBMLByteLength,\n numberToByteArray,\n SupportedCodec,\n vintEncode,\n WEBMBuilder,\n} from \"..\";\nimport { AVProcessor } from \"./interface\";\n\nexport type WebmInput = {\n frame?: {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n };\n eol?: boolean;\n};\n\nexport interface WebmOutput {\n saveToFile?: Buffer;\n kind?: \"initial\" | \"cluster\" | \"block\" | \"cuePoints\";\n /**ms */\n previousDuration?: number;\n eol?: {\n /**ms */\n duration: number;\n durationElement: Uint8Array;\n header: Buffer;\n };\n}\n\nexport interface WebmOption {\n /**ms */\n duration?: number;\n encryptionKey?: Buffer;\n strictTimestamp?: boolean;\n}\n\nexport class WebmBase implements AVProcessor<WebmInput> {\n private builder: WEBMBuilder;\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: ClusterTimestamp } = {};\n private cuePoints: CuePoint[] = [];\n private position = 0;\n private clusterCounts = 0;\n /**ms */\n elapsed?: number;\n audioStopped = false;\n videoStopped = false;\n stopped = false;\n videoKeyframeReceived = false;\n internalStats = {};\n onStopped = new Event();\n\n constructor(\n public tracks: {\n width?: number;\n height?: number;\n kind: MediaKind;\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, options.encryptionKey);\n\n tracks.forEach((t) => {\n this.timestamps[t.trackNumber] = new ClusterTimestamp();\n });\n }\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n videoKeyframeReceived: this.videoKeyframeReceived,\n videoStopped: this.videoStopped,\n audioStopped: this.audioStopped,\n stopped: this.stopped,\n };\n }\n\n private processInput(input: WebmInput, trackNumber: number) {\n if (this.stopped) {\n return;\n }\n\n const track = this.tracks.find((t) => t.trackNumber === trackNumber);\n if (!track) {\n throw new Error(\"track not found\");\n }\n\n if (!input.frame) {\n if (this.tracks.length === 2) {\n if (track.kind === \"audio\") {\n this.audioStopped = true;\n this.internalStats[\"audioStopped\"] = new Date().toISOString();\n if (this.videoStopped) {\n this.stop();\n }\n } else {\n this.videoStopped = true;\n this.internalStats[\"videoStopped\"] = new Date().toISOString();\n if (this.audioStopped) {\n this.stop();\n }\n }\n } else if (input.eol) {\n this.stop();\n }\n\n return;\n }\n\n if (track.kind === \"audio\") {\n this.audioStopped = false;\n } else {\n this.videoStopped = false;\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.internalStats[\"processAudioInput\"] = new Date().toISOString();\n this.processInput(input, track.trackNumber);\n }\n };\n\n processVideoInput = (input: WebmInput) => {\n if (input.frame?.isKeyframe) {\n this.videoKeyframeReceived = true;\n }\n if (!this.videoKeyframeReceived && input?.frame?.isKeyframe !== true) {\n return;\n }\n\n const track = this.tracks.find((t) => t.kind === \"video\");\n if (track) {\n this.internalStats[\"processVideoInput\"] = new Date().toISOString();\n this.processInput(input, track.trackNumber);\n }\n };\n\n protected start() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(this.options.duration),\n ]);\n this.output({ saveToFile: staticPart, kind: \"initial\" });\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 this.internalStats[\"onFrameReceived_trackNumber\" + frame.trackNumber] =\n new Date().toISOString();\n this.internalStats[\"onFrameReceived_count\"] =\n (this.internalStats[\"onFrameReceived_count\"] ?? 0) + 1;\n\n const timestampManager = this.timestamps[track.trackNumber];\n if (timestampManager.baseTime == undefined) {\n for (const t of Object.values(this.timestamps)) {\n t.baseTime = frame.time;\n }\n }\n\n // clusterの経過時間 ms\n let elapsed = timestampManager.update(frame.time);\n\n if (this.clusterCounts === 0) {\n this.createCluster(0.0, 0);\n } else if (\n (track.kind === \"video\" && frame.isKeyframe) ||\n // simpleBlockのタイムスタンプはsigned 16bitだから\n elapsed > MaxSinged16Int\n ) {\n this.relativeTimestamp += elapsed;\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.createCluster(this.relativeTimestamp, elapsed);\n Object.values(this.timestamps).forEach((t) => t.shift(elapsed));\n elapsed = timestampManager.update(frame.time);\n }\n }\n\n if (elapsed >= 0) {\n this.createSimpleBlock({\n frame,\n trackNumber: track.trackNumber,\n elapsed,\n });\n } else {\n this.internalStats[\"delayed_frame\"] = {\n elapsed,\n trackNumber: track.trackNumber,\n timestamp: new Date().toISOString(),\n count: (this.internalStats[\"delayed_frame\"]?.count ?? 0) + 1,\n };\n }\n }\n\n private createCluster(\n timestamp: number,\n /**ms */\n duration: number\n ) {\n const cluster = this.builder.createCluster(timestamp);\n this.clusterCounts++;\n this.output({\n saveToFile: Buffer.from(cluster),\n kind: \"cluster\",\n previousDuration: duration,\n });\n this.position += cluster.length;\n this.elapsed = undefined;\n }\n\n private createSimpleBlock({\n frame,\n trackNumber,\n elapsed,\n }: {\n frame: NonNullable<WebmInput[\"frame\"]>;\n trackNumber: number;\n elapsed: number;\n }) {\n if (this.elapsed == undefined) {\n this.elapsed = elapsed;\n }\n if (elapsed < this.elapsed && this.options.strictTimestamp) {\n this.internalStats[\"previous_timestamp\"] = {\n elapsed,\n present: this.elapsed,\n trackNumber,\n timestamp: new Date().toISOString(),\n count: (this.internalStats[\"previous_timestamp\"]?.count ?? 0) + 1,\n };\n return;\n }\n if (elapsed > this.elapsed + 1000) {\n const key = \"maybe_packetLost-\" + trackNumber;\n this.internalStats[key] = {\n elapsed,\n present: this.elapsed,\n trackNumber,\n timestamp: new Date().toISOString(),\n count: (this.internalStats[key]?.count ?? 0) + 1,\n };\n }\n this.elapsed = elapsed;\n\n const block = this.builder.createSimpleBlock(\n frame.data,\n frame.isKeyframe,\n trackNumber,\n elapsed\n );\n\n this.internalStats[\"createSimpleBlock_trackNumber\" + trackNumber] =\n new Date().toISOString();\n\n this.output({ saveToFile: block, kind: \"block\" });\n this.position += block.length;\n const [cuePoint] = this.cuePoints.slice(-1);\n if (cuePoint) {\n cuePoint.blockNumber++;\n }\n }\n\n stop() {\n if (this.stopped) {\n return;\n }\n this.videoStopped = true;\n this.audioStopped = true;\n this.stopped = true;\n this.internalStats[\"stopped\"] = new Date().toISOString();\n\n const latestTimestamp = Object.values(this.timestamps)\n .sort((a, b) => a.elapsed - b.elapsed)\n .reverse()[0].elapsed;\n const duration = this.relativeTimestamp + latestTimestamp;\n\n const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n this.output({\n saveToFile: Buffer.from(cues),\n kind: \"cuePoints\",\n previousDuration: duration,\n });\n\n const durationElement = this.builder.createDuration(duration);\n const header = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(duration),\n ]);\n\n this.output({ eol: { duration, durationElement, header } });\n\n this.timestamps = {};\n this.cuePoints = [];\n this.internalStats = {};\n this.output = undefined as any;\n\n this.onStopped.execute();\n }\n}\n\nclass ClusterTimestamp {\n /**ms */\n baseTime?: number;\n /**ms */\n elapsed = 0;\n private offset = 0;\n\n shift(\n /**ms */\n elapsed: number\n ) {\n this.offset += elapsed;\n }\n\n update(\n /**ms */\n time: number\n ) {\n if (this.baseTime == undefined) {\n throw new Error(\"baseTime not exist\");\n }\n\n this.elapsed = time - this.baseTime - this.offset;\n\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 */\nexport const Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nexport const MaxSinged16Int = (0x01 << 16) / 2 - 1;\n\nexport const DurationPosition = 83;\n\nexport const SegmentSizePosition = 40;\n\nexport function replaceSegmentSize(totalFileSize: number) {\n const bodySize = totalFileSize - SegmentSizePosition;\n const resize = [\n ...vintEncode(numberToByteArray(bodySize, getEBMLByteLength(bodySize))),\n ];\n const todoFill = 8 - resize.length - 2;\n if (todoFill > 0) {\n resize.push(0xec);\n if (todoFill > 1) {\n const voidSize = vintEncode(\n numberToByteArray(todoFill, getEBMLByteLength(todoFill))\n );\n [...voidSize].forEach((i) => resize.push(i));\n }\n }\n return Buffer.from(resize);\n}\n\nexport type MediaKind = \"video\" | \"audio\";\n"]}
@@ -1,7 +1,7 @@
1
- import { SupportedCodec } from "../container/webm";
2
- import { WebmBase, WebmOption, WebmOutput } from "./webm";
1
+ import { SupportedCodec } from "..";
2
+ import { WebmBase, WebmInput, WebmOption, WebmOutput } from "./webm";
3
3
  export declare class WebmCallback extends WebmBase {
4
- private cb;
4
+ private cb?;
5
5
  private queue;
6
6
  constructor(tracks: {
7
7
  width?: number;
@@ -12,7 +12,8 @@ export declare class WebmCallback extends WebmBase {
12
12
  trackNumber: number;
13
13
  }[], options?: WebmOption);
14
14
  pipe: (cb: (input: WebmOutput) => Promise<void>) => void;
15
- inputAudio: (input: import("./webm").WebmInput) => void;
16
- inputVideo: (input: import("./webm").WebmInput) => void;
15
+ inputAudio: (input: WebmInput) => void;
16
+ inputVideo: (input: WebmInput) => void;
17
+ destroy: () => void;
17
18
  }
18
19
  export declare const saveToFileSystem: (path: string) => (value: WebmOutput) => Promise<void>;
@@ -2,13 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.saveToFileSystem = exports.WebmCallback = void 0;
4
4
  const promises_1 = require("fs/promises");
5
- const src_1 = require("../../../common/src");
5
+ const __1 = require("..");
6
6
  const webm_1 = require("./webm");
7
7
  class WebmCallback extends webm_1.WebmBase {
8
8
  constructor(tracks, options = {}) {
9
- super(tracks, (output) => {
10
- if (this.cb) {
11
- this.queue.push(() => this.cb(output));
9
+ super(tracks, async (output) => {
10
+ const cb = this.cb;
11
+ if (cb) {
12
+ await this.queue.push(() => cb(output));
12
13
  }
13
14
  }, options);
14
15
  Object.defineProperty(this, "cb", {
@@ -21,7 +22,7 @@ class WebmCallback extends webm_1.WebmBase {
21
22
  enumerable: true,
22
23
  configurable: true,
23
24
  writable: true,
24
- value: new src_1.PromiseQueue()
25
+ value: new __1.PromiseQueue()
25
26
  });
26
27
  Object.defineProperty(this, "pipe", {
27
28
  enumerable: true,
@@ -36,13 +37,26 @@ class WebmCallback extends webm_1.WebmBase {
36
37
  enumerable: true,
37
38
  configurable: true,
38
39
  writable: true,
39
- value: this.processAudioInput
40
+ value: (input) => {
41
+ this.processAudioInput(input);
42
+ }
40
43
  });
41
44
  Object.defineProperty(this, "inputVideo", {
42
45
  enumerable: true,
43
46
  configurable: true,
44
47
  writable: true,
45
- value: this.processVideoInput
48
+ value: (input) => {
49
+ this.processVideoInput(input);
50
+ }
51
+ });
52
+ Object.defineProperty(this, "destroy", {
53
+ enumerable: true,
54
+ configurable: true,
55
+ writable: true,
56
+ value: () => {
57
+ this.cb = undefined;
58
+ this.queue.cancel();
59
+ }
46
60
  });
47
61
  }
48
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webmCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webmCallback.ts"],"names":[],"mappings":";;;AAAA,0CAAqD;AAErD,6CAAmD;AAEnD,iCAOgB;AAEhB,MAAa,YAAa,SAAQ,eAAQ;IAGxC,YACE,MAOG,EACH,UAAsB,EAAE;QAExB,KAAK,CACH,MAAM,EACN,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,IAAI,CAAC,EAAE,EAAE;gBACX,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;aACxC;QACH,CAAC,EACD,OAAO,CACR,CAAC;QArBJ;;;;;WAAkD;QAClD;;;;mBAAgB,IAAI,kBAAY,EAAE;WAAC;QAuBnC;;;;mBAAO,CAAC,EAAwC,EAAE,EAAE;gBAClD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,CAAC;WAAC;QAEF;;;;mBAAa,IAAI,CAAC,iBAAiB;WAAC;QACpC;;;;mBAAa,IAAI,CAAC,iBAAiB;WAAC;IARpC,CAAC;CASF;AAhCD,oCAgCC;AAEM,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,EAAE,KAAiB,EAAE,EAAE;IAC5E,IAAI,KAAK,CAAC,UAAU,EAAE;QACpB,MAAM,IAAA,qBAAU,EAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;KAC1C;SAAM,IAAI,KAAK,CAAC,GAAG,EAAE;QACpB,MAAM,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEvC,eAAe;QACf,MAAM,OAAO,CAAC,KAAK,CACjB,eAAe,EACf,CAAC,EACD,eAAe,CAAC,MAAM,EACtB,uBAAgB,CACjB,CAAC;QAEF,WAAW;QACX,MAAM,IAAI,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAA,yBAAkB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,0BAAmB,CAAC,CAAC;QAEnE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;KACvB;AACH,CAAC,CAAC;AAtBW,QAAA,gBAAgB,oBAsB3B","sourcesContent":["import { appendFile, open, stat } from \"fs/promises\";\n\nimport { PromiseQueue } from \"../../../common/src\";\nimport { SupportedCodec } from \"../container/webm\";\nimport {\n DurationPosition,\n replaceSegmentSize,\n SegmentSizePosition,\n WebmBase,\n WebmOption,\n WebmOutput,\n} from \"./webm\";\n\nexport class WebmCallback extends WebmBase {\n private cb!: (input: WebmOutput) => Promise<void>;\n private queue = new PromiseQueue();\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: WebmOption = {}\n ) {\n super(\n tracks,\n (output) => {\n if (this.cb) {\n this.queue.push(() => this.cb(output));\n }\n },\n options\n );\n }\n\n pipe = (cb: (input: WebmOutput) => Promise<void>) => {\n this.cb = cb;\n this.start();\n };\n\n inputAudio = this.processAudioInput;\n inputVideo = this.processVideoInput;\n}\n\nexport const saveToFileSystem = (path: string) => async (value: WebmOutput) => {\n if (value.saveToFile) {\n await appendFile(path, value.saveToFile);\n } else if (value.eol) {\n const { durationElement } = value.eol;\n const handler = await open(path, \"r+\");\n\n // set duration\n await handler.write(\n durationElement,\n 0,\n durationElement.length,\n DurationPosition\n );\n\n // set size\n const meta = await stat(path);\n const resize = replaceSegmentSize(meta.size);\n await handler.write(resize, 0, resize.length, SegmentSizePosition);\n\n await handler.close();\n }\n};\n"]}
1
+ {"version":3,"file":"webmCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webmCallback.ts"],"names":[],"mappings":";;;AAAA,0CAAqD;AAErD,0BAAkD;AAClD,iCAQgB;AAEhB,MAAa,YAAa,SAAQ,eAAQ;IAGxC,YACE,MAOG,EACH,UAAsB,EAAE;QAExB,KAAK,CACH,MAAM,EACN,KAAK,EAAE,MAAM,EAAE,EAAE;YACf,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,EAAE,EAAE;gBACN,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;aACzC;QACH,CAAC,EACD,OAAO,CACR,CAAC;QAtBJ;;;;;WAAkD;QAClD;;;;mBAAgB,IAAI,gBAAY,EAAE;WAAC;QAwBnC;;;;mBAAO,CAAC,EAAwC,EAAE,EAAE;gBAClD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,CAAC;WAAC;QAEF;;;;mBAAa,CAAC,KAAgB,EAAE,EAAE;gBAChC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;WAAC;QACF;;;;mBAAa,CAAC,KAAgB,EAAE,EAAE;gBAChC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;WAAC;QAEF;;;;mBAAU,GAAG,EAAE;gBACb,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC;gBACpB,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACtB,CAAC;WAAC;IAjBF,CAAC;CAkBF;AA1CD,oCA0CC;AAEM,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,EAAE,KAAiB,EAAE,EAAE;IAC5E,IAAI,KAAK,CAAC,UAAU,EAAE;QACpB,MAAM,IAAA,qBAAU,EAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;KAC1C;SAAM,IAAI,KAAK,CAAC,GAAG,EAAE;QACpB,MAAM,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEvC,eAAe;QACf,MAAM,OAAO,CAAC,KAAK,CACjB,eAAe,EACf,CAAC,EACD,eAAe,CAAC,MAAM,EACtB,uBAAgB,CACjB,CAAC;QAEF,WAAW;QACX,MAAM,IAAI,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAA,yBAAkB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,0BAAmB,CAAC,CAAC;QAEnE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;KACvB;AACH,CAAC,CAAC;AAtBW,QAAA,gBAAgB,oBAsB3B","sourcesContent":["import { appendFile, open, stat } from \"fs/promises\";\n\nimport { PromiseQueue, SupportedCodec } from \"..\";\nimport {\n DurationPosition,\n replaceSegmentSize,\n SegmentSizePosition,\n WebmBase,\n WebmInput,\n WebmOption,\n WebmOutput,\n} from \"./webm\";\n\nexport class WebmCallback extends WebmBase {\n private cb?: (input: WebmOutput) => Promise<void>;\n private queue = new PromiseQueue();\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: WebmOption = {}\n ) {\n super(\n tracks,\n async (output) => {\n const cb = this.cb;\n if (cb) {\n await this.queue.push(() => cb(output));\n }\n },\n options\n );\n }\n\n pipe = (cb: (input: WebmOutput) => Promise<void>) => {\n this.cb = cb;\n this.start();\n };\n\n inputAudio = (input: WebmInput) => {\n this.processAudioInput(input);\n };\n inputVideo = (input: WebmInput) => {\n this.processVideoInput(input);\n };\n\n destroy = () => {\n this.cb = undefined;\n this.queue.cancel();\n };\n}\n\nexport const saveToFileSystem = (path: string) => async (value: WebmOutput) => {\n if (value.saveToFile) {\n await appendFile(path, value.saveToFile);\n } else if (value.eol) {\n const { durationElement } = value.eol;\n const handler = await open(path, \"r+\");\n\n // set duration\n await handler.write(\n durationElement,\n 0,\n durationElement.length,\n DurationPosition\n );\n\n // set size\n const meta = await stat(path);\n const resize = replaceSegmentSize(meta.size);\n await handler.write(resize, 0, resize.length, SegmentSizePosition);\n\n await handler.close();\n }\n};\n"]}
@@ -1,32 +1,41 @@
1
+ /// <reference types="node" />
2
+ import { ChildProcess } from "child_process";
1
3
  import { MediaStreamTrack } from "../media/track";
2
- export declare const getUserMedia: (path: string, loop?: boolean) => Promise<MediaPlayerMp4 | MediaPlayerWebm>;
3
- export declare class MediaPlayerMp4 {
4
- private videoPort;
5
- private audioPort;
6
- private path;
7
- private loop?;
8
- private streamId;
4
+ export declare const getUserMedia: ({ path, loop, width, height, }: {
5
+ path: string;
6
+ loop?: boolean | undefined;
7
+ width?: number | undefined;
8
+ height?: number | undefined;
9
+ }) => Promise<MediaPlayerMp4 | MediaPlayerWebm>;
10
+ declare abstract class MediaPlayer {
11
+ protected props: {
12
+ videoPort: number;
13
+ audioPort: number;
14
+ path: string;
15
+ loop?: boolean;
16
+ width?: number;
17
+ height?: number;
18
+ };
19
+ protected streamId: string;
9
20
  audio: MediaStreamTrack;
10
21
  video: MediaStreamTrack;
11
- private process;
22
+ protected process: ChildProcess;
12
23
  stopped: boolean;
13
- constructor(videoPort: number, audioPort: number, path: string, loop?: boolean | undefined);
24
+ constructor(props: {
25
+ videoPort: number;
26
+ audioPort: number;
27
+ path: string;
28
+ loop?: boolean;
29
+ width?: number;
30
+ height?: number;
31
+ });
14
32
  private setupTrack;
15
- start(): Promise<void>;
16
33
  stop(): void;
17
34
  }
18
- export declare class MediaPlayerWebm {
19
- private videoPort;
20
- private audioPort;
21
- private path;
22
- private loop?;
23
- private streamId;
24
- audio: MediaStreamTrack;
25
- video: MediaStreamTrack;
26
- private process;
27
- stopped: boolean;
28
- constructor(videoPort: number, audioPort: number, path: string, loop?: boolean | undefined);
29
- private setupTrack;
35
+ export declare class MediaPlayerMp4 extends MediaPlayer {
36
+ start(): Promise<void>;
37
+ }
38
+ export declare class MediaPlayerWebm extends MediaPlayer {
30
39
  start(): Promise<void>;
31
- stop(): void;
32
40
  }
41
+ export {};
@@ -8,42 +8,38 @@ const uuid_1 = require("uuid");
8
8
  const src_1 = require("../../../common/src");
9
9
  const src_2 = require("../../../rtp/src");
10
10
  const track_1 = require("../media/track");
11
- const getUserMedia = async (path, loop) => {
11
+ const getUserMedia = async ({ path, loop, width, height, }) => {
12
12
  const audioPort = await (0, src_1.randomPort)();
13
13
  const videoPort = await (0, src_1.randomPort)();
14
14
  if (path.endsWith(".mp4")) {
15
- return new MediaPlayerMp4(audioPort, videoPort, path, loop);
15
+ return new MediaPlayerMp4({
16
+ audioPort,
17
+ videoPort,
18
+ path,
19
+ loop,
20
+ width,
21
+ height,
22
+ });
16
23
  }
17
24
  else {
18
- return new MediaPlayerWebm(audioPort, videoPort, path, loop);
25
+ return new MediaPlayerWebm({
26
+ audioPort,
27
+ videoPort,
28
+ path,
29
+ loop,
30
+ width,
31
+ height,
32
+ });
19
33
  }
20
34
  };
21
35
  exports.getUserMedia = getUserMedia;
22
- class MediaPlayerMp4 {
23
- constructor(videoPort, audioPort, path, loop) {
24
- Object.defineProperty(this, "videoPort", {
36
+ class MediaPlayer {
37
+ constructor(props) {
38
+ Object.defineProperty(this, "props", {
25
39
  enumerable: true,
26
40
  configurable: true,
27
41
  writable: true,
28
- value: videoPort
29
- });
30
- Object.defineProperty(this, "audioPort", {
31
- enumerable: true,
32
- configurable: true,
33
- writable: true,
34
- value: audioPort
35
- });
36
- Object.defineProperty(this, "path", {
37
- enumerable: true,
38
- configurable: true,
39
- writable: true,
40
- value: path
41
- });
42
- Object.defineProperty(this, "loop", {
43
- enumerable: true,
44
- configurable: true,
45
- writable: true,
46
- value: loop
42
+ value: props
47
43
  });
48
44
  Object.defineProperty(this, "streamId", {
49
45
  enumerable: true,
@@ -97,22 +93,39 @@ class MediaPlayerMp4 {
97
93
  });
98
94
  }
99
95
  });
100
- this.setupTrack(audioPort, this.audio);
101
- this.setupTrack(videoPort, this.video);
96
+ this.setupTrack(props.audioPort, this.audio);
97
+ this.setupTrack(props.videoPort, this.video);
98
+ }
99
+ stop() {
100
+ this.stopped = true;
101
+ this.process.kill("SIGINT");
102
102
  }
103
+ }
104
+ class MediaPlayerMp4 extends MediaPlayer {
103
105
  async start() {
104
106
  let payloadType = 96;
105
107
  const run = async () => {
106
108
  if (payloadType > 100)
107
109
  payloadType = 96;
108
- const cmd = `gst-launch-1.0 filesrc location= ${this.path} ! \
110
+ let cmd = "";
111
+ if (this.props.width && this.props.height) {
112
+ cmd = `gst-launch-1.0 filesrc location= ${this.props.path} ! \
113
+ decodebin ! videoscale ! video/x-raw,width=${this.props.width},height=${this.props.height} ! x264enc ! \
114
+ h264parse ! rtph264pay config-interval=10 pt=${payloadType++} ! \
115
+ udpsink host=127.0.0.1 port=${this.props.videoPort}`;
116
+ }
117
+ else {
118
+ cmd = `gst-launch-1.0 filesrc location= ${this.props.path} ! \
109
119
  qtdemux name=d ! \
110
120
  queue ! h264parse ! rtph264pay config-interval=10 pt=${payloadType++} ! \
111
- udpsink host=127.0.0.1 port=${this.videoPort} d. ! \
121
+ udpsink host=127.0.0.1 port=${this.props.videoPort} d. ! \
112
122
  queue ! aacparse ! avdec_aac ! audioresample ! audioconvert ! opusenc ! rtpopuspay pt=${payloadType++} ! \
113
- udpsink host=127.0.0.1 port=${this.audioPort}`;
123
+ udpsink host=127.0.0.1 port=${this.props.audioPort}`;
124
+ }
125
+ console.log(cmd);
114
126
  this.process = (0, child_process_1.exec)(cmd);
115
- if (this.loop) {
127
+ this.process.on("error", (e) => console.error("gst error", e));
128
+ if (this.props.loop) {
116
129
  await new Promise((r) => this.process.on("close", r));
117
130
  if (!this.stopped) {
118
131
  run();
@@ -122,112 +135,21 @@ udpsink host=127.0.0.1 port=${this.audioPort}`;
122
135
  await (0, promises_1.setImmediate)();
123
136
  run();
124
137
  }
125
- stop() {
126
- this.stopped = true;
127
- this.process.kill("SIGINT");
128
- }
129
138
  }
130
139
  exports.MediaPlayerMp4 = MediaPlayerMp4;
131
- class MediaPlayerWebm {
132
- constructor(videoPort, audioPort, path, loop) {
133
- Object.defineProperty(this, "videoPort", {
134
- enumerable: true,
135
- configurable: true,
136
- writable: true,
137
- value: videoPort
138
- });
139
- Object.defineProperty(this, "audioPort", {
140
- enumerable: true,
141
- configurable: true,
142
- writable: true,
143
- value: audioPort
144
- });
145
- Object.defineProperty(this, "path", {
146
- enumerable: true,
147
- configurable: true,
148
- writable: true,
149
- value: path
150
- });
151
- Object.defineProperty(this, "loop", {
152
- enumerable: true,
153
- configurable: true,
154
- writable: true,
155
- value: loop
156
- });
157
- Object.defineProperty(this, "streamId", {
158
- enumerable: true,
159
- configurable: true,
160
- writable: true,
161
- value: (0, uuid_1.v4)()
162
- });
163
- Object.defineProperty(this, "audio", {
164
- enumerable: true,
165
- configurable: true,
166
- writable: true,
167
- value: new track_1.MediaStreamTrack({ kind: "audio", streamId: this.streamId })
168
- });
169
- Object.defineProperty(this, "video", {
170
- enumerable: true,
171
- configurable: true,
172
- writable: true,
173
- value: new track_1.MediaStreamTrack({ kind: "video", streamId: this.streamId })
174
- });
175
- Object.defineProperty(this, "process", {
176
- enumerable: true,
177
- configurable: true,
178
- writable: true,
179
- value: void 0
180
- });
181
- Object.defineProperty(this, "stopped", {
182
- enumerable: true,
183
- configurable: true,
184
- writable: true,
185
- value: false
186
- });
187
- Object.defineProperty(this, "setupTrack", {
188
- enumerable: true,
189
- configurable: true,
190
- writable: true,
191
- value: (port, track) => {
192
- let payloadType = 0;
193
- let latestTimestamp = 0;
194
- let timestampDiff = 0;
195
- const socket = (0, dgram_1.createSocket)("udp4");
196
- socket.bind(port);
197
- socket.on("message", async (buf) => {
198
- const rtp = src_2.RtpPacket.deSerialize(buf);
199
- if (!payloadType) {
200
- payloadType = rtp.header.payloadType;
201
- }
202
- // detect gStreamer restarted
203
- if (payloadType !== rtp.header.payloadType) {
204
- payloadType = rtp.header.payloadType;
205
- track.onSourceChanged.execute(rtp.header);
206
- timestampDiff = (0, src_1.uint32Add)(rtp.header.timestamp, -latestTimestamp);
207
- console.log({ timestampDiff });
208
- }
209
- latestTimestamp = rtp.header.timestamp;
210
- rtp.header.timestamp = (0, src_1.uint32Add)(rtp.header.timestamp, -timestampDiff);
211
- track.writeRtp(rtp.serialize());
212
- });
213
- }
214
- });
215
- this.setupTrack(audioPort, this.audio);
216
- this.setupTrack(videoPort, this.video);
217
- }
140
+ class MediaPlayerWebm extends MediaPlayer {
218
141
  async start() {
219
142
  let payloadType = 96;
220
143
  const run = async () => {
221
144
  if (payloadType > 100)
222
145
  payloadType = 96;
223
- const cmd = `gst-launch-1.0 filesrc location=${this.path} ! matroskademux name=d \
146
+ const cmd = `gst-launch-1.0 filesrc location=${this.props.path} ! matroskademux name=d \
224
147
  d.video_0 ! queue ! rtpvp8pay pt=${payloadType++} ! \
225
- udpsink host=127.0.0.1 port=${this.videoPort} \
148
+ udpsink host=127.0.0.1 port=${this.props.videoPort} \
226
149
  d.audio_0 ! queue ! rtpopuspay pt=${payloadType++} ! \
227
- udpsink host=127.0.0.1 port=${this.audioPort}`;
150
+ udpsink host=127.0.0.1 port=${this.props.audioPort}`;
228
151
  this.process = (0, child_process_1.exec)(cmd);
229
- console.log(cmd);
230
- if (this.loop) {
152
+ if (this.props.loop) {
231
153
  await new Promise((r) => this.process.on("close", r));
232
154
  if (!this.stopped) {
233
155
  run();
@@ -237,10 +159,6 @@ udpsink host=127.0.0.1 port=${this.audioPort}`;
237
159
  await (0, promises_1.setImmediate)();
238
160
  run();
239
161
  }
240
- stop() {
241
- this.stopped = true;
242
- this.process.kill("SIGINT");
243
- }
244
162
  }
245
163
  exports.MediaPlayerWebm = MediaPlayerWebm;
246
164
  //# sourceMappingURL=userMedia.js.map