werift 0.17.0 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ice/src/ice.d.ts +10 -1
- package/lib/ice/src/ice.js +15 -3
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/rtp/src/container/ebml/ebml.d.ts +32 -0
- package/lib/rtp/src/container/ebml/ebml.js +115 -0
- package/lib/rtp/src/container/ebml/ebml.js.map +1 -0
- package/lib/rtp/src/container/ebml/id.d.ts +221 -0
- package/lib/rtp/src/container/ebml/id.js +225 -0
- package/lib/rtp/src/container/ebml/id.js.map +1 -0
- package/lib/rtp/src/container/ebml/index.d.ts +3 -0
- package/lib/rtp/src/container/ebml/index.js +20 -0
- package/lib/rtp/src/container/ebml/index.js.map +1 -0
- package/lib/rtp/src/container/ebml/typedArrayUtils.d.ts +7 -0
- package/lib/rtp/src/container/ebml/typedArrayUtils.js +109 -0
- package/lib/rtp/src/container/ebml/typedArrayUtils.js.map +1 -0
- package/lib/rtp/src/container/webm.d.ts +10 -4
- package/lib/rtp/src/container/webm.js +56 -7
- package/lib/rtp/src/container/webm.js.map +1 -1
- package/lib/rtp/src/index.d.ts +1 -0
- package/lib/rtp/src/index.js +1 -0
- package/lib/rtp/src/index.js.map +1 -1
- package/lib/rtp/src/processor/avBuffer.d.ts +28 -0
- package/lib/rtp/src/processor/avBuffer.js +91 -0
- package/lib/rtp/src/processor/avBuffer.js.map +1 -0
- package/lib/rtp/src/processor/avBufferCallback.d.ts +10 -0
- package/lib/rtp/src/processor/avBufferCallback.js +27 -0
- package/lib/rtp/src/processor/avBufferCallback.js.map +1 -0
- package/lib/rtp/src/processor/depacketizer.d.ts +1 -1
- package/lib/rtp/src/processor/depacketizer.js.map +1 -1
- package/lib/rtp/src/processor/depacketizerCallback.d.ts +1 -3
- package/lib/rtp/src/processor/depacketizerCallback.js +2 -2
- package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -1
- package/lib/rtp/src/processor/depacketizerTransformer.d.ts +1 -1
- package/lib/rtp/src/processor/index.d.ts +3 -0
- package/lib/rtp/src/processor/index.js +3 -0
- package/lib/rtp/src/processor/index.js.map +1 -1
- package/lib/rtp/src/processor/jitterBuffer.d.ts +1 -1
- package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
- package/lib/rtp/src/processor/jitterBufferCallback.d.ts +1 -3
- package/lib/rtp/src/processor/jitterBufferCallback.js +2 -2
- 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/source/index.d.ts +2 -2
- package/lib/rtp/src/processor/source/index.js +16 -3
- package/lib/rtp/src/processor/source/index.js.map +1 -1
- package/lib/rtp/src/processor/source/rtpCallback.d.ts +17 -0
- package/lib/rtp/src/processor/source/rtpCallback.js +33 -0
- package/lib/rtp/src/processor/source/rtpCallback.js.map +1 -0
- package/lib/rtp/src/processor/source/{rtp.d.ts → rtpStream.d.ts} +2 -5
- package/lib/rtp/src/processor/source/{rtp.js → rtpStream.js} +12 -12
- package/lib/rtp/src/processor/source/rtpStream.js.map +1 -0
- package/lib/rtp/src/processor/webm.d.ts +17 -2
- package/lib/rtp/src/processor/webm.js +83 -33
- package/lib/rtp/src/processor/webm.js.map +1 -1
- package/lib/rtp/src/processor/webmCallback.d.ts +16 -0
- package/lib/rtp/src/processor/webmCallback.js +21 -0
- package/lib/rtp/src/processor/webmCallback.js.map +1 -0
- package/lib/rtp/src/processor/webmStream.d.ts +5 -16
- package/lib/rtp/src/processor/webmStream.js.map +1 -1
- package/lib/{webrtc/src/media/receiver/red.d.ts → rtp/src/rtp/red/handler.d.ts} +2 -2
- package/lib/{webrtc/src/media/receiver/red.js → rtp/src/rtp/red/handler.js} +10 -10
- package/lib/rtp/src/rtp/red/handler.js.map +1 -0
- package/lib/webrtc/src/const.d.ts +1 -1
- package/lib/webrtc/src/const.js +2 -2
- package/lib/webrtc/src/const.js.map +1 -1
- package/lib/webrtc/src/media/receiver/nack.d.ts +1 -0
- package/lib/webrtc/src/media/receiver/nack.js +29 -16
- package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
- package/lib/webrtc/src/media/router.js +17 -13
- package/lib/webrtc/src/media/router.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +1 -1
- package/lib/webrtc/src/media/rtpReceiver.js +14 -9
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +10 -6
- package/lib/webrtc/src/media/rtpTransceiver.js +23 -14
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/track.js +3 -2
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +20 -3
- package/lib/webrtc/src/nonstandard/userMedia.js +79 -8
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +5 -2
- package/lib/webrtc/src/peerConnection.js +72 -46
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sdp.js +2 -2
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/transport/ice.js +10 -3
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +0 -1
- package/lib/webrtc/src/utils.js +1 -3
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/const.ts +1 -1
- package/src/media/receiver/nack.ts +33 -17
- package/src/media/router.ts +16 -13
- package/src/media/rtpReceiver.ts +21 -9
- package/src/media/rtpTransceiver.ts +28 -15
- package/src/media/track.ts +3 -2
- package/src/nonstandard/recorder/writer/webm.ts +2 -2
- package/src/nonstandard/userMedia.ts +89 -7
- package/src/peerConnection.ts +88 -51
- package/src/sdp.ts +2 -2
- package/src/transport/ice.ts +13 -3
- package/src/utils.ts +0 -3
- package/lib/rtp/src/processor/source/rtp.js.map +0 -1
- package/lib/webrtc/src/media/receiver/red.js.map +0 -1
- package/src/media/receiver/red.ts +0 -70
|
@@ -6,8 +6,8 @@ class JitterBufferCallback extends jitterBuffer_1.JitterBufferBase {
|
|
|
6
6
|
constructor(clockRate, options = {}) {
|
|
7
7
|
super(clockRate, options);
|
|
8
8
|
this.clockRate = clockRate;
|
|
9
|
-
this.pipe = (
|
|
10
|
-
this.cb =
|
|
9
|
+
this.pipe = (cb) => {
|
|
10
|
+
this.cb = cb;
|
|
11
11
|
return this;
|
|
12
12
|
};
|
|
13
13
|
this.input = (input) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jitterBufferCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/jitterBufferCallback.ts"],"names":[],"mappings":";;;AAAA,iDAKwB;AAExB,MAAa,oBAAqB,SAAQ,+BAAgB;IAExD,YACS,SAAiB,EACxB,UAAwC,EAAE;QAE1C,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAHnB,cAAS,GAAT,SAAS,CAAQ;QAM1B,SAAI,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"jitterBufferCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/jitterBufferCallback.ts"],"names":[],"mappings":";;;AAAA,iDAKwB;AAExB,MAAa,oBAAqB,SAAQ,+BAAgB;IAExD,YACS,SAAiB,EACxB,UAAwC,EAAE;QAE1C,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAHnB,cAAS,GAAT,SAAS,CAAQ;QAM1B,SAAI,GAAG,CAAC,EAAuC,EAAE,EAAE;YACjD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,UAAK,GAAG,CAAC,KAAwB,EAAE,EAAE;YACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;gBAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;aACjB;QACH,CAAC,CAAC;IAXF,CAAC;CAYF;AAnBD,oDAmBC","sourcesContent":["import {\n JitterBufferBase,\n JitterBufferInput,\n JitterBufferOptions,\n JitterBufferOutput,\n} from \"./jitterBuffer\";\n\nexport class JitterBufferCallback extends JitterBufferBase {\n private cb!: (input: JitterBufferOutput) => void;\n constructor(\n public clockRate: number,\n options: Partial<JitterBufferOptions> = {}\n ) {\n super(clockRate, options);\n }\n\n pipe = (cb: (input: JitterBufferOutput) => void) => {\n this.cb = cb;\n return this;\n };\n\n input = (input: JitterBufferInput) => {\n for (const output of this.processInput(input)) {\n this.cb(output);\n }\n };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { TransformStream } from "stream/web";
|
|
3
3
|
import { JitterBufferBase, JitterBufferInput, JitterBufferOptions, JitterBufferOutput } from "./jitterBuffer";
|
|
4
|
-
export declare const jitterBufferTransformer: (clockRate: number, options?: Partial<JitterBufferOptions> | undefined) => TransformStream<import("./source
|
|
4
|
+
export declare const jitterBufferTransformer: (clockRate: number, options?: Partial<JitterBufferOptions> | undefined) => TransformStream<import("./source").RtpOutput, JitterBufferOutput>;
|
|
5
5
|
export declare class JitterBufferTransformer extends JitterBufferBase {
|
|
6
6
|
clockRate: number;
|
|
7
7
|
transform: TransformStream<JitterBufferInput, JitterBufferOutput>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
export * from "./rtpCallback";
|
|
2
|
+
export * from "./rtpStream";
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "RtpSourceStream", { enumerable: true, get: function () { return rtp_1.RtpSourceStream; } });
|
|
17
|
+
__exportStar(require("./rtpCallback"), exports);
|
|
18
|
+
__exportStar(require("./rtpStream"), exports);
|
|
6
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../rtp/src/processor/source/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../rtp/src/processor/source/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,8CAA4B","sourcesContent":["export * from \"./rtpCallback\";\nexport * from \"./rtpStream\";\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { RtpPacket } from "../../rtp/rtp";
|
|
3
|
+
export interface RtpOutput {
|
|
4
|
+
rtp?: RtpPacket;
|
|
5
|
+
eol?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class RtpSourceCallback {
|
|
8
|
+
private options;
|
|
9
|
+
private cb?;
|
|
10
|
+
constructor(options?: {
|
|
11
|
+
payloadType?: number;
|
|
12
|
+
clearInvalidPTPacket?: boolean;
|
|
13
|
+
});
|
|
14
|
+
pipe(cb: (chunk: RtpOutput) => void): void;
|
|
15
|
+
input: (packet: Buffer | RtpPacket) => void;
|
|
16
|
+
stop(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RtpSourceCallback = void 0;
|
|
4
|
+
const rtp_1 = require("../../rtp/rtp");
|
|
5
|
+
class RtpSourceCallback {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
this.options = options;
|
|
8
|
+
this.input = (packet) => {
|
|
9
|
+
const rtp = packet instanceof rtp_1.RtpPacket ? packet : rtp_1.RtpPacket.deSerialize(packet);
|
|
10
|
+
if (this.options.payloadType != undefined &&
|
|
11
|
+
this.options.payloadType !== rtp.header.payloadType) {
|
|
12
|
+
if (this.options.clearInvalidPTPacket) {
|
|
13
|
+
rtp.clear();
|
|
14
|
+
}
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (this.cb) {
|
|
18
|
+
this.cb({ rtp });
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
options.clearInvalidPTPacket = options.clearInvalidPTPacket ?? true;
|
|
22
|
+
}
|
|
23
|
+
pipe(cb) {
|
|
24
|
+
this.cb = cb;
|
|
25
|
+
}
|
|
26
|
+
stop() {
|
|
27
|
+
if (this.cb) {
|
|
28
|
+
this.cb({ eol: true });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.RtpSourceCallback = RtpSourceCallback;
|
|
33
|
+
//# sourceMappingURL=rtpCallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtpCallback.js","sourceRoot":"","sources":["../../../../../../rtp/src/processor/source/rtpCallback.ts"],"names":[],"mappings":";;;AAAA,uCAA0C;AAO1C,MAAa,iBAAiB;IAG5B,YACU,UAGJ,EAAE;QAHE,YAAO,GAAP,OAAO,CAGT;QASR,UAAK,GAAG,CAAC,MAA0B,EAAE,EAAE;YACrC,MAAM,GAAG,GACP,MAAM,YAAY,eAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAEvE,IACE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,SAAS;gBACrC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,EACnD;gBACA,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE;oBACrC,GAAG,CAAC,KAAK,EAAE,CAAC;iBACb;gBACD,OAAO;aACR;YAED,IAAI,IAAI,CAAC,EAAE,EAAE;gBACX,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;aAClB;QACH,CAAC,CAAC;QAxBA,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,IAAI,IAAI,CAAC;IACtE,CAAC;IAED,IAAI,CAAC,EAA8B;QACjC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAqBD,IAAI;QACF,IAAI,IAAI,CAAC,EAAE,EAAE;YACX,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;SACxB;IACH,CAAC;CACF;AAxCD,8CAwCC","sourcesContent":["import { RtpPacket } from \"../../rtp/rtp\";\n\nexport interface RtpOutput {\n rtp?: RtpPacket;\n eol?: boolean;\n}\n\nexport class RtpSourceCallback {\n private cb?: (chunk: RtpOutput) => void;\n\n constructor(\n private options: {\n payloadType?: number;\n clearInvalidPTPacket?: boolean;\n } = {}\n ) {\n options.clearInvalidPTPacket = options.clearInvalidPTPacket ?? true;\n }\n\n pipe(cb: (chunk: RtpOutput) => void) {\n this.cb = cb;\n }\n\n input = (packet: Buffer | RtpPacket) => {\n const rtp =\n packet instanceof RtpPacket ? packet : RtpPacket.deSerialize(packet);\n\n if (\n this.options.payloadType != undefined &&\n this.options.payloadType !== rtp.header.payloadType\n ) {\n if (this.options.clearInvalidPTPacket) {\n rtp.clear();\n }\n return;\n }\n\n if (this.cb) {\n this.cb({ rtp });\n }\n };\n\n stop() {\n if (this.cb) {\n this.cb({ eol: true });\n }\n }\n}\n"]}
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { ReadableStream, ReadableStreamController } from "stream/web";
|
|
4
4
|
import { RtpPacket } from "../../rtp/rtp";
|
|
5
|
-
|
|
6
|
-
rtp?: RtpPacket;
|
|
7
|
-
eol?: boolean;
|
|
8
|
-
}
|
|
5
|
+
import { RtpOutput } from "./rtpCallback";
|
|
9
6
|
export declare class RtpSourceStream {
|
|
10
7
|
private options;
|
|
11
8
|
readable: ReadableStream<RtpOutput>;
|
|
@@ -15,6 +12,6 @@ export declare class RtpSourceStream {
|
|
|
15
12
|
payloadType?: number;
|
|
16
13
|
clearInvalidPTPacket?: boolean;
|
|
17
14
|
});
|
|
18
|
-
push(packet: Buffer | RtpPacket)
|
|
15
|
+
push: (packet: Buffer | RtpPacket) => void;
|
|
19
16
|
stop(): void;
|
|
20
17
|
}
|
|
@@ -6,6 +6,17 @@ const rtp_1 = require("../../rtp/rtp");
|
|
|
6
6
|
class RtpSourceStream {
|
|
7
7
|
constructor(options = {}) {
|
|
8
8
|
this.options = options;
|
|
9
|
+
this.push = (packet) => {
|
|
10
|
+
const rtp = packet instanceof rtp_1.RtpPacket ? packet : rtp_1.RtpPacket.deSerialize(packet);
|
|
11
|
+
if (this.options.payloadType != undefined &&
|
|
12
|
+
this.options.payloadType !== rtp.header.payloadType) {
|
|
13
|
+
if (this.options.clearInvalidPTPacket) {
|
|
14
|
+
rtp.clear();
|
|
15
|
+
}
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.write({ rtp });
|
|
19
|
+
};
|
|
9
20
|
options.clearInvalidPTPacket = options.clearInvalidPTPacket ?? true;
|
|
10
21
|
this.readable = new web_1.ReadableStream({
|
|
11
22
|
start: (controller) => {
|
|
@@ -14,20 +25,9 @@ class RtpSourceStream {
|
|
|
14
25
|
},
|
|
15
26
|
});
|
|
16
27
|
}
|
|
17
|
-
push(packet) {
|
|
18
|
-
const rtp = packet instanceof rtp_1.RtpPacket ? packet : rtp_1.RtpPacket.deSerialize(packet);
|
|
19
|
-
if (this.options.payloadType != undefined &&
|
|
20
|
-
this.options.payloadType !== rtp.header.payloadType) {
|
|
21
|
-
if (this.options.clearInvalidPTPacket) {
|
|
22
|
-
rtp.clear();
|
|
23
|
-
}
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
this.write({ rtp });
|
|
27
|
-
}
|
|
28
28
|
stop() {
|
|
29
29
|
this.controller.enqueue({ eol: true });
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
exports.RtpSourceStream = RtpSourceStream;
|
|
33
|
-
//# sourceMappingURL=
|
|
33
|
+
//# sourceMappingURL=rtpStream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtpStream.js","sourceRoot":"","sources":["../../../../../../rtp/src/processor/source/rtpStream.ts"],"names":[],"mappings":";;;AAAA,oCAAsE;AAEtE,uCAA0C;AAG1C,MAAa,eAAe;IAK1B,YACU,UAGJ,EAAE;QAHE,YAAO,GAAP,OAAO,CAGT;QAYR,SAAI,GAAG,CAAC,MAA0B,EAAE,EAAE;YACpC,MAAM,GAAG,GACP,MAAM,YAAY,eAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAEvE,IACE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,SAAS;gBACrC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,EACnD;gBACA,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE;oBACrC,GAAG,CAAC,KAAK,EAAE,CAAC;iBACb;gBACD,OAAO;aACR;YAED,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACtB,CAAC,CAAC;QAzBA,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,IAAI,IAAI,CAAC;QAEpE,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAc,CAAC;YACjC,KAAK,EAAE,CAAC,UAAU,EAAE,EAAE;gBACpB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;gBAC7B,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpD,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAmBD,IAAI;QACF,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;CACF;AAzCD,0CAyCC","sourcesContent":["import { ReadableStream, ReadableStreamController } from \"stream/web\";\n\nimport { RtpPacket } from \"../../rtp/rtp\";\nimport { RtpOutput } from \"./rtpCallback\";\n\nexport class RtpSourceStream {\n readable: ReadableStream<RtpOutput>;\n write!: (chunk: RtpOutput) => void;\n protected controller!: ReadableStreamController<RtpOutput>;\n\n constructor(\n private options: {\n payloadType?: number;\n clearInvalidPTPacket?: boolean;\n } = {}\n ) {\n options.clearInvalidPTPacket = options.clearInvalidPTPacket ?? true;\n\n this.readable = new ReadableStream({\n start: (controller) => {\n this.controller = controller;\n this.write = (chunk) => controller.enqueue(chunk);\n },\n });\n }\n\n push = (packet: Buffer | RtpPacket) => {\n const rtp =\n packet instanceof RtpPacket ? packet : RtpPacket.deSerialize(packet);\n\n if (\n this.options.payloadType != undefined &&\n this.options.payloadType !== rtp.header.payloadType\n ) {\n if (this.options.clearInvalidPTPacket) {\n rtp.clear();\n }\n return;\n }\n\n this.write({ rtp });\n };\n\n stop() {\n this.controller.enqueue({ eol: true });\n }\n}\n"]}
|
|
@@ -4,6 +4,8 @@ import { DepacketizerOutput } from "./depacketizer";
|
|
|
4
4
|
export declare type WebmInput = DepacketizerOutput;
|
|
5
5
|
export declare type WebmOutput = {
|
|
6
6
|
saveToFile?: Buffer;
|
|
7
|
+
kind?: "initial" | "cluster" | "block" | "cuePoints";
|
|
8
|
+
previousDuration?: number;
|
|
7
9
|
eol?: {
|
|
8
10
|
/**ms */
|
|
9
11
|
duration: number;
|
|
@@ -13,6 +15,8 @@ export declare type WebmOutput = {
|
|
|
13
15
|
export interface WebmOption {
|
|
14
16
|
/**ms */
|
|
15
17
|
duration?: number;
|
|
18
|
+
encryptionKey?: Buffer;
|
|
19
|
+
strictTimestamp?: boolean;
|
|
16
20
|
}
|
|
17
21
|
export declare class WebmBase {
|
|
18
22
|
tracks: {
|
|
@@ -30,7 +34,9 @@ export declare class WebmBase {
|
|
|
30
34
|
private timestamps;
|
|
31
35
|
private cuePoints;
|
|
32
36
|
private position;
|
|
37
|
+
private clusterCounts;
|
|
33
38
|
stopped: boolean;
|
|
39
|
+
elapsed?: number;
|
|
34
40
|
constructor(tracks: {
|
|
35
41
|
width?: number;
|
|
36
42
|
height?: number;
|
|
@@ -40,9 +46,18 @@ export declare class WebmBase {
|
|
|
40
46
|
trackNumber: number;
|
|
41
47
|
}[], output: (output: WebmOutput) => void, options?: WebmOption);
|
|
42
48
|
private processInput;
|
|
43
|
-
processAudioInput(input: WebmInput)
|
|
44
|
-
processVideoInput(input: WebmInput)
|
|
49
|
+
processAudioInput: (input: WebmInput) => void;
|
|
50
|
+
processVideoInput: (input: WebmInput) => void;
|
|
45
51
|
start(): void;
|
|
46
52
|
private onFrameReceived;
|
|
53
|
+
private createCluster;
|
|
54
|
+
private createSimpleBlock;
|
|
47
55
|
private stop;
|
|
48
56
|
}
|
|
57
|
+
/**4294967295 */
|
|
58
|
+
export declare const Max32Uint: number;
|
|
59
|
+
/**32767 */
|
|
60
|
+
export declare const MaxSinged16Int: number;
|
|
61
|
+
export declare const DurationPosition = 83;
|
|
62
|
+
export declare const SegmentSizePosition = 40;
|
|
63
|
+
export declare function replaceSegmentSize(totalFileSize: number): Buffer;
|
|
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.WebmBase = void 0;
|
|
6
|
+
exports.replaceSegmentSize = exports.SegmentSizePosition = exports.DurationPosition = exports.MaxSinged16Int = exports.Max32Uint = exports.WebmBase = void 0;
|
|
7
7
|
const debug_1 = __importDefault(require("debug"));
|
|
8
8
|
const __1 = require("..");
|
|
9
|
+
const ebml_1 = require("../container/ebml");
|
|
9
10
|
const webm_1 = require("../container/webm");
|
|
10
|
-
const sourcePath = `werift-rtp : packages/rtp/src/
|
|
11
|
+
const sourcePath = `werift-rtp : packages/rtp/src/processor/webm.ts`;
|
|
11
12
|
const log = (0, debug_1.default)(sourcePath);
|
|
12
13
|
class WebmBase {
|
|
13
14
|
constructor(tracks, output, options = {}) {
|
|
@@ -18,8 +19,21 @@ class WebmBase {
|
|
|
18
19
|
this.timestamps = {};
|
|
19
20
|
this.cuePoints = [];
|
|
20
21
|
this.position = 0;
|
|
22
|
+
this.clusterCounts = 0;
|
|
21
23
|
this.stopped = false;
|
|
22
|
-
this.
|
|
24
|
+
this.processAudioInput = (input) => {
|
|
25
|
+
const track = this.tracks.find((t) => t.kind === "audio");
|
|
26
|
+
if (track) {
|
|
27
|
+
this.processInput(input, track.trackNumber);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
this.processVideoInput = (input) => {
|
|
31
|
+
const track = this.tracks.find((t) => t.kind === "video");
|
|
32
|
+
if (track) {
|
|
33
|
+
this.processInput(input, track.trackNumber);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
this.builder = new webm_1.WEBMBuilder(tracks, options.encryptionKey);
|
|
23
37
|
tracks.forEach((t) => {
|
|
24
38
|
this.timestamps[t.trackNumber] = new ClusterTimestamp(t.clockRate);
|
|
25
39
|
});
|
|
@@ -35,24 +49,12 @@ class WebmBase {
|
|
|
35
49
|
}
|
|
36
50
|
this.onFrameReceived({ ...input.frame, trackNumber });
|
|
37
51
|
}
|
|
38
|
-
processAudioInput(input) {
|
|
39
|
-
const track = this.tracks.find((t) => t.kind === "audio");
|
|
40
|
-
if (track) {
|
|
41
|
-
this.processInput(input, track.trackNumber);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
processVideoInput(input) {
|
|
45
|
-
const track = this.tracks.find((t) => t.kind === "video");
|
|
46
|
-
if (track) {
|
|
47
|
-
this.processInput(input, track.trackNumber);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
52
|
start() {
|
|
51
53
|
const staticPart = Buffer.concat([
|
|
52
54
|
this.builder.ebmlHeader,
|
|
53
55
|
this.builder.createSegment(this.options.duration),
|
|
54
56
|
]);
|
|
55
|
-
this.output({ saveToFile: staticPart });
|
|
57
|
+
this.output({ saveToFile: staticPart, kind: "initial" });
|
|
56
58
|
this.position += staticPart.length;
|
|
57
59
|
const video = this.tracks.find((t) => t.kind === "video");
|
|
58
60
|
if (video) {
|
|
@@ -65,21 +67,49 @@ class WebmBase {
|
|
|
65
67
|
return;
|
|
66
68
|
}
|
|
67
69
|
const timestampManager = this.timestamps[track.trackNumber];
|
|
70
|
+
// clusterの経過時間
|
|
68
71
|
let elapsed = timestampManager.update(frame.timestamp);
|
|
69
|
-
if (
|
|
70
|
-
|
|
72
|
+
if (this.clusterCounts === 0) {
|
|
73
|
+
this.createCluster(0.0, 0);
|
|
74
|
+
}
|
|
75
|
+
else if ((track.kind === "video" && frame.isKeyframe) ||
|
|
76
|
+
elapsed > exports.MaxSinged16Int) {
|
|
71
77
|
this.relativeTimestamp += elapsed;
|
|
72
|
-
const cluster = this.builder.createCluster(this.relativeTimestamp);
|
|
73
|
-
this.output({ saveToFile: Buffer.from(cluster) });
|
|
74
78
|
if (elapsed !== 0) {
|
|
75
79
|
this.cuePoints.push(new CuePoint(this.builder, track.trackNumber, this.relativeTimestamp, this.position));
|
|
80
|
+
this.createCluster(this.relativeTimestamp, elapsed);
|
|
81
|
+
Object.values(this.timestamps).forEach((t) => t.shift(elapsed));
|
|
82
|
+
elapsed = timestampManager.update(frame.timestamp);
|
|
76
83
|
}
|
|
77
|
-
this.position += cluster.length;
|
|
78
|
-
Object.values(this.timestamps).forEach((t) => t.reset());
|
|
79
|
-
elapsed = timestampManager.update(frame.timestamp);
|
|
80
84
|
}
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
this.createSimpleBlock({ frame, trackNumber: track.trackNumber, elapsed });
|
|
86
|
+
}
|
|
87
|
+
createCluster(timestamp, duration) {
|
|
88
|
+
const cluster = this.builder.createCluster(timestamp);
|
|
89
|
+
this.clusterCounts++;
|
|
90
|
+
this.output({
|
|
91
|
+
saveToFile: Buffer.from(cluster),
|
|
92
|
+
kind: "cluster",
|
|
93
|
+
previousDuration: duration,
|
|
94
|
+
});
|
|
95
|
+
this.position += cluster.length;
|
|
96
|
+
this.elapsed = undefined;
|
|
97
|
+
}
|
|
98
|
+
createSimpleBlock({ frame, trackNumber, elapsed, }) {
|
|
99
|
+
if (this.elapsed == undefined) {
|
|
100
|
+
this.elapsed = elapsed;
|
|
101
|
+
}
|
|
102
|
+
if (elapsed < this.elapsed && this.options.strictTimestamp) {
|
|
103
|
+
log("previous timestamp", {
|
|
104
|
+
elapsed,
|
|
105
|
+
present: this.elapsed,
|
|
106
|
+
trackNumber,
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.elapsed = elapsed;
|
|
111
|
+
const block = this.builder.createSimpleBlock(frame.data, frame.isKeyframe, trackNumber, elapsed);
|
|
112
|
+
this.output({ saveToFile: block, kind: "block" });
|
|
83
113
|
this.position += block.length;
|
|
84
114
|
const [cuePoint] = this.cuePoints.slice(-1);
|
|
85
115
|
if (cuePoint) {
|
|
@@ -93,7 +123,7 @@ class WebmBase {
|
|
|
93
123
|
this.stopped = true;
|
|
94
124
|
log("stop");
|
|
95
125
|
const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));
|
|
96
|
-
this.output({ saveToFile: Buffer.from(cues) });
|
|
126
|
+
this.output({ saveToFile: Buffer.from(cues), kind: "cuePoints" });
|
|
97
127
|
const latestTimestamp = Object.values(this.timestamps).sort((a, b) => a.elapsed - b.elapsed)[0].elapsed;
|
|
98
128
|
const duration = this.relativeTimestamp + latestTimestamp;
|
|
99
129
|
const durationElement = this.builder.createDuration(duration);
|
|
@@ -104,23 +134,25 @@ exports.WebmBase = WebmBase;
|
|
|
104
134
|
class ClusterTimestamp {
|
|
105
135
|
constructor(clockRate) {
|
|
106
136
|
this.clockRate = clockRate;
|
|
137
|
+
/**ms */
|
|
107
138
|
this.elapsed = 0;
|
|
139
|
+
this.offset = 0;
|
|
108
140
|
}
|
|
109
|
-
|
|
110
|
-
this.
|
|
141
|
+
shift(elapsed) {
|
|
142
|
+
this.offset += elapsed;
|
|
111
143
|
}
|
|
112
144
|
update(timestamp) {
|
|
113
145
|
if (this.baseTimestamp == undefined) {
|
|
114
146
|
this.baseTimestamp = timestamp;
|
|
115
147
|
}
|
|
116
|
-
const rotate = Math.abs(timestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;
|
|
148
|
+
const rotate = Math.abs(timestamp - this.baseTimestamp) > (exports.Max32Uint / 4) * 3;
|
|
117
149
|
if (rotate) {
|
|
118
150
|
log("rotate", { baseTimestamp: this.baseTimestamp, timestamp });
|
|
119
151
|
}
|
|
120
152
|
const elapsed = rotate
|
|
121
|
-
? timestamp + Max32Uint - this.baseTimestamp
|
|
153
|
+
? timestamp + exports.Max32Uint - this.baseTimestamp
|
|
122
154
|
: timestamp - this.baseTimestamp;
|
|
123
|
-
this.elapsed = (0, __1.int)((elapsed / this.clockRate) * 1000);
|
|
155
|
+
this.elapsed = (0, __1.int)((elapsed / this.clockRate) * 1000) - this.offset;
|
|
124
156
|
return this.elapsed;
|
|
125
157
|
}
|
|
126
158
|
}
|
|
@@ -142,7 +174,25 @@ class CuePoint {
|
|
|
142
174
|
}
|
|
143
175
|
}
|
|
144
176
|
/**4294967295 */
|
|
145
|
-
|
|
177
|
+
exports.Max32Uint = Number(0x01n << 32n) - 1;
|
|
146
178
|
/**32767 */
|
|
147
|
-
|
|
179
|
+
exports.MaxSinged16Int = (0x01 << 16) / 2 - 1;
|
|
180
|
+
exports.DurationPosition = 83;
|
|
181
|
+
exports.SegmentSizePosition = 40;
|
|
182
|
+
function replaceSegmentSize(totalFileSize) {
|
|
183
|
+
const bodySize = totalFileSize - exports.SegmentSizePosition;
|
|
184
|
+
const resize = [
|
|
185
|
+
...(0, ebml_1.vintEncode)((0, ebml_1.numberToByteArray)(bodySize, (0, ebml_1.getEBMLByteLength)(bodySize))),
|
|
186
|
+
];
|
|
187
|
+
const todoFill = 8 - resize.length - 2;
|
|
188
|
+
if (todoFill > 0) {
|
|
189
|
+
resize.push(0xec);
|
|
190
|
+
if (todoFill > 1) {
|
|
191
|
+
const voidSize = (0, ebml_1.vintEncode)((0, ebml_1.numberToByteArray)(todoFill, (0, ebml_1.getEBMLByteLength)(todoFill)));
|
|
192
|
+
[...voidSize].forEach((i) => resize.push(i));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return Buffer.from(resize);
|
|
196
|
+
}
|
|
197
|
+
exports.replaceSegmentSize = replaceSegmentSize;
|
|
148
198
|
//# sourceMappingURL=webm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { int } from \"..\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { DepacketizerOutput } from \"./depacketizer\";\n\nconst sourcePath = `werift-rtp : packages/rtp/src/processor_v2/webmLive.ts`;\nconst log = debug(sourcePath);\n\nexport type WebmInput = DepacketizerOutput;\n\nexport type WebmOutput = {\n saveToFile?: Buffer;\n eol?: {\n /**ms */\n duration: number;\n durationElement: Uint8Array;\n };\n};\n\nexport interface WebmOption {\n /**ms */\n duration?: number;\n}\n\nexport class WebmBase {\n private builder: WEBMBuilder;\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: ClusterTimestamp } = {};\n private cuePoints: CuePoint[] = [];\n private position = 0;\n stopped = false;\n\n constructor(\n public tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n trackNumber: number;\n }[],\n private output: (output: WebmOutput) => void,\n private options: WebmOption = {}\n ) {\n this.builder = new WEBMBuilder(tracks);\n\n tracks.forEach((t) => {\n this.timestamps[t.trackNumber] = new ClusterTimestamp(t.clockRate);\n });\n }\n\n private processInput(input: WebmInput, trackNumber: number) {\n if (this.stopped) return;\n if (!input.frame) {\n if (input.eol) {\n this.stop();\n }\n return;\n }\n\n this.onFrameReceived({ ...input.frame, trackNumber });\n }\n\n processAudioInput(input: WebmInput) {\n const track = this.tracks.find((t) => t.kind === \"audio\");\n if (track) {\n this.processInput(input, track.trackNumber);\n }\n }\n\n processVideoInput(input: WebmInput) {\n const track = this.tracks.find((t) => t.kind === \"video\");\n if (track) {\n this.processInput(input, track.trackNumber);\n }\n }\n\n start() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(this.options.duration),\n ]);\n this.output({ saveToFile: staticPart });\n this.position += staticPart.length;\n\n const video = this.tracks.find((t) => t.kind === \"video\");\n if (video) {\n this.cuePoints.push(\n new CuePoint(this.builder, video.trackNumber, 0.0, this.position)\n );\n }\n }\n\n private onFrameReceived(frame: WebmInput[\"frame\"] & { trackNumber: number }) {\n const track = this.tracks.find((t) => t.trackNumber === frame.trackNumber);\n if (!track) {\n return;\n }\n\n const timestampManager = this.timestamps[track.trackNumber];\n let elapsed = timestampManager.update(frame.timestamp);\n\n if (\n (track.kind === \"video\" && frame.isKeyframe) ||\n elapsed > MaxSinged16Int\n ) {\n this.relativeTimestamp += elapsed;\n\n const cluster = this.builder.createCluster(this.relativeTimestamp);\n this.output({ saveToFile: Buffer.from(cluster) });\n\n if (elapsed !== 0) {\n this.cuePoints.push(\n new CuePoint(\n this.builder,\n track.trackNumber,\n this.relativeTimestamp,\n this.position\n )\n );\n }\n this.position += cluster.length;\n Object.values(this.timestamps).forEach((t) => t.reset());\n elapsed = timestampManager.update(frame.timestamp);\n }\n\n const block = this.builder.createSimpleBlock(\n frame.data,\n frame.isKeyframe,\n track.trackNumber,\n elapsed\n );\n this.output({ saveToFile: block });\n this.position += block.length;\n const [cuePoint] = this.cuePoints.slice(-1);\n if (cuePoint) {\n cuePoint.blockNumber++;\n }\n }\n\n private stop() {\n if (this.stopped) {\n return;\n }\n this.stopped = true;\n\n log(\"stop\");\n\n const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n this.output({ saveToFile: Buffer.from(cues) });\n\n const latestTimestamp = Object.values(this.timestamps).sort(\n (a, b) => a.elapsed - b.elapsed\n )[0].elapsed;\n const duration = this.relativeTimestamp + latestTimestamp;\n const durationElement = this.builder.createDuration(duration);\n this.output({ eol: { duration, durationElement } });\n }\n}\n\nclass ClusterTimestamp {\n baseTimestamp?: number;\n elapsed = 0;\n\n constructor(public clockRate: number) {}\n\n reset() {\n this.baseTimestamp = undefined;\n }\n\n update(timestamp: number) {\n if (this.baseTimestamp == undefined) {\n this.baseTimestamp = timestamp;\n }\n const rotate =\n Math.abs(timestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;\n\n if (rotate) {\n log(\"rotate\", { baseTimestamp: this.baseTimestamp, timestamp });\n }\n\n const elapsed = rotate\n ? timestamp + Max32Uint - this.baseTimestamp\n : timestamp - this.baseTimestamp;\n\n this.elapsed = int((elapsed / this.clockRate) * 1000);\n return this.elapsed;\n }\n}\n\nclass CuePoint {\n /**\n * cuesの後のclusterのあるべき位置\n * cuesはclusterの前に挿入される\n */\n cuesLength = 0;\n blockNumber = 0;\n\n constructor(\n private readonly builder: WEBMBuilder,\n private readonly trackNumber: number,\n private readonly relativeTimestamp: number,\n public position: number\n ) {}\n\n build() {\n return this.builder.createCuePoint(\n this.relativeTimestamp,\n this.trackNumber,\n this.position - 48 + this.cuesLength,\n this.blockNumber\n );\n }\n}\n\n/**4294967295 */\nconst Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nconst MaxSinged16Int = (0x01 << 16) / 2 - 1;\n"]}
|
|
1
|
+
{"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { int } from \"..\";\nimport {\n getEBMLByteLength,\n numberToByteArray,\n vintEncode,\n} from \"../container/ebml\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { DepacketizerOutput } from \"./depacketizer\";\n\nconst sourcePath = `werift-rtp : packages/rtp/src/processor/webm.ts`;\nconst log = debug(sourcePath);\n\nexport type WebmInput = DepacketizerOutput;\n\nexport type WebmOutput = {\n saveToFile?: Buffer;\n kind?: \"initial\" | \"cluster\" | \"block\" | \"cuePoints\";\n previousDuration?: number;\n eol?: {\n /**ms */\n duration: number;\n durationElement: Uint8Array;\n };\n};\n\nexport interface WebmOption {\n /**ms */\n duration?: number;\n encryptionKey?: Buffer;\n strictTimestamp?: boolean;\n}\n\nexport class WebmBase {\n private builder: WEBMBuilder;\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: ClusterTimestamp } = {};\n private cuePoints: CuePoint[] = [];\n private position = 0;\n private clusterCounts = 0;\n stopped = false;\n elapsed?: number;\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(t.clockRate);\n });\n }\n\n private processInput(input: WebmInput, trackNumber: number) {\n if (this.stopped) return;\n if (!input.frame) {\n if (input.eol) {\n this.stop();\n }\n return;\n }\n\n this.onFrameReceived({ ...input.frame, trackNumber });\n }\n\n processAudioInput = (input: WebmInput) => {\n const track = this.tracks.find((t) => t.kind === \"audio\");\n if (track) {\n this.processInput(input, track.trackNumber);\n }\n };\n\n processVideoInput = (input: WebmInput) => {\n const track = this.tracks.find((t) => t.kind === \"video\");\n if (track) {\n this.processInput(input, track.trackNumber);\n }\n };\n\n start() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(this.options.duration),\n ]);\n this.output({ saveToFile: staticPart, 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 const timestampManager = this.timestamps[track.trackNumber];\n // clusterの経過時間\n let elapsed = timestampManager.update(frame.timestamp);\n\n if (this.clusterCounts === 0) {\n this.createCluster(0.0, 0);\n } else if (\n (track.kind === \"video\" && frame.isKeyframe) ||\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.timestamp);\n }\n }\n\n this.createSimpleBlock({ frame, trackNumber: track.trackNumber, elapsed });\n }\n\n private createCluster(timestamp: number, duration: number) {\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 log(\"previous timestamp\", {\n elapsed,\n present: this.elapsed,\n trackNumber,\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 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 log(\"stop\");\n\n const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n this.output({ saveToFile: Buffer.from(cues), kind: \"cuePoints\" });\n\n const latestTimestamp = Object.values(this.timestamps).sort(\n (a, b) => a.elapsed - b.elapsed\n )[0].elapsed;\n const duration = this.relativeTimestamp + latestTimestamp;\n const durationElement = this.builder.createDuration(duration);\n this.output({ eol: { duration, durationElement } });\n }\n}\n\nclass ClusterTimestamp {\n baseTimestamp?: number;\n /**ms */\n elapsed = 0;\n private offset = 0;\n\n constructor(public clockRate: number) {}\n\n shift(elapsed: number) {\n this.offset += elapsed;\n }\n\n update(timestamp: number) {\n if (this.baseTimestamp == undefined) {\n this.baseTimestamp = timestamp;\n }\n const rotate =\n Math.abs(timestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;\n\n if (rotate) {\n log(\"rotate\", { baseTimestamp: this.baseTimestamp, timestamp });\n }\n\n const elapsed = rotate\n ? timestamp + Max32Uint - this.baseTimestamp\n : timestamp - this.baseTimestamp;\n\n this.elapsed = int((elapsed / this.clockRate) * 1000) - this.offset;\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"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SupportedCodec } from "../container/webm";
|
|
2
|
+
import { WebmBase, WebmOption, WebmOutput } from "./webm";
|
|
3
|
+
export declare class WebmCallback extends WebmBase {
|
|
4
|
+
private cb;
|
|
5
|
+
constructor(tracks: {
|
|
6
|
+
width?: number;
|
|
7
|
+
height?: number;
|
|
8
|
+
kind: "audio" | "video";
|
|
9
|
+
codec: SupportedCodec;
|
|
10
|
+
clockRate: number;
|
|
11
|
+
trackNumber: number;
|
|
12
|
+
}[], options?: WebmOption);
|
|
13
|
+
pipe: (cb: (input: WebmOutput) => void) => void;
|
|
14
|
+
inputAudio: (input: import("./depacketizer").DepacketizerOutput) => void;
|
|
15
|
+
inputVideo: (input: import("./depacketizer").DepacketizerOutput) => void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebmCallback = void 0;
|
|
4
|
+
const webm_1 = require("./webm");
|
|
5
|
+
class WebmCallback extends webm_1.WebmBase {
|
|
6
|
+
constructor(tracks, options = {}) {
|
|
7
|
+
super(tracks, (output) => {
|
|
8
|
+
if (this.cb) {
|
|
9
|
+
this.cb(output);
|
|
10
|
+
}
|
|
11
|
+
}, options);
|
|
12
|
+
this.pipe = (cb) => {
|
|
13
|
+
this.cb = cb;
|
|
14
|
+
this.start();
|
|
15
|
+
};
|
|
16
|
+
this.inputAudio = this.processAudioInput;
|
|
17
|
+
this.inputVideo = this.processVideoInput;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.WebmCallback = WebmCallback;
|
|
21
|
+
//# sourceMappingURL=webmCallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webmCallback.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webmCallback.ts"],"names":[],"mappings":";;;AACA,iCAA0D;AAE1D,MAAa,YAAa,SAAQ,eAAQ;IAExC,YACE,MAOG,EACH,UAAsB,EAAE;QAExB,KAAK,CACH,MAAM,EACN,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,IAAI,CAAC,EAAE,EAAE;gBACX,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;aACjB;QACH,CAAC,EACD,OAAO,CACR,CAAC;QAGJ,SAAI,GAAG,CAAC,EAA+B,EAAE,EAAE;YACzC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,CAAC;QAEF,eAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpC,eAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC;IARpC,CAAC;CASF;AA/BD,oCA+BC","sourcesContent":["import { SupportedCodec } from \"../container/webm\";\nimport { WebmBase, WebmOption, WebmOutput } from \"./webm\";\n\nexport class WebmCallback extends WebmBase {\n private cb!: (input: WebmOutput) => void;\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.cb(output);\n }\n },\n options\n );\n }\n\n pipe = (cb: (input: WebmOutput) => void) => {\n this.cb = cb;\n this.start();\n };\n\n inputAudio = this.processAudioInput;\n inputVideo = this.processVideoInput;\n}\n"]}
|
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
2
|
import { ReadableStream, WritableStream } from "stream/web";
|
|
4
3
|
import { SupportedCodec } from "../container/webm";
|
|
5
|
-
import { WebmBase, WebmInput } from "./webm";
|
|
6
|
-
export declare type
|
|
7
|
-
|
|
8
|
-
eol?: {
|
|
9
|
-
/**ms */
|
|
10
|
-
duration: number;
|
|
11
|
-
durationElement: Uint8Array;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
export interface WebmLiveOption {
|
|
15
|
-
/**ms */
|
|
16
|
-
duration?: number;
|
|
17
|
-
}
|
|
4
|
+
import { WebmBase, WebmInput, WebmOption, WebmOutput } from "./webm";
|
|
5
|
+
export declare type WebmStreamOutput = WebmOutput;
|
|
6
|
+
export declare type WebmStreamOption = WebmOption;
|
|
18
7
|
export declare class WebmStream extends WebmBase {
|
|
19
8
|
audioStream: WritableStream<WebmInput>;
|
|
20
9
|
videoStream: WritableStream<WebmInput>;
|
|
21
|
-
webmStream: ReadableStream<
|
|
10
|
+
webmStream: ReadableStream<WebmStreamOutput>;
|
|
22
11
|
private controller;
|
|
23
12
|
constructor(tracks: {
|
|
24
13
|
width?: number;
|
|
@@ -27,5 +16,5 @@ export declare class WebmStream extends WebmBase {
|
|
|
27
16
|
codec: SupportedCodec;
|
|
28
17
|
clockRate: number;
|
|
29
18
|
trackNumber: number;
|
|
30
|
-
}[], options?:
|
|
19
|
+
}[], options?: WebmStreamOption);
|
|
31
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webmStream.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webmStream.ts"],"names":[],"mappings":";;;AAAA,oCAIoB;AAGpB,
|
|
1
|
+
{"version":3,"file":"webmStream.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webmStream.ts"],"names":[],"mappings":";;;AAAA,oCAIoB;AAGpB,iCAAqE;AAMrE,MAAa,UAAW,SAAQ,eAAQ;IAMtC,YACE,MAOG,EACH,UAA4B,EAAE;QAE9B,KAAK,CACH,MAAM,EACN,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,EACD,OAAO,CACR,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC1D,IAAI,UAAU,EAAE;YACd,IAAI,CAAC,WAAW,GAAG,IAAI,oBAAc,CAAC;gBACpC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;aACF,CAAC,CAAC;SACJ;QAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC1D,IAAI,UAAU,EAAE;YACd,IAAI,CAAC,WAAW,GAAG,IAAI,oBAAc,CAAC;gBACpC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;aACF,CAAC,CAAC;SACJ;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,oBAAc,CAAmB;YACrD,KAAK,EAAE,CAAC,UAAU,EAAE,EAAE;gBACpB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC/B,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACF;AAnDD,gCAmDC","sourcesContent":["import {\n ReadableStream,\n ReadableStreamController,\n WritableStream,\n} from \"stream/web\";\n\nimport { SupportedCodec } from \"../container/webm\";\nimport { WebmBase, WebmInput, WebmOption, WebmOutput } from \"./webm\";\n\nexport type WebmStreamOutput = WebmOutput;\n\nexport type WebmStreamOption = WebmOption;\n\nexport class WebmStream extends WebmBase {\n audioStream!: WritableStream<WebmInput>;\n videoStream!: WritableStream<WebmInput>;\n webmStream: ReadableStream<WebmStreamOutput>;\n private controller!: ReadableStreamController<WebmStreamOutput>;\n\n constructor(\n tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n trackNumber: number;\n }[],\n options: WebmStreamOption = {}\n ) {\n super(\n tracks,\n (output) => {\n this.controller.enqueue(output);\n },\n options\n );\n\n const audioTrack = tracks.find((t) => t.kind === \"audio\");\n if (audioTrack) {\n this.audioStream = new WritableStream({\n write: (input) => {\n this.processAudioInput(input);\n },\n });\n }\n\n const videoTrack = tracks.find((t) => t.kind === \"video\");\n if (videoTrack) {\n this.videoStream = new WritableStream({\n write: (input) => {\n this.processVideoInput(input);\n },\n });\n }\n\n this.webmStream = new ReadableStream<WebmStreamOutput>({\n start: (controller) => {\n this.controller = controller;\n },\n });\n\n this.start();\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Red, RtpPacket } from "../..";
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class RedHandler {
|
|
3
3
|
private readonly size;
|
|
4
4
|
private sequenceNumbers;
|
|
5
|
-
push(red: Red,
|
|
5
|
+
push(red: Red, base: RtpPacket): RtpPacket[];
|
|
6
6
|
}
|