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.
- package/lib/dtls/src/flight/server/flight2.js +1 -1
- package/lib/dtls/src/flight/server/flight2.js.map +1 -1
- package/lib/rtp/src/container/ebml/ebml.d.ts +5 -6
- package/lib/rtp/src/container/ebml/ebml.js +14 -13
- package/lib/rtp/src/container/ebml/ebml.js.map +1 -1
- package/lib/rtp/src/container/ebml/typedArrayUtils.d.ts +3 -4
- package/lib/rtp/src/container/ebml/typedArrayUtils.js +9 -10
- package/lib/rtp/src/container/ebml/typedArrayUtils.js.map +1 -1
- package/lib/rtp/src/container/index.d.ts +2 -0
- package/lib/rtp/src/{processor/source → container}/index.js +2 -3
- package/lib/rtp/src/container/index.js.map +1 -0
- package/lib/rtp/src/helper.d.ts +4 -0
- package/lib/rtp/src/helper.js +14 -1
- package/lib/rtp/src/helper.js.map +1 -1
- package/lib/rtp/src/index.d.ts +2 -0
- package/lib/rtp/src/index.js +2 -0
- package/lib/rtp/src/index.js.map +1 -1
- package/lib/rtp/src/processor/depacketizer.d.ts +1 -1
- package/lib/rtp/src/processor/depacketizer.js +16 -9
- package/lib/rtp/src/processor/depacketizer.js.map +1 -1
- package/lib/rtp/src/processor/depacketizerCallback.d.ts +14 -6
- package/lib/rtp/src/processor/depacketizerCallback.js +2 -35
- package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -1
- package/lib/rtp/src/processor/dtx.d.ts +1 -0
- package/lib/rtp/src/processor/dtx.js +10 -1
- package/lib/rtp/src/processor/dtx.js.map +1 -1
- package/lib/rtp/src/processor/dtxCallback.d.ts +14 -5
- package/lib/rtp/src/processor/dtxCallback.js +2 -35
- package/lib/rtp/src/processor/dtxCallback.js.map +1 -1
- package/lib/rtp/src/processor/index.d.ts +3 -1
- package/lib/rtp/src/processor/index.js +3 -1
- package/lib/rtp/src/processor/index.js.map +1 -1
- package/lib/rtp/src/processor/interface.d.ts +17 -0
- package/lib/rtp/src/processor/interface.js +57 -0
- package/lib/rtp/src/processor/interface.js.map +1 -1
- package/lib/rtp/src/processor/jitterBuffer.d.ts +1 -2
- package/lib/rtp/src/processor/jitterBuffer.js +3 -1
- package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
- package/lib/rtp/src/processor/jitterBufferCallback.d.ts +14 -5
- package/lib/rtp/src/processor/jitterBufferCallback.js +2 -35
- package/lib/rtp/src/processor/jitterBufferCallback.js.map +1 -1
- package/lib/rtp/src/processor/jitterBufferTransformer.d.ts +1 -1
- package/lib/rtp/src/processor/lipsync.d.ts +19 -8
- package/lib/rtp/src/processor/lipsync.js +131 -83
- package/lib/rtp/src/processor/lipsync.js.map +1 -1
- package/lib/rtp/src/processor/lipsyncCallback.d.ts +8 -5
- package/lib/rtp/src/processor/lipsyncCallback.js +39 -4
- package/lib/rtp/src/processor/lipsyncCallback.js.map +1 -1
- package/lib/rtp/src/processor/mute.d.ts +17 -4
- package/lib/rtp/src/processor/mute.js +121 -40
- package/lib/rtp/src/processor/mute.js.map +1 -1
- package/lib/rtp/src/processor/muteCallback.d.ts +5 -2
- package/lib/rtp/src/processor/muteCallback.js +23 -7
- package/lib/rtp/src/processor/muteCallback.js.map +1 -1
- package/lib/rtp/src/processor/nack.d.ts +6 -6
- package/lib/rtp/src/processor/nack.js +23 -17
- package/lib/rtp/src/processor/nack.js.map +1 -1
- package/lib/rtp/src/processor/nackHandlerCallback.d.ts +14 -7
- package/lib/rtp/src/processor/nackHandlerCallback.js +2 -29
- package/lib/rtp/src/processor/nackHandlerCallback.js.map +1 -1
- package/lib/rtp/src/processor/ntpTime.d.ts +7 -7
- package/lib/rtp/src/processor/ntpTime.js +27 -29
- package/lib/rtp/src/processor/ntpTime.js.map +1 -1
- package/lib/rtp/src/processor/ntpTimeCallback.d.ts +13 -4
- package/lib/rtp/src/processor/ntpTimeCallback.js +2 -29
- package/lib/rtp/src/processor/ntpTimeCallback.js.map +1 -1
- package/lib/rtp/src/processor/rtcpCallback.d.ts +18 -0
- package/lib/rtp/src/processor/{source/rtcpCallback.js → rtcpCallback.js} +25 -3
- package/lib/rtp/src/processor/rtcpCallback.js.map +1 -0
- package/lib/rtp/src/processor/rtpCallback.d.ts +28 -0
- package/lib/rtp/src/processor/rtpCallback.js +125 -0
- package/lib/rtp/src/processor/rtpCallback.js.map +1 -0
- package/lib/rtp/src/processor/{source/rtpStream.d.ts → rtpStream.d.ts} +1 -1
- package/lib/rtp/src/processor/{source/rtpStream.js → rtpStream.js} +1 -1
- package/lib/rtp/src/processor/rtpStream.js.map +1 -0
- package/lib/rtp/src/processor/rtpTimeCallback.d.ts +13 -5
- package/lib/rtp/src/processor/rtpTimeCallback.js +2 -29
- package/lib/rtp/src/processor/rtpTimeCallback.js.map +1 -1
- package/lib/rtp/src/processor/webm.d.ts +8 -4
- package/lib/rtp/src/processor/webm.js +41 -8
- package/lib/rtp/src/processor/webm.js.map +1 -1
- package/lib/rtp/src/processor/webmCallback.d.ts +6 -5
- package/lib/rtp/src/processor/webmCallback.js +21 -7
- package/lib/rtp/src/processor/webmCallback.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +32 -23
- package/lib/webrtc/src/nonstandard/userMedia.js +49 -131
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/package.json +1 -1
- package/src/nonstandard/userMedia.ts +69 -75
- package/lib/rtp/src/processor/source/index.d.ts +0 -3
- package/lib/rtp/src/processor/source/index.js.map +0 -1
- package/lib/rtp/src/processor/source/rtcpCallback.d.ts +0 -13
- package/lib/rtp/src/processor/source/rtcpCallback.js.map +0 -1
- package/lib/rtp/src/processor/source/rtpCallback.d.ts +0 -19
- package/lib/rtp/src/processor/source/rtpCallback.js +0 -62
- package/lib/rtp/src/processor/source/rtpCallback.js.map +0 -1
- 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
|
|
5
|
-
const
|
|
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
|
|
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 {
|
|
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,
|
|
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,
|
|
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":";;;;;;AAAA,sDAA4B;AAE5B,0BAMY;AAiCZ,MAAa,QAAQ;IAgBnB,YACS,MAOJ,EACK,MAAoC,EACpC,UAAsB,EAAE;;;;;mBATzB;;;;;;mBAQC;;;;;;mBACA;;QAzBV;;;;;WAA6B;QAC7B;;;;mBAA4B,CAAC;WAAC;QAC9B;;;;mBAAyD,EAAE;WAAC;QAC5D;;;;mBAAgC,EAAE;WAAC;QACnC;;;;mBAAmB,CAAC;WAAC;QACrB;;;;mBAAwB,CAAC;WAAC;QAC1B,QAAQ;QACR;;;;;WAAiB;QACjB;;;;mBAAe,KAAK;WAAC;QACrB;;;;mBAAe,KAAK;WAAC;QACrB;;;;mBAAU,KAAK;WAAC;QAChB;;;;mBAAwB,KAAK;WAAC;QAC9B;;;;mBAAgB,EAAE;WAAC;QACnB;;;;mBAAY,IAAI,iBAAK,EAAE;WAAC;QAwExB;;;;mBAAoB,CAAC,KAAgB,EAAE,EAAE;gBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;gBAC1D,IAAI,KAAK,EAAE;oBACT,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBACnE,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;iBAC7C;YACH,CAAC;WAAC;QAEF;;;;mBAAoB,CAAC,KAAgB,EAAE,EAAE;gBACvC,IAAI,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE;oBAC3B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;iBACnC;gBACD,IAAI,CAAC,IAAI,CAAC,qBAAqB,IAAI,KAAK,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,EAAE;oBACpE,OAAO;iBACR;gBAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;gBAC1D,IAAI,KAAK,EAAE;oBACT,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBACnE,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;iBAC7C;YACH,CAAC;WAAC;QA/EA,IAAI,CAAC,OAAO,GAAG,IAAI,eAAW,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAE9D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACnB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAC1D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM;QACJ,OAAO;YACL,GAAG,IAAI,CAAC,aAAa;YACrB,qBAAqB,EAAE,IAAI,CAAC,qBAAqB;YACjD,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;IAEO,YAAY,CAAC,KAAgB,EAAE,WAAmB;QACxD,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,OAAO;SACR;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;SACpC;QAED,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YAChB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;oBAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBACzB,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBAC9D,IAAI,IAAI,CAAC,YAAY,EAAE;wBACrB,IAAI,CAAC,IAAI,EAAE,CAAC;qBACb;iBACF;qBAAM;oBACL,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBACzB,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBAC9D,IAAI,IAAI,CAAC,YAAY,EAAE;wBACrB,IAAI,CAAC,IAAI,EAAE,CAAC;qBACb;iBACF;aACF;iBAAM,IAAI,KAAK,CAAC,GAAG,EAAE;gBACpB,IAAI,CAAC,IAAI,EAAE,CAAC;aACb;YAED,OAAO;SACR;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;YAC1B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;SAC3B;aAAM;YACL,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;SAC3B;QAED,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IACxD,CAAC;IAyBS,KAAK;QACb,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,UAAU;YACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;SAClD,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,MAAM,CAAC;QAEnC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC1D,IAAI,KAAK,EAAE;YACT,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAClE,CAAC;SACH;IACH,CAAC;IAEO,eAAe,CAAC,KAAmD;QACzE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3E,IAAI,CAAC,KAAK,EAAE;YACV,OAAO;SACR;QAED,IAAI,CAAC,aAAa,CAAC,6BAA6B,GAAG,KAAK,CAAC,WAAW,CAAC;YACnE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC;YACzC,CAAC,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAEzD,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC5D,IAAI,gBAAgB,CAAC,QAAQ,IAAI,SAAS,EAAE;YAC1C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBAC9C,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC;aACzB;SACF;QAED,kBAAkB;QAClB,IAAI,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElD,IAAI,IAAI,CAAC,aAAa,KAAK,CAAC,EAAE;YAC5B,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;SAC5B;aAAM,IACL,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC;YAC5C,sCAAsC;YACtC,OAAO,GAAG,sBAAc,EACxB;YACA,IAAI,CAAC,iBAAiB,IAAI,OAAO,CAAC;YAElC,IAAI,OAAO,KAAK,CAAC,EAAE;gBACjB,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,IAAI,QAAQ,CACV,IAAI,CAAC,OAAO,EACZ,KAAK,CAAC,WAAW,EACjB,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,QAAQ,CACd,CACF,CAAC;gBAEF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;gBACpD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBAChE,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC/C;SACF;QAED,IAAI,OAAO,IAAI,CAAC,EAAE;YAChB,IAAI,CAAC,iBAAiB,CAAC;gBACrB,KAAK;gBACL,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,OAAO;aACR,CAAC,CAAC;SACJ;aAAM;YACL,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,GAAG;gBACpC,OAAO;gBACP,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;aAC7D,CAAC;SACH;IACH,CAAC;IAEO,aAAa,CACnB,SAAiB;IACjB,QAAQ;IACR,QAAgB;QAEhB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC;YACV,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YAChC,IAAI,EAAE,SAAS;YACf,gBAAgB,EAAE,QAAQ;SAC3B,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;IAC3B,CAAC;IAEO,iBAAiB,CAAC,EACxB,KAAK,EACL,WAAW,EACX,OAAO,GAKR;QACC,IAAI,IAAI,CAAC,OAAO,IAAI,SAAS,EAAE;YAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;SACxB;QACD,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;YAC1D,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,GAAG;gBACzC,OAAO;gBACP,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,WAAW;gBACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;aAClE,CAAC;YACF,OAAO;SACR;QACD,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE;YACjC,MAAM,GAAG,GAAG,mBAAmB,GAAG,WAAW,CAAC;YAC9C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG;gBACxB,OAAO;gBACP,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,WAAW;gBACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;aACjD,CAAC;SACH;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAC1C,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,UAAU,EAChB,WAAW,EACX,OAAO,CACR,CAAC;QAEF,IAAI,CAAC,aAAa,CAAC,+BAA+B,GAAG,WAAW,CAAC;YAC/D,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3B,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC;QAC9B,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,QAAQ,EAAE;YACZ,QAAQ,CAAC,WAAW,EAAE,CAAC;SACxB;IACH,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,OAAO;SACR;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAEzD,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;aACnD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;aACrC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,GAAG,eAAe,CAAC;QAE1D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,CAAC;YACV,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC7B,IAAI,EAAE,WAAW;YACjB,gBAAgB,EAAE,QAAQ;SAC3B,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,UAAU;YACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC;SACrC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,SAAgB,CAAC;QAE/B,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF;AAnSD,4BAmSC;AAED,MAAM,gBAAgB;IAAtB;QACE,QAAQ;QACR;;;;;WAAkB;QAClB,QAAQ;QACR;;;;mBAAU,CAAC;WAAC;QACZ;;;;mBAAiB,CAAC;WAAC;IAqBrB,CAAC;IAnBC,KAAK;IACH,QAAQ;IACR,OAAe;QAEf,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC;IACzB,CAAC;IAED,MAAM;IACJ,QAAQ;IACR,IAAY;QAEZ,IAAI,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE;YAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;SACvC;QAED,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;QAElD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF;AAED,MAAM,QAAQ;IAQZ,YACmB,OAAoB,EACpB,WAAmB,EACnB,iBAAyB,EACnC,QAAgB;;;;;mBAHN;;;;;;mBACA;;;;;;mBACA;;;;;;mBACV;;QAXT;;;WAGG;QACH;;;;mBAAa,CAAC;WAAC;QACf;;;;mBAAc,CAAC;WAAC;IAOb,CAAC;IAEJ,KAAK;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAChC,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,QAAQ,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,EACpC,IAAI,CAAC,WAAW,CACjB,CAAC;IACJ,CAAC;CACF;AAED,gBAAgB;AACH,QAAA,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;AAClD,WAAW;AACE,QAAA,cAAc,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtC,QAAA,gBAAgB,GAAG,EAAE,CAAC;AAEtB,QAAA,mBAAmB,GAAG,EAAE,CAAC;AAEtC,SAAgB,kBAAkB,CAAC,aAAqB;IACtD,MAAM,QAAQ,GAAG,aAAa,GAAG,2BAAmB,CAAC;IACrD,MAAM,MAAM,GAAG;QACb,GAAG,IAAA,cAAU,EAAC,IAAA,qBAAiB,EAAC,QAAQ,EAAE,IAAA,qBAAiB,EAAC,QAAQ,CAAC,CAAC,CAAC;KACxE,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACvC,IAAI,QAAQ,GAAG,CAAC,EAAE;QAChB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,QAAQ,GAAG,CAAC,EAAE;YAChB,MAAM,QAAQ,GAAG,IAAA,cAAU,EACzB,IAAA,qBAAiB,EAAC,QAAQ,EAAE,IAAA,qBAAiB,EAAC,QAAQ,CAAC,CAAC,CACzD,CAAC;YACF,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SAC9C;KACF;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAhBD,gDAgBC","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 "
|
|
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:
|
|
16
|
-
inputVideo: (input:
|
|
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
|
|
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
|
-
|
|
11
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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,
|
|
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
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
22
|
+
protected process: ChildProcess;
|
|
12
23
|
stopped: boolean;
|
|
13
|
-
constructor(
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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(
|
|
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(
|
|
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
|
|
23
|
-
constructor(
|
|
24
|
-
Object.defineProperty(this, "
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|