im-rtc-call-engine 1.0.0
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/LICENSE +21 -0
- package/dist/bytes.d.ts +11 -0
- package/dist/bytes.d.ts.map +1 -0
- package/dist/bytes.js +20 -0
- package/dist/bytes.js.map +1 -0
- package/dist/callOptions.d.ts +27 -0
- package/dist/callOptions.d.ts.map +1 -0
- package/dist/callOptions.js +19 -0
- package/dist/callOptions.js.map +1 -0
- package/dist/deviceId.d.ts +10 -0
- package/dist/deviceId.d.ts.map +1 -0
- package/dist/deviceId.js +55 -0
- package/dist/deviceId.js.map +1 -0
- package/dist/engine.d.ts +302 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +489 -0
- package/dist/engine.js.map +1 -0
- package/dist/engineBus.d.ts +16 -0
- package/dist/engineBus.d.ts.map +1 -0
- package/dist/engineBus.js +89 -0
- package/dist/engineBus.js.map +1 -0
- package/dist/engineWiring.d.ts +40 -0
- package/dist/engineWiring.d.ts.map +1 -0
- package/dist/engineWiring.js +57 -0
- package/dist/engineWiring.js.map +1 -0
- package/dist/errors.d.ts +185 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +253 -0
- package/dist/errors.js.map +1 -0
- package/dist/eventBus.d.ts +24 -0
- package/dist/eventBus.d.ts.map +1 -0
- package/dist/eventBus.js +50 -0
- package/dist/eventBus.js.map +1 -0
- package/dist/events.d.ts +220 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +35 -0
- package/dist/events.js.map +1 -0
- package/dist/frameLoop.d.ts +93 -0
- package/dist/frameLoop.d.ts.map +1 -0
- package/dist/frameLoop.js +346 -0
- package/dist/frameLoop.js.map +1 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +64 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +101 -0
- package/dist/logger.js.map +1 -0
- package/dist/media/engineMediaApi.d.ts +40 -0
- package/dist/media/engineMediaApi.d.ts.map +1 -0
- package/dist/media/engineMediaApi.js +71 -0
- package/dist/media/engineMediaApi.js.map +1 -0
- package/dist/media/firstFrameGate.d.ts +47 -0
- package/dist/media/firstFrameGate.d.ts.map +1 -0
- package/dist/media/firstFrameGate.js +117 -0
- package/dist/media/firstFrameGate.js.map +1 -0
- package/dist/media/mediaAdapter.d.ts +135 -0
- package/dist/media/mediaAdapter.d.ts.map +1 -0
- package/dist/media/mediaAdapter.js +2 -0
- package/dist/media/mediaAdapter.js.map +1 -0
- package/dist/media/mediaBridge.d.ts +99 -0
- package/dist/media/mediaBridge.d.ts.map +1 -0
- package/dist/media/mediaBridge.js +186 -0
- package/dist/media/mediaBridge.js.map +1 -0
- package/dist/media/mediaPlane.d.ts +58 -0
- package/dist/media/mediaPlane.d.ts.map +1 -0
- package/dist/media/mediaPlane.js +119 -0
- package/dist/media/mediaPlane.js.map +1 -0
- package/dist/media/videoProfile.d.ts +79 -0
- package/dist/media/videoProfile.d.ts.map +1 -0
- package/dist/media/videoProfile.js +46 -0
- package/dist/media/videoProfile.js.map +1 -0
- package/dist/media/videoProfile.test.d.ts +2 -0
- package/dist/media/videoProfile.test.d.ts.map +1 -0
- package/dist/media/videoProfile.test.js +26 -0
- package/dist/media/videoProfile.test.js.map +1 -0
- package/dist/media/viewRegistry.d.ts +75 -0
- package/dist/media/viewRegistry.d.ts.map +1 -0
- package/dist/media/viewRegistry.js +130 -0
- package/dist/media/viewRegistry.js.map +1 -0
- package/dist/media/webrtcAdapter.d.ts +158 -0
- package/dist/media/webrtcAdapter.d.ts.map +1 -0
- package/dist/media/webrtcAdapter.js +502 -0
- package/dist/media/webrtcAdapter.js.map +1 -0
- package/dist/protocolId.d.ts +14 -0
- package/dist/protocolId.d.ts.map +1 -0
- package/dist/protocolId.js +109 -0
- package/dist/protocolId.js.map +1 -0
- package/dist/reasons.d.ts +63 -0
- package/dist/reasons.d.ts.map +1 -0
- package/dist/reasons.js +81 -0
- package/dist/reasons.js.map +1 -0
- package/dist/redact.d.ts +19 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +50 -0
- package/dist/redact.js.map +1 -0
- package/dist/signaling/backoff.d.ts +17 -0
- package/dist/signaling/backoff.d.ts.map +1 -0
- package/dist/signaling/backoff.js +23 -0
- package/dist/signaling/backoff.js.map +1 -0
- package/dist/signaling/candidate.d.ts +19 -0
- package/dist/signaling/candidate.d.ts.map +1 -0
- package/dist/signaling/candidate.js +22 -0
- package/dist/signaling/candidate.js.map +1 -0
- package/dist/signaling/caseMapping.d.ts +19 -0
- package/dist/signaling/caseMapping.d.ts.map +1 -0
- package/dist/signaling/caseMapping.js +34 -0
- package/dist/signaling/caseMapping.js.map +1 -0
- package/dist/signaling/connection.d.ts +110 -0
- package/dist/signaling/connection.d.ts.map +1 -0
- package/dist/signaling/connection.js +365 -0
- package/dist/signaling/connection.js.map +1 -0
- package/dist/signaling/connectionFactory.d.ts +55 -0
- package/dist/signaling/connectionFactory.d.ts.map +1 -0
- package/dist/signaling/connectionFactory.js +29 -0
- package/dist/signaling/connectionFactory.js.map +1 -0
- package/dist/signaling/connectionTypes.d.ts +94 -0
- package/dist/signaling/connectionTypes.d.ts.map +1 -0
- package/dist/signaling/connectionTypes.js +2 -0
- package/dist/signaling/connectionTypes.js.map +1 -0
- package/dist/signaling/discipline.d.ts +6 -0
- package/dist/signaling/discipline.d.ts.map +1 -0
- package/dist/signaling/discipline.js +100 -0
- package/dist/signaling/discipline.js.map +1 -0
- package/dist/signaling/enums.d.ts +53 -0
- package/dist/signaling/enums.d.ts.map +1 -0
- package/dist/signaling/enums.js +52 -0
- package/dist/signaling/enums.js.map +1 -0
- package/dist/signaling/envelope.d.ts +31 -0
- package/dist/signaling/envelope.d.ts.map +1 -0
- package/dist/signaling/envelope.js +91 -0
- package/dist/signaling/envelope.js.map +1 -0
- package/dist/signaling/fieldSpec.d.ts +101 -0
- package/dist/signaling/fieldSpec.d.ts.map +1 -0
- package/dist/signaling/fieldSpec.js +130 -0
- package/dist/signaling/fieldSpec.js.map +1 -0
- package/dist/signaling/frameSender.d.ts +34 -0
- package/dist/signaling/frameSender.d.ts.map +1 -0
- package/dist/signaling/frameSender.js +57 -0
- package/dist/signaling/frameSender.js.map +1 -0
- package/dist/signaling/frames.call.d.ts +299 -0
- package/dist/signaling/frames.call.d.ts.map +1 -0
- package/dist/signaling/frames.call.js +149 -0
- package/dist/signaling/frames.call.js.map +1 -0
- package/dist/signaling/frames.room.d.ts +566 -0
- package/dist/signaling/frames.room.d.ts.map +1 -0
- package/dist/signaling/frames.room.js +165 -0
- package/dist/signaling/frames.room.js.map +1 -0
- package/dist/signaling/frames.sys.d.ts +145 -0
- package/dist/signaling/frames.sys.d.ts.map +1 -0
- package/dist/signaling/frames.sys.js +53 -0
- package/dist/signaling/frames.sys.js.map +1 -0
- package/dist/signaling/handshakeGiveUp.d.ts +36 -0
- package/dist/signaling/handshakeGiveUp.d.ts.map +1 -0
- package/dist/signaling/handshakeGiveUp.js +48 -0
- package/dist/signaling/handshakeGiveUp.js.map +1 -0
- package/dist/signaling/heartbeat.d.ts +34 -0
- package/dist/signaling/heartbeat.d.ts.map +1 -0
- package/dist/signaling/heartbeat.js +52 -0
- package/dist/signaling/heartbeat.js.map +1 -0
- package/dist/signaling/pendingRequests.d.ts +33 -0
- package/dist/signaling/pendingRequests.d.ts.map +1 -0
- package/dist/signaling/pendingRequests.js +57 -0
- package/dist/signaling/pendingRequests.js.map +1 -0
- package/dist/signaling/reconnector.d.ts +43 -0
- package/dist/signaling/reconnector.d.ts.map +1 -0
- package/dist/signaling/reconnector.js +76 -0
- package/dist/signaling/reconnector.js.map +1 -0
- package/dist/signaling/registry.d.ts +100 -0
- package/dist/signaling/registry.d.ts.map +1 -0
- package/dist/signaling/registry.js +217 -0
- package/dist/signaling/registry.js.map +1 -0
- package/dist/signaling/resumeDeadline.d.ts +48 -0
- package/dist/signaling/resumeDeadline.d.ts.map +1 -0
- package/dist/signaling/resumeDeadline.js +89 -0
- package/dist/signaling/resumeDeadline.js.map +1 -0
- package/dist/signaling/tokenExpiry.d.ts +89 -0
- package/dist/signaling/tokenExpiry.d.ts.map +1 -0
- package/dist/signaling/tokenExpiry.js +106 -0
- package/dist/signaling/tokenExpiry.js.map +1 -0
- package/dist/signaling/webSocket.d.ts +59 -0
- package/dist/signaling/webSocket.d.ts.map +1 -0
- package/dist/signaling/webSocket.js +50 -0
- package/dist/signaling/webSocket.js.map +1 -0
- package/dist/state/callMachine.d.ts +56 -0
- package/dist/state/callMachine.d.ts.map +1 -0
- package/dist/state/callMachine.js +176 -0
- package/dist/state/callMachine.js.map +1 -0
- package/dist/state/callRecv.d.ts +12 -0
- package/dist/state/callRecv.d.ts.map +1 -0
- package/dist/state/callRecv.js +255 -0
- package/dist/state/callRecv.js.map +1 -0
- package/dist/state/engineMachine.d.ts +41 -0
- package/dist/state/engineMachine.d.ts.map +1 -0
- package/dist/state/engineMachine.js +210 -0
- package/dist/state/engineMachine.js.map +1 -0
- package/dist/state/forceEnd.d.ts +44 -0
- package/dist/state/forceEnd.d.ts.map +1 -0
- package/dist/state/forceEnd.js +96 -0
- package/dist/state/forceEnd.js.map +1 -0
- package/dist/state/roomMachine.d.ts +92 -0
- package/dist/state/roomMachine.d.ts.map +1 -0
- package/dist/state/roomMachine.js +319 -0
- package/dist/state/roomMachine.js.map +1 -0
- package/dist/state/roomRecv.d.ts +7 -0
- package/dist/state/roomRecv.d.ts.map +1 -0
- package/dist/state/roomRecv.js +209 -0
- package/dist/state/roomRecv.js.map +1 -0
- package/dist/state/types.d.ts +61 -0
- package/dist/state/types.d.ts.map +1 -0
- package/dist/state/types.js +30 -0
- package/dist/state/types.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { VideoProfiles, defaultVideoProfile, videoConstraints } from './videoProfile.js';
|
|
3
|
+
describe('画质档位', () => {
|
|
4
|
+
it('默认是 720p——1080p 在九宫格里只是白烧上行带宽', () => {
|
|
5
|
+
expect(defaultVideoProfile).toBe(VideoProfiles.p720);
|
|
6
|
+
});
|
|
7
|
+
/*
|
|
8
|
+
`exact` 会在不支持该分辨率的摄像头上抛 OverconstrainedError,通话直接打不出去。
|
|
9
|
+
画质是偏好不是硬条件,所以只能用 ideal。
|
|
10
|
+
*/
|
|
11
|
+
it('约束用 ideal 不用 exact', () => {
|
|
12
|
+
const constraints = videoConstraints(VideoProfiles.p1080);
|
|
13
|
+
expect(constraints.width).toEqual({ ideal: 1920 });
|
|
14
|
+
expect(constraints.height).toEqual({ ideal: 1080 });
|
|
15
|
+
expect(constraints.frameRate).toEqual({ ideal: 30 });
|
|
16
|
+
expect(JSON.stringify(constraints)).not.toContain('exact');
|
|
17
|
+
});
|
|
18
|
+
/*
|
|
19
|
+
这个数字要和服务端 internal/sfu/bwe.go 的 bitrateHigh 对得上:
|
|
20
|
+
那边拿它做带宽预算,对不上的话降层判断是按一个错的数字做的。
|
|
21
|
+
*/
|
|
22
|
+
it('720p 的码率与服务端 simulcast h 层的目标值一致', () => {
|
|
23
|
+
expect(VideoProfiles.p720.maxBitrateBps).toBe(1_500_000);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=videoProfile.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"videoProfile.test.js","sourceRoot":"","sources":["../../src/media/videoProfile.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEzF,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH;;;MAGE;IACF,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,WAAW,GAAG,gBAAgB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH;;;MAGE;IACF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uid ↔ 视频元素的挂载登记。
|
|
3
|
+
*
|
|
4
|
+
* # 为什么这层要存在
|
|
5
|
+
*
|
|
6
|
+
* CONVENTIONS §1:**uikit 禁止直接碰 `RTCPeerConnection`**,视频一律经
|
|
7
|
+
* `engine.attachView(uid, el)` 挂载。有了这条边界,换媒体实现时 uikit 一行不用改。
|
|
8
|
+
*
|
|
9
|
+
* # 为什么不能「收到轨道就挂上去」
|
|
10
|
+
*
|
|
11
|
+
* 轨道到达与「知道它是谁的」是**两个独立的时序**:`ontrack` 在第一个 RTP 包到达时触发,
|
|
12
|
+
* 而 `room.track_published`(带 uid)是信令帧,两者谁先到都可能。
|
|
13
|
+
* 所以这里按 track_id 收轨道、按 uid 认领,**认领可以迟到**——
|
|
14
|
+
* 迟到时把已经攒着的轨道补挂上去。漏掉这一步的表现是「有声音没画面」,
|
|
15
|
+
* 且只在网络较快时偶发。
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* ViewElement 是能承载 MediaStream 的元素。取 DOM 的最小交集,便于在测试里做替身。
|
|
19
|
+
*
|
|
20
|
+
* `srcObject` 的类型跟 `HTMLMediaElement` 保持一致(`MediaProvider | null`)——
|
|
21
|
+
* 写成更窄的 `MediaStream | null` 的话,真正的 `<video>` 反而**赋不进来**:
|
|
22
|
+
* TS 的可变属性是不变的,窄类型不接受宽类型。
|
|
23
|
+
*/
|
|
24
|
+
export interface ViewElement {
|
|
25
|
+
srcObject: MediaProvider | null;
|
|
26
|
+
}
|
|
27
|
+
/** ViewRegistry 管「哪条轨道属于谁」与「谁挂在哪个元素上」。 */
|
|
28
|
+
export declare class ViewRegistry {
|
|
29
|
+
/** uid → 该用户的媒体流(音视频合在一条流里,浏览器才会同步播放)。 */
|
|
30
|
+
private readonly streams;
|
|
31
|
+
/** uid → 已挂载的元素。 */
|
|
32
|
+
private readonly views;
|
|
33
|
+
/** track_id → 还没认领归属的轨道。 */
|
|
34
|
+
private readonly orphans;
|
|
35
|
+
/** track_id → uid,认领之后的记账,退订时按 track_id 摘轨道要用。 */
|
|
36
|
+
private readonly owners;
|
|
37
|
+
/**
|
|
38
|
+
* addTrack 收下一条下行轨道。
|
|
39
|
+
*
|
|
40
|
+
* uid 为空表示「还不知道是谁的」——先存进 orphans,等 claim 来认领。
|
|
41
|
+
*/
|
|
42
|
+
addTrack(trackId: string, track: MediaStreamTrack, uid: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* claim 认领一条之前不知道归属的轨道。
|
|
45
|
+
*
|
|
46
|
+
* engine 在 `room.track_published` 到达、或状态机补上 track_id → uid 之后调它。
|
|
47
|
+
* 认领不到(轨道还没来)时什么都不做——轨道到达时会走 addTrack 那条路。
|
|
48
|
+
*/
|
|
49
|
+
claim(trackId: string, uid: string): void;
|
|
50
|
+
/** removeTrack 摘掉一条轨道(对方停发或退订)。 */
|
|
51
|
+
removeTrack(trackId: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* attach 把某个 uid 的画面挂到元素上;`el` 传 null 表示卸载。
|
|
54
|
+
*
|
|
55
|
+
* **卸载必须做**:组件卸载时不清 `srcObject`,被卸掉的 <video> 会连着
|
|
56
|
+
* MediaStream 一起被引用,画面停了但解码器还占着(CONVENTIONS §5)。
|
|
57
|
+
*/
|
|
58
|
+
attach(uid: string, el: ViewElement | null): void;
|
|
59
|
+
/**
|
|
60
|
+
* claimedTracks 列出**已认领**的 track_id → 归属。
|
|
61
|
+
*
|
|
62
|
+
* 给 `MediaBridge.syncRemoteTracks` 做对账用:状态机里已经没有的那些要摘掉。
|
|
63
|
+
* 返回快照而不是内部 Map——调用方要边遍历边 `removeTrack`。
|
|
64
|
+
*/
|
|
65
|
+
claimedTracks(): [string, string][];
|
|
66
|
+
/** viewOf 取某人此刻挂着的元素(没挂为 undefined)。 */
|
|
67
|
+
viewOf(uid: string): ViewElement | undefined;
|
|
68
|
+
/** streamFor 取某人的流,宿主想自己挂载时用。 */
|
|
69
|
+
streamFor(uid: string): MediaStream | undefined;
|
|
70
|
+
/** clear 清空全部登记(通话结束 / logout)。 */
|
|
71
|
+
clear(): void;
|
|
72
|
+
private streamOf;
|
|
73
|
+
private refresh;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=viewRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewRegistry.d.ts","sourceRoot":"","sources":["../../src/media/viewRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC;AAED,0CAA0C;AAC1C,qBAAa,YAAY;IACvB,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,oBAAoB;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,4BAA4B;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IAEpD;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAWrE;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAMzC,mCAAmC;IACnC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAelC;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI;IAWjD;;;;;OAKG;IACH,aAAa,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;IAInC,wCAAwC;IACxC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI5C,iCAAiC;IACjC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI/C,mCAAmC;IACnC,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,OAAO;CAKhB"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uid ↔ 视频元素的挂载登记。
|
|
3
|
+
*
|
|
4
|
+
* # 为什么这层要存在
|
|
5
|
+
*
|
|
6
|
+
* CONVENTIONS §1:**uikit 禁止直接碰 `RTCPeerConnection`**,视频一律经
|
|
7
|
+
* `engine.attachView(uid, el)` 挂载。有了这条边界,换媒体实现时 uikit 一行不用改。
|
|
8
|
+
*
|
|
9
|
+
* # 为什么不能「收到轨道就挂上去」
|
|
10
|
+
*
|
|
11
|
+
* 轨道到达与「知道它是谁的」是**两个独立的时序**:`ontrack` 在第一个 RTP 包到达时触发,
|
|
12
|
+
* 而 `room.track_published`(带 uid)是信令帧,两者谁先到都可能。
|
|
13
|
+
* 所以这里按 track_id 收轨道、按 uid 认领,**认领可以迟到**——
|
|
14
|
+
* 迟到时把已经攒着的轨道补挂上去。漏掉这一步的表现是「有声音没画面」,
|
|
15
|
+
* 且只在网络较快时偶发。
|
|
16
|
+
*/
|
|
17
|
+
/** ViewRegistry 管「哪条轨道属于谁」与「谁挂在哪个元素上」。 */
|
|
18
|
+
export class ViewRegistry {
|
|
19
|
+
/** uid → 该用户的媒体流(音视频合在一条流里,浏览器才会同步播放)。 */
|
|
20
|
+
streams = new Map();
|
|
21
|
+
/** uid → 已挂载的元素。 */
|
|
22
|
+
views = new Map();
|
|
23
|
+
/** track_id → 还没认领归属的轨道。 */
|
|
24
|
+
orphans = new Map();
|
|
25
|
+
/** track_id → uid,认领之后的记账,退订时按 track_id 摘轨道要用。 */
|
|
26
|
+
owners = new Map();
|
|
27
|
+
/**
|
|
28
|
+
* addTrack 收下一条下行轨道。
|
|
29
|
+
*
|
|
30
|
+
* uid 为空表示「还不知道是谁的」——先存进 orphans,等 claim 来认领。
|
|
31
|
+
*/
|
|
32
|
+
addTrack(trackId, track, uid) {
|
|
33
|
+
if (uid === '') {
|
|
34
|
+
this.orphans.set(trackId, track);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.orphans.delete(trackId);
|
|
38
|
+
this.owners.set(trackId, uid);
|
|
39
|
+
this.streamOf(uid).addTrack(track);
|
|
40
|
+
this.refresh(uid);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* claim 认领一条之前不知道归属的轨道。
|
|
44
|
+
*
|
|
45
|
+
* engine 在 `room.track_published` 到达、或状态机补上 track_id → uid 之后调它。
|
|
46
|
+
* 认领不到(轨道还没来)时什么都不做——轨道到达时会走 addTrack 那条路。
|
|
47
|
+
*/
|
|
48
|
+
claim(trackId, uid) {
|
|
49
|
+
const track = this.orphans.get(trackId);
|
|
50
|
+
if (track === undefined || uid === '')
|
|
51
|
+
return;
|
|
52
|
+
this.addTrack(trackId, track, uid);
|
|
53
|
+
}
|
|
54
|
+
/** removeTrack 摘掉一条轨道(对方停发或退订)。 */
|
|
55
|
+
removeTrack(trackId) {
|
|
56
|
+
this.orphans.delete(trackId);
|
|
57
|
+
const uid = this.owners.get(trackId);
|
|
58
|
+
if (uid === undefined)
|
|
59
|
+
return;
|
|
60
|
+
this.owners.delete(trackId);
|
|
61
|
+
const stream = this.streams.get(uid);
|
|
62
|
+
if (stream === undefined)
|
|
63
|
+
return;
|
|
64
|
+
for (const track of stream.getTracks()) {
|
|
65
|
+
if (track.id === trackId)
|
|
66
|
+
stream.removeTrack(track);
|
|
67
|
+
}
|
|
68
|
+
if (stream.getTracks().length === 0)
|
|
69
|
+
this.streams.delete(uid);
|
|
70
|
+
this.refresh(uid);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* attach 把某个 uid 的画面挂到元素上;`el` 传 null 表示卸载。
|
|
74
|
+
*
|
|
75
|
+
* **卸载必须做**:组件卸载时不清 `srcObject`,被卸掉的 <video> 会连着
|
|
76
|
+
* MediaStream 一起被引用,画面停了但解码器还占着(CONVENTIONS §5)。
|
|
77
|
+
*/
|
|
78
|
+
attach(uid, el) {
|
|
79
|
+
if (el === null) {
|
|
80
|
+
const previous = this.views.get(uid);
|
|
81
|
+
if (previous !== undefined)
|
|
82
|
+
previous.srcObject = null;
|
|
83
|
+
this.views.delete(uid);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.views.set(uid, el);
|
|
87
|
+
this.refresh(uid);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* claimedTracks 列出**已认领**的 track_id → 归属。
|
|
91
|
+
*
|
|
92
|
+
* 给 `MediaBridge.syncRemoteTracks` 做对账用:状态机里已经没有的那些要摘掉。
|
|
93
|
+
* 返回快照而不是内部 Map——调用方要边遍历边 `removeTrack`。
|
|
94
|
+
*/
|
|
95
|
+
claimedTracks() {
|
|
96
|
+
return [...this.owners];
|
|
97
|
+
}
|
|
98
|
+
/** viewOf 取某人此刻挂着的元素(没挂为 undefined)。 */
|
|
99
|
+
viewOf(uid) {
|
|
100
|
+
return this.views.get(uid);
|
|
101
|
+
}
|
|
102
|
+
/** streamFor 取某人的流,宿主想自己挂载时用。 */
|
|
103
|
+
streamFor(uid) {
|
|
104
|
+
return this.streams.get(uid);
|
|
105
|
+
}
|
|
106
|
+
/** clear 清空全部登记(通话结束 / logout)。 */
|
|
107
|
+
clear() {
|
|
108
|
+
for (const [, el] of this.views)
|
|
109
|
+
el.srcObject = null;
|
|
110
|
+
this.views.clear();
|
|
111
|
+
this.streams.clear();
|
|
112
|
+
this.orphans.clear();
|
|
113
|
+
this.owners.clear();
|
|
114
|
+
}
|
|
115
|
+
streamOf(uid) {
|
|
116
|
+
let stream = this.streams.get(uid);
|
|
117
|
+
if (stream === undefined) {
|
|
118
|
+
stream = new MediaStream();
|
|
119
|
+
this.streams.set(uid, stream);
|
|
120
|
+
}
|
|
121
|
+
return stream;
|
|
122
|
+
}
|
|
123
|
+
refresh(uid) {
|
|
124
|
+
const el = this.views.get(uid);
|
|
125
|
+
if (el === undefined)
|
|
126
|
+
return;
|
|
127
|
+
el.srcObject = this.streams.get(uid) ?? null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=viewRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewRegistry.js","sourceRoot":"","sources":["../../src/media/viewRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { PcRole } from '../signaling/enums.js';
|
|
2
|
+
import type { LocalTrackInfo, MediaAdapter, MediaAdapterEvents, MediaSource } from './mediaAdapter.js';
|
|
3
|
+
import type { VideoProfile } from './videoProfile.js';
|
|
4
|
+
/**
|
|
5
|
+
* 浏览器 WebRTC 的媒体适配器。
|
|
6
|
+
*
|
|
7
|
+
* **两条 PeerConnection,各有固定 offerer**(协议 §3.3):pub 由本端 offer、
|
|
8
|
+
* sub 由服务端 offer。固定 offerer 就没有 glare,所以这里**没有一行**
|
|
9
|
+
* perfect negotiation / rollback。
|
|
10
|
+
*
|
|
11
|
+
* **不配 iceServers**:SFU 有公网 IP,客户端直连它,不部署 TURN(拍板 §11-2)。
|
|
12
|
+
*/
|
|
13
|
+
export declare class WebRTCAdapter implements MediaAdapter {
|
|
14
|
+
private readonly source;
|
|
15
|
+
private pub;
|
|
16
|
+
private sub;
|
|
17
|
+
private events;
|
|
18
|
+
/** cid → 本端轨道。cid 就是轨道的 id(见 LocalTrackInfo)。 */
|
|
19
|
+
private readonly locals;
|
|
20
|
+
/** 候选缓存:PC 的远端描述还没设时收到的候选先存着(乱序是常态)。 */
|
|
21
|
+
private readonly pendingCandidates;
|
|
22
|
+
/** 采集画质档位。见 videoProfile.ts:**策略归宿主**,不是服务端下发的。 */
|
|
23
|
+
private readonly video;
|
|
24
|
+
/** 已经在预览的摄像头。发布时复用它,不重开设备。 */
|
|
25
|
+
private preview;
|
|
26
|
+
/** 预览那条轨道是否已经挂到 pub 上。`addTrack` 同一条轨道两次会抛异常。 */
|
|
27
|
+
private cameraPublished;
|
|
28
|
+
/**
|
|
29
|
+
* acquireCamera 已经认领了预览(发布中或已发布)。**进门就置位**,不等预览起完:
|
|
30
|
+
* 预览还在路上时来一句 `stopLocalPreview`,不能把马上要发布的这条停掉。
|
|
31
|
+
*/
|
|
32
|
+
private cameraClaimed;
|
|
33
|
+
/** 摄像头挂上 pub 的 sender。通话中关了再开要靠它 `replaceTrack`,不重新协商。 */
|
|
34
|
+
private cameraSender;
|
|
35
|
+
/**
|
|
36
|
+
* 预览意图的序号:每次 start / stop 加一。
|
|
37
|
+
* `stopLocalPreview` 等完在起的那一次之后序号变了,说明这期间又有人要了预览——听后来的。
|
|
38
|
+
*/
|
|
39
|
+
private previewIntent;
|
|
40
|
+
/** 通话中开关摄像头排成一队:连点时上一次的 getUserMedia 还没回来,下一次不能插队。 */
|
|
41
|
+
private cameraToggle;
|
|
42
|
+
/** 已经拿到并挂在 pub 上的麦克风轨道 cid;没有是 null。见 {@link publishedMicrophoneCid}。 */
|
|
43
|
+
private micCid;
|
|
44
|
+
/** 麦克风权限已经探过一次。见 `probeMicrophone`:探测不是免费的。 */
|
|
45
|
+
private micProbed;
|
|
46
|
+
/** 摄像头权限已经探过一次。见 `probeCamera`。 */
|
|
47
|
+
private cameraProbed;
|
|
48
|
+
/**
|
|
49
|
+
* 正在起的那次预览。**并发的 startLocalPreview / acquireCamera / probeCamera 共用这一次 getUserMedia**。
|
|
50
|
+
*
|
|
51
|
+
* 来电页的预览还没起完、用户就点了接听:接听路径要探权限、要起预览、进房后还要发布,
|
|
52
|
+
* 三处各自去 `getUserMedia` 就是把摄像头开两三次——多出来的那条流没人收,指示灯灭不掉。
|
|
53
|
+
*/
|
|
54
|
+
private previewOpening;
|
|
55
|
+
/** close() 一次加一。起到一半被 close 掉的预览靠它认出自己已经作废。 */
|
|
56
|
+
private closeGeneration;
|
|
57
|
+
/** source 缺省时用 navigator.mediaDevices;端到端测试可以传合成源。 */
|
|
58
|
+
constructor(source?: MediaSource, videoProfile?: VideoProfile);
|
|
59
|
+
open(events: MediaAdapterEvents): void;
|
|
60
|
+
/** 下一个上行 offer 要不要带 ICE restart。见 restartPubICE()。 */
|
|
61
|
+
private pubICERestartPending;
|
|
62
|
+
private createPeer;
|
|
63
|
+
acquireMicrophone(): Promise<LocalTrackInfo>;
|
|
64
|
+
probeMicrophone(): Promise<void>;
|
|
65
|
+
probeCamera(): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* startLocalPreview 只起采集,不挂到 pub 上。
|
|
68
|
+
*
|
|
69
|
+
* **拨出中就该看得见自己**(草图 §03-E),可那时还没有房间、推不了流。
|
|
70
|
+
* 所以采集与发布拆成两步,`acquireCamera` 复用这条轨道——
|
|
71
|
+
* 不复用的话第二次 `getUserMedia` 会去抢同一个摄像头。
|
|
72
|
+
*/
|
|
73
|
+
startLocalPreview(): Promise<LocalTrackInfo>;
|
|
74
|
+
/**
|
|
75
|
+
* stopLocalPreview 停掉**还没发布**的预览,摄像头指示灯随之熄灭(交互稿 §01 v3.7)。
|
|
76
|
+
*
|
|
77
|
+
* 进房前(来电页 / 拨出中)关摄像头原先只是把画面藏起来,采集一直开到通话结束。
|
|
78
|
+
* 已经发布(或正在发布)的不停:通话中关摄像头走 `setMuted`,发送器与协商要留着。
|
|
79
|
+
*/
|
|
80
|
+
stopLocalPreview(): Promise<void>;
|
|
81
|
+
private openPreview;
|
|
82
|
+
acquireCamera(simulcast?: boolean): Promise<LocalTrackInfo>;
|
|
83
|
+
/**
|
|
84
|
+
* addVideoTrack 把一条上行视频挂到 pub 上。
|
|
85
|
+
*
|
|
86
|
+
* # 为什么不能用 addTrack
|
|
87
|
+
*
|
|
88
|
+
* `addTrack` 只会产生**一个 encoding**,浏览器里发 simulcast 必须在建
|
|
89
|
+
* transceiver 时就把 `sendEncodings` 给出来——协商之后再 `setParameters`
|
|
90
|
+
* 加层是加不上的(规范不允许改 encoding 的条数)。
|
|
91
|
+
*
|
|
92
|
+
* 这正是之前那个洞:`publishCamera(simulcast = true)` 的这个参数一路传进了
|
|
93
|
+
* `room.publish` 帧、**告诉服务端「我是 simulcast」**,可媒体面走的是裸
|
|
94
|
+
* `addTrack`,实际只发一层。服务端于是只看到空 RID 的单层(`ridToLayer("")`
|
|
95
|
+
* 当成 h),层选择无从谈起:订阅者报 `l` 也只能收到全速率的 h
|
|
96
|
+
* (`selectLayer` 的兜底),弱下行的那一方被自己的全速率流压死。
|
|
97
|
+
*
|
|
98
|
+
* `streams: [stream]` 不能省:msid 的第二段就是 cid,服务端靠它认领 m-line
|
|
99
|
+
* (协议 §3.2)。省掉它服务端永远认不回这条轨道。
|
|
100
|
+
*/
|
|
101
|
+
private addVideoTrack;
|
|
102
|
+
/**
|
|
103
|
+
* acquire 拿一条本端轨道并挂到 pub PC 上。
|
|
104
|
+
*
|
|
105
|
+
* `getUserMedia` **只在 localhost / HTTPS 可用**;权限被拒要有明确的界面态与重试,
|
|
106
|
+
* **不弹 alert**(CONVENTIONS §8)——所以这里只抛结构化错误,界面怎么表现由 uikit 决定。
|
|
107
|
+
*/
|
|
108
|
+
private acquire;
|
|
109
|
+
publishedMicrophoneCid(): string | null;
|
|
110
|
+
/** 摄像头「已发布」= 预览那条轨道真的挂上了 pub(`cameraPublished`),只在预览不算。 */
|
|
111
|
+
publishedCameraCid(): string | null;
|
|
112
|
+
/** getStreamOrThrow 取流,并把浏览器的异常收敛成结构化错误。 */
|
|
113
|
+
private getStreamOrThrow;
|
|
114
|
+
/**
|
|
115
|
+
* applyVideoBitrate 给上行视频压一个码率上限。
|
|
116
|
+
*
|
|
117
|
+
* **不设的话浏览器会自己往上飙**:Chrome 对 720p 的默认上限远高于我们给
|
|
118
|
+
* simulcast h 层定的目标值,服务端的带宽预算(`bwe.go` 的 `bitrateHigh`)
|
|
119
|
+
* 就成了一个对不上的数字,降层判断跟着不准。
|
|
120
|
+
*
|
|
121
|
+
* 失败只记日志:码率是画质偏好,`setParameters` 被拒不该让通话打不出去。
|
|
122
|
+
*/
|
|
123
|
+
private applyVideoBitrate;
|
|
124
|
+
createPubOffer(): Promise<string>;
|
|
125
|
+
/**
|
|
126
|
+
* restartPubICE 让**下一个**上行 offer 带上 ICE restart(换一对新 ufrag/pwd 重新打洞)。
|
|
127
|
+
*
|
|
128
|
+
* `pub` 那条 PC 的 offerer 恒为本端(协议 §3.3),它 `failed` 了只能自己救;
|
|
129
|
+
* `sub` 那条由服务端救——**各自重启自己 offer 的那条**,不需要新的协议帧,也不会 glare。
|
|
130
|
+
* 做成「置一个位、下一个 offer 生效」而不是「立刻发帧」:发帧是 engine 的事,媒体层不认识信令。
|
|
131
|
+
*/
|
|
132
|
+
restartPubICE(): void;
|
|
133
|
+
applyPubAnswer(sdp: string): Promise<void>;
|
|
134
|
+
answerSubOffer(sdp: string): Promise<string>;
|
|
135
|
+
/**
|
|
136
|
+
* addRemoteCandidate 加一个远端候选。
|
|
137
|
+
*
|
|
138
|
+
* 远端描述还没设时**缓存起来而不是报错**——trickle ICE 与 offer/answer 天然会赛跑,
|
|
139
|
+
* 协议要求容忍(§3.3)。
|
|
140
|
+
*/
|
|
141
|
+
addRemoteCandidate(pc: PcRole, candidate: RTCIceCandidateInit): Promise<void>;
|
|
142
|
+
private drainCandidates;
|
|
143
|
+
setMuted(cid: string, muted: boolean): Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* syncCameraCapture 让已发布摄像头的采集跟上开关(交互稿 §01 v3.7:通话中关摄像头也停采集)。
|
|
146
|
+
*
|
|
147
|
+
* 光 `enabled=false` 的话画面是黑了,**摄像头指示灯却一直亮着**。所以关 = `stop()` 掉轨道;
|
|
148
|
+
* 开 = 重新 getUserMedia,再用 `replaceTrack` 换到同一个 sender 上——
|
|
149
|
+
* transceiver、msid、cid 都不变,**不重新协商**,服务端只看到这条 Track 又有包了。
|
|
150
|
+
* 重新采集可能被拒(用户刚在浏览器里收回了权限),错误原样抛给调用方,轨道留在停着的状态。
|
|
151
|
+
*/
|
|
152
|
+
private syncCameraCapture;
|
|
153
|
+
localTrack(cid: string): MediaStreamTrack | undefined;
|
|
154
|
+
close(): void;
|
|
155
|
+
private requirePub;
|
|
156
|
+
private requireSub;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=webrtcAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webrtcAdapter.d.ts","sourceRoot":"","sources":["../../src/media/webrtcAdapter.ts"],"names":[],"mappings":"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"}
|