werift 0.18.7 → 0.18.8
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 +1 -0
- package/lib/ice/src/ice.js +4 -0
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/rtp/src/helper.d.ts +1 -0
- package/lib/rtp/src/helper.js +6 -1
- package/lib/rtp/src/helper.js.map +1 -1
- package/lib/webrtc/src/index.d.ts +2 -0
- package/lib/webrtc/src/index.js +2 -0
- package/lib/webrtc/src/index.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +8 -5
- package/lib/webrtc/src/peerConnection.js +8 -0
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.js +1 -1
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +1 -2
- package/lib/webrtc/src/utils.js +1 -6
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/peerConnection.ts +20 -4
- package/src/transport/dtls.ts +2 -1
- package/src/utils.ts +0 -5
package/lib/webrtc/src/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ 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.createSelfSignedCertificate = exports.RtpBuilder = exports.parseIceServers = exports.compactNtp = exports.ntpTime = exports.timestampSeconds = exports.milliTime = exports.microTime = exports.reverseDirection = exports.andDirection = exports.reverseSimulcastDirection = exports.
|
|
6
|
+
exports.createSelfSignedCertificate = exports.RtpBuilder = exports.parseIceServers = exports.compactNtp = exports.ntpTime = exports.timestampSeconds = exports.milliTime = exports.microTime = exports.reverseDirection = exports.andDirection = exports.reverseSimulcastDirection = exports.isDtls = exports.fingerprint = void 0;
|
|
7
7
|
/* eslint-disable prefer-const */
|
|
8
8
|
const crypto_1 = require("crypto");
|
|
9
9
|
const debug_1 = __importDefault(require("debug"));
|
|
@@ -26,11 +26,6 @@ function isDtls(buf) {
|
|
|
26
26
|
return firstByte > 19 && firstByte < 64;
|
|
27
27
|
}
|
|
28
28
|
exports.isDtls = isDtls;
|
|
29
|
-
function isMedia(buf) {
|
|
30
|
-
const firstByte = buf[0];
|
|
31
|
-
return firstByte > 127 && firstByte < 192;
|
|
32
|
-
}
|
|
33
|
-
exports.isMedia = isMedia;
|
|
34
29
|
function reverseSimulcastDirection(dir) {
|
|
35
30
|
if (dir === "recv")
|
|
36
31
|
return "send";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":";;;;;;AAAA,iCAAiC;AACjC,mCAAoC;AACpC,kDAA0B;AAC1B,2CAAyC;AAEzC,0CAO0B;AAC1B,0DAA8D;AAE9D,uCAAqD;AACrD,2DAA+D;AAE/D,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAEjC,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,qCAAqC,CAAC,CAAC;AAEzD,SAAgB,WAAW,CAAC,IAAY,EAAE,QAAgB;IACxD,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE7D,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,CAAC;AAPD,kCAOC;AAED,SAAgB,MAAM,CAAC,GAAW;IAChC,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACzB,OAAO,SAAS,GAAG,EAAE,IAAI,SAAS,GAAG,EAAE,CAAC;AAC1C,CAAC;AAHD,wBAGC;AAED,SAAgB,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable prefer-const */\nimport { createHash } from \"crypto\";\nimport debug from \"debug\";\nimport { performance } from \"perf_hooks\";\n\nimport {\n bufferReader,\n bufferWriter,\n random16,\n random32,\n uint16Add,\n uint32Add,\n} from \"../../common/src\";\nimport { CipherContext } from \"../../dtls/src/context/cipher\";\nimport { Address } from \"../../ice/src\";\nimport { RtpHeader, RtpPacket } from \"../../rtp/src\";\nimport { Direction, Directions } from \"./media/rtpTransceiver\";\nimport { RTCIceServer } from \"./peerConnection\";\nconst now = require(\"nano-time\");\n\nconst log = debug(\"werift:packages/webrtc/src/utils.ts\");\n\nexport function fingerprint(file: Buffer, hashName: string) {\n const upper = (s: string) => s.toUpperCase();\n const colon = (s: any) => s.match(/(.{2})/g).join(\":\");\n\n const hash = createHash(hashName).update(file).digest(\"hex\");\n\n return colon(upper(hash));\n}\n\nexport function isDtls(buf: Buffer) {\n const firstByte = buf[0];\n return firstByte > 19 && firstByte < 64;\n}\n\nexport function reverseSimulcastDirection(dir: \"recv\" | \"send\") {\n if (dir === \"recv\") return \"send\";\n return \"recv\";\n}\n\nexport const andDirection = (a: Direction, b: Direction) =>\n Directions[Directions.indexOf(a) & Directions.indexOf(b)];\n\nexport function reverseDirection(dir: Direction): Direction {\n if (dir === \"sendonly\") return \"recvonly\";\n if (dir === \"recvonly\") return \"sendonly\";\n return dir;\n}\n\nexport const microTime = () => now.micro() as number;\n\nexport const milliTime = () => new Date().getTime();\n\nexport const timestampSeconds = () => Date.now() / 1000;\n\n/**https://datatracker.ietf.org/doc/html/rfc3550#section-4 */\nexport const ntpTime = () => {\n const now = performance.timeOrigin + performance.now() - Date.UTC(1900, 0, 1);\n\n const seconds = now / 1000;\n const [sec, msec] = seconds.toString().split(\".\").map(Number);\n\n const buf = bufferWriter([4, 4], [sec, msec]);\n\n return buf.readBigUInt64BE();\n};\n\n/**\n * https://datatracker.ietf.org/doc/html/rfc3550#section-4\n * @param ntp\n * @returns 32bit\n */\nexport const compactNtp = (ntp: bigint) => {\n const buf = bufferWriter([8], [ntp]);\n const [, sec, msec] = bufferReader(buf, [2, 2, 2, 2]);\n return bufferWriter([2, 2], [sec, msec]).readUInt32BE();\n};\n\nexport function parseIceServers(iceServers: RTCIceServer[]) {\n const url2Address = (url?: string) => {\n if (!url) return;\n const [address, port] = url.split(\":\");\n return [address, parseInt(port)] as Address;\n };\n\n const stunServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"stun:\"))?.urls.slice(5)\n );\n const turnServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"turn:\"))?.urls.slice(5)\n );\n const { credential, username } =\n iceServers.find(({ urls }) => urls.includes(\"turn:\")) || {};\n\n const options = {\n stunServer,\n turnServer,\n turnUsername: username,\n turnPassword: credential,\n };\n log(\"iceOptions\", options);\n return options;\n}\n\nexport class RtpBuilder {\n sequenceNumber = random16();\n timestamp = random32();\n\n create(payload: Buffer) {\n this.sequenceNumber = uint16Add(this.sequenceNumber, 1);\n this.timestamp = uint32Add(this.timestamp, 960);\n\n const header = new RtpHeader({\n sequenceNumber: this.sequenceNumber,\n timestamp: Number(this.timestamp),\n payloadType: 96,\n extension: true,\n marker: false,\n padding: false,\n });\n const rtp = new RtpPacket(header, payload);\n return rtp;\n }\n}\n\n/**\n *\n * @param signatureHash\n * @param namedCurveAlgorithm necessary when use ecdsa\n */\nexport const createSelfSignedCertificate =\n CipherContext.createSelfSignedCertificateWithKey;\n"]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from "./dataChannel";
|
|
|
6
6
|
export * from "./media/extension/rtcpFeedback";
|
|
7
7
|
export * from "./media/extension/rtpExtension";
|
|
8
8
|
export * from "./media/parameters";
|
|
9
|
+
export * from "./media/rtpReceiver";
|
|
10
|
+
export * from "./media/rtpSender";
|
|
9
11
|
export * from "./media/rtpTransceiver";
|
|
10
12
|
export * from "./media/track";
|
|
11
13
|
export * from "./nonstandard/recorder";
|
package/src/peerConnection.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { Message } from "../../ice/src/stun/message";
|
|
|
9
9
|
import { Protocol } from "../../ice/src/types/model";
|
|
10
10
|
import {
|
|
11
11
|
Address,
|
|
12
|
+
CandidatePair,
|
|
12
13
|
deepMerge,
|
|
13
14
|
InterfaceAddresses,
|
|
14
15
|
Recvonly,
|
|
@@ -481,6 +482,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
481
482
|
interfaceAddresses: this.config.iceInterfaceAddresses,
|
|
482
483
|
additionalHostAddresses: this.config.iceAdditionalHostAddresses,
|
|
483
484
|
filterStunResponse: this.config.iceFilterStunResponse,
|
|
485
|
+
filterCandidatePair: this.config.iceFilterCandidatePair,
|
|
484
486
|
useIpv4: this.config.iceUseIpv4,
|
|
485
487
|
useIpv6: this.config.iceUseIpv6,
|
|
486
488
|
});
|
|
@@ -835,10 +837,16 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
835
837
|
return bundle;
|
|
836
838
|
}
|
|
837
839
|
|
|
838
|
-
async setRemoteDescription(sessionDescription: {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
840
|
+
async setRemoteDescription(sessionDescription: RTCSessionDescriptionInit) {
|
|
841
|
+
if (
|
|
842
|
+
!sessionDescription.sdp ||
|
|
843
|
+
!sessionDescription.type ||
|
|
844
|
+
sessionDescription.type === "rollback" ||
|
|
845
|
+
sessionDescription.type === "pranswer"
|
|
846
|
+
) {
|
|
847
|
+
throw new Error("invalid sessionDescription");
|
|
848
|
+
}
|
|
849
|
+
|
|
842
850
|
// # parse and validate description
|
|
843
851
|
const remoteSdp = SessionDescription.parse(sessionDescription.sdp);
|
|
844
852
|
remoteSdp.type = sessionDescription.type;
|
|
@@ -1646,6 +1654,7 @@ export interface PeerConfig {
|
|
|
1646
1654
|
iceFilterStunResponse:
|
|
1647
1655
|
| ((message: Message, addr: Address, protocol: Protocol) => boolean)
|
|
1648
1656
|
| undefined;
|
|
1657
|
+
iceFilterCandidatePair: ((pair: CandidatePair) => boolean) | undefined;
|
|
1649
1658
|
dtls: Partial<{
|
|
1650
1659
|
keys: DtlsKeys;
|
|
1651
1660
|
}>;
|
|
@@ -1715,6 +1724,7 @@ export const defaultPeerConfig: PeerConfig = {
|
|
|
1715
1724
|
iceUseIpv4: true,
|
|
1716
1725
|
iceUseIpv6: true,
|
|
1717
1726
|
iceFilterStunResponse: undefined,
|
|
1727
|
+
iceFilterCandidatePair: undefined,
|
|
1718
1728
|
dtls: {},
|
|
1719
1729
|
bundlePolicy: "max-compat",
|
|
1720
1730
|
debug: {},
|
|
@@ -1737,3 +1747,9 @@ export interface RTCPeerConnectionIceEvent {
|
|
|
1737
1747
|
}
|
|
1738
1748
|
|
|
1739
1749
|
type Media = "audio" | "video";
|
|
1750
|
+
|
|
1751
|
+
export interface RTCSessionDescriptionInit {
|
|
1752
|
+
sdp?: string;
|
|
1753
|
+
type: RTCSdpType;
|
|
1754
|
+
}
|
|
1755
|
+
export type RTCSdpType = "answer" | "offer" | "pranswer" | "rollback";
|
package/src/transport/dtls.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { CipherContext } from "../../../dtls/src/context/cipher";
|
|
|
20
20
|
import { Profile } from "../../../dtls/src/context/srtp";
|
|
21
21
|
import { Connection } from "../../../ice/src";
|
|
22
22
|
import {
|
|
23
|
+
isMedia,
|
|
23
24
|
isRtcp,
|
|
24
25
|
RtcpPacket,
|
|
25
26
|
RtcpPacketConverter,
|
|
@@ -31,7 +32,7 @@ import {
|
|
|
31
32
|
import { keyLength, saltLength } from "../../../rtp/src/srtp/const";
|
|
32
33
|
import { RtpRouter } from "../media/router";
|
|
33
34
|
import { PeerConfig } from "../peerConnection";
|
|
34
|
-
import { fingerprint, isDtls
|
|
35
|
+
import { fingerprint, isDtls } from "../utils";
|
|
35
36
|
import { RTCIceTransport } from "./ice";
|
|
36
37
|
|
|
37
38
|
const log = debug("werift:packages/webrtc/src/transport/dtls.ts");
|
package/src/utils.ts
CHANGED
|
@@ -34,11 +34,6 @@ export function isDtls(buf: Buffer) {
|
|
|
34
34
|
return firstByte > 19 && firstByte < 64;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export function isMedia(buf: Buffer) {
|
|
38
|
-
const firstByte = buf[0];
|
|
39
|
-
return firstByte > 127 && firstByte < 192;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
37
|
export function reverseSimulcastDirection(dir: "recv" | "send") {
|
|
43
38
|
if (dir === "recv") return "send";
|
|
44
39
|
return "recv";
|