@vivix-ai/ivi-frontend-sdk 0.3.10 → 0.3.11
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/README.md +6 -5
- package/dist/index.cjs +110 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +110 -35
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -246,11 +246,12 @@ await runtime.start();
|
|
|
246
246
|
|
|
247
247
|
会被串联的关键 spans 包括:
|
|
248
248
|
|
|
249
|
-
- `
|
|
250
|
-
- `
|
|
251
|
-
- `
|
|
252
|
-
- `
|
|
253
|
-
- `
|
|
249
|
+
- `sdk.session.create`:HTTP 创建 IVI Session
|
|
250
|
+
- `sdk.runtime.create` / `sdk.runtime.start` / `sdk.runtime.stop`
|
|
251
|
+
- `sdk.client.connect` / `sdk.client.connection`:底层 `@vivix-ai/ivi-sdk-ts` WebSocket 连接与聚合消息计数
|
|
252
|
+
- `sdk.media.trtc.join_room` / `sdk.media.livekit.join_room`:媒体进房耗时
|
|
253
|
+
- `sdk.media.trtc.waiting_remote_video_available` / `sdk.media.trtc.start_remote_video` / `sdk.media.trtc.remote_video_rendered`:TRTC 远端视频事件等待、开始渲染、渲染完成等首屏关键点
|
|
254
|
+
- `sdk.media.livekit.*`:LiveKit 远端视频可用等首屏关键点
|
|
254
255
|
|
|
255
256
|
SDK span 不会写入 token、`user_sig`、TRTC `secret_key` 或完整业务 payload。低基数字段可以放在 `telemetry.attributes` 中统一附加。
|
|
256
257
|
|
package/dist/index.cjs
CHANGED
|
@@ -1540,14 +1540,14 @@ var TrtcSourceManager = class {
|
|
|
1540
1540
|
const client = TRTC.create();
|
|
1541
1541
|
const onRemoteVideoAvailable = (event) => {
|
|
1542
1542
|
this.log("info", `\u8FDC\u7AEF\u89C6\u9891\u53EF\u7528 source=${session.sourceId} userId=${event.userId} streamType=${event.streamType}`);
|
|
1543
|
-
|
|
1544
|
-
"ivi.media.trtc.remote_video_available",
|
|
1545
|
-
this.telemetry,
|
|
1546
|
-
buildTrtcMediaTelemetryAttributes(session.sourceId, event.userId, event.streamType)
|
|
1547
|
-
);
|
|
1543
|
+
const telemetryAttributes = buildTrtcMediaTelemetryAttributes(session.sourceId, event.userId, event.streamType);
|
|
1548
1544
|
const remoteVideoKey = buildRemoteVideoKey(event.userId, String(event.streamType));
|
|
1549
1545
|
session.remoteVideoStreams.add(remoteVideoKey);
|
|
1550
1546
|
if (!session.hasEverReceivedRemoteVideo) {
|
|
1547
|
+
this.endRemoteVideoAvailableWait(session, {
|
|
1548
|
+
...telemetryAttributes,
|
|
1549
|
+
"ivi.media.trtc.waiting_remote_video_available.result": "available"
|
|
1550
|
+
});
|
|
1551
1551
|
session.hasEverReceivedRemoteVideo = true;
|
|
1552
1552
|
for (const waiter of session.remoteVideoWaiters) {
|
|
1553
1553
|
waiter(true);
|
|
@@ -1594,15 +1594,38 @@ var TrtcSourceManager = class {
|
|
|
1594
1594
|
client.on(TRTC.EVENT.REMOTE_AUDIO_AVAILABLE, onRemoteAudioAvailable);
|
|
1595
1595
|
client.on(TRTC.EVENT.REMOTE_AUDIO_UNAVAILABLE, onRemoteAudioUnavailable);
|
|
1596
1596
|
this.log("info", `\u6B63\u5728\u8FDB\u623F source=${session.sourceId} room=${roomId} sdkAppId=${sdkAppId} userId=${userId}`);
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1597
|
+
session.remoteVideoAvailableSpan = startIviTelemetrySpan(
|
|
1598
|
+
"sdk.media.trtc.waiting_remote_video_available",
|
|
1599
|
+
this.telemetry,
|
|
1600
|
+
buildTrtcWaitingRemoteVideoTelemetryAttributes(session.sourceId, roomId, sdkAppId, isStringRoomId)
|
|
1601
|
+
);
|
|
1602
|
+
const joinRoomSpan = startIviTelemetrySpan(
|
|
1603
|
+
"sdk.media.trtc.join_room",
|
|
1604
|
+
this.telemetry,
|
|
1605
|
+
buildTrtcJoinRoomTelemetryAttributes(session.sourceId, roomId, userId, sdkAppId, isStringRoomId)
|
|
1606
|
+
);
|
|
1607
|
+
try {
|
|
1608
|
+
await client.enterRoom({
|
|
1609
|
+
sdkAppId,
|
|
1610
|
+
userId,
|
|
1611
|
+
userSig,
|
|
1612
|
+
scene: TRTC.TYPE.SCENE_LIVE,
|
|
1613
|
+
role: TRTC.TYPE.ROLE_AUDIENCE,
|
|
1614
|
+
autoReceiveAudio: true,
|
|
1615
|
+
...isStringRoomId ? { strRoomId: roomId } : { roomId: Number(roomId) }
|
|
1616
|
+
});
|
|
1617
|
+
endIviTelemetrySpan(joinRoomSpan.span, {
|
|
1618
|
+
"ivi.media.trtc.join_room.result": "connected"
|
|
1619
|
+
});
|
|
1620
|
+
} catch (error) {
|
|
1621
|
+
this.failRemoteVideoAvailableWait(session, error, {
|
|
1622
|
+
"ivi.media.trtc.waiting_remote_video_available.result": "join_failed"
|
|
1623
|
+
});
|
|
1624
|
+
failIviTelemetrySpan(joinRoomSpan.span, error, {
|
|
1625
|
+
"ivi.media.trtc.join_room.result": "failed"
|
|
1626
|
+
});
|
|
1627
|
+
throw error;
|
|
1628
|
+
}
|
|
1606
1629
|
session.TRTC = TRTC;
|
|
1607
1630
|
session.client = client;
|
|
1608
1631
|
session.status = "connected";
|
|
@@ -1614,6 +1637,9 @@ var TrtcSourceManager = class {
|
|
|
1614
1637
|
});
|
|
1615
1638
|
await this.applyAudioPolicy(session);
|
|
1616
1639
|
})().catch((error) => {
|
|
1640
|
+
this.failRemoteVideoAvailableWait(session, error, {
|
|
1641
|
+
"ivi.media.trtc.waiting_remote_video_available.result": "connect_failed"
|
|
1642
|
+
});
|
|
1617
1643
|
session.status = "error";
|
|
1618
1644
|
session.error = error instanceof Error ? error.message : String(error);
|
|
1619
1645
|
this.log("error", `\u8FDE\u63A5\u5931\u8D25 source=${session.sourceId} error=${session.error}`);
|
|
@@ -1658,7 +1684,7 @@ var TrtcSourceManager = class {
|
|
|
1658
1684
|
streamType
|
|
1659
1685
|
);
|
|
1660
1686
|
const telemetrySpan = startIviTelemetrySpan(
|
|
1661
|
-
"
|
|
1687
|
+
"sdk.media.trtc.start_remote_video",
|
|
1662
1688
|
this.telemetry,
|
|
1663
1689
|
telemetryAttributes
|
|
1664
1690
|
);
|
|
@@ -1672,7 +1698,7 @@ var TrtcSourceManager = class {
|
|
|
1672
1698
|
});
|
|
1673
1699
|
endIviTelemetrySpan(telemetrySpan.span);
|
|
1674
1700
|
recordIviTelemetrySpan(
|
|
1675
|
-
"
|
|
1701
|
+
"sdk.media.trtc.remote_video_rendered",
|
|
1676
1702
|
this.telemetry,
|
|
1677
1703
|
telemetryAttributes
|
|
1678
1704
|
);
|
|
@@ -1736,6 +1762,22 @@ var TrtcSourceManager = class {
|
|
|
1736
1762
|
this.log("warn", `TRTC AIDenoiser \u5F00\u542F\u5931\u8D25 source=${session.sourceId}`, error);
|
|
1737
1763
|
}
|
|
1738
1764
|
}
|
|
1765
|
+
endRemoteVideoAvailableWait(session, attributes) {
|
|
1766
|
+
const waitingSpan = session.remoteVideoAvailableSpan;
|
|
1767
|
+
if (!waitingSpan) {
|
|
1768
|
+
return;
|
|
1769
|
+
}
|
|
1770
|
+
session.remoteVideoAvailableSpan = void 0;
|
|
1771
|
+
endIviTelemetrySpan(waitingSpan.span, attributes);
|
|
1772
|
+
}
|
|
1773
|
+
failRemoteVideoAvailableWait(session, error, attributes) {
|
|
1774
|
+
const waitingSpan = session.remoteVideoAvailableSpan;
|
|
1775
|
+
if (!waitingSpan) {
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
session.remoteVideoAvailableSpan = void 0;
|
|
1779
|
+
failIviTelemetrySpan(waitingSpan.span, error, attributes);
|
|
1780
|
+
}
|
|
1739
1781
|
/**
|
|
1740
1782
|
* 销毁单个 source 会话:
|
|
1741
1783
|
* 解绑事件、停止远端视频、退出房间并销毁客户端。
|
|
@@ -1749,6 +1791,9 @@ var TrtcSourceManager = class {
|
|
|
1749
1791
|
session.remoteVideoStreams.clear();
|
|
1750
1792
|
session.status = "idle";
|
|
1751
1793
|
session.error = void 0;
|
|
1794
|
+
this.endRemoteVideoAvailableWait(session, {
|
|
1795
|
+
"ivi.media.trtc.waiting_remote_video_available.result": "cancelled"
|
|
1796
|
+
});
|
|
1752
1797
|
for (const waiter of session.remoteVideoWaiters) {
|
|
1753
1798
|
waiter(false);
|
|
1754
1799
|
}
|
|
@@ -1908,6 +1953,23 @@ function buildTrtcMediaTelemetryAttributes(sourceId, userId, streamType) {
|
|
|
1908
1953
|
"ivi.trtc.stream_type": String(streamType)
|
|
1909
1954
|
};
|
|
1910
1955
|
}
|
|
1956
|
+
function buildTrtcJoinRoomTelemetryAttributes(sourceId, roomId, userId, sdkAppId, isStringRoomId) {
|
|
1957
|
+
return {
|
|
1958
|
+
"ivi.source.id": sourceId,
|
|
1959
|
+
"ivi.trtc.room_id": roomId,
|
|
1960
|
+
"ivi.trtc.user_id": userId,
|
|
1961
|
+
"ivi.trtc.sdk_app_id": sdkAppId,
|
|
1962
|
+
"ivi.trtc.room_id.is_string": isStringRoomId
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
function buildTrtcWaitingRemoteVideoTelemetryAttributes(sourceId, roomId, sdkAppId, isStringRoomId) {
|
|
1966
|
+
return {
|
|
1967
|
+
"ivi.source.id": sourceId,
|
|
1968
|
+
"ivi.trtc.room_id": roomId,
|
|
1969
|
+
"ivi.trtc.sdk_app_id": sdkAppId,
|
|
1970
|
+
"ivi.trtc.room_id.is_string": isStringRoomId
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1911
1973
|
function parseRemoteVideoKey(key) {
|
|
1912
1974
|
const separatorIndex = key.indexOf("::");
|
|
1913
1975
|
if (separatorIndex < 0) {
|
|
@@ -2196,7 +2258,7 @@ var LivekitSourceManager = class {
|
|
|
2196
2258
|
});
|
|
2197
2259
|
if (kind === "video" && !session.hasEverReceivedRemoteVideo) {
|
|
2198
2260
|
recordIviTelemetrySpan(
|
|
2199
|
-
"
|
|
2261
|
+
"sdk.media.livekit.remote_video_available",
|
|
2200
2262
|
this.telemetry,
|
|
2201
2263
|
{
|
|
2202
2264
|
"ivi.source.id": session.sourceId,
|
|
@@ -2241,7 +2303,22 @@ var LivekitSourceManager = class {
|
|
|
2241
2303
|
"info",
|
|
2242
2304
|
`\u6B63\u5728\u8FDB\u623F source=${session.sourceId} room=${describeLivekitRoom(session.livekit)} ws=${session.livekit.ws_url}`
|
|
2243
2305
|
);
|
|
2244
|
-
|
|
2306
|
+
const joinRoomSpan = startIviTelemetrySpan(
|
|
2307
|
+
"sdk.media.livekit.join_room",
|
|
2308
|
+
this.telemetry,
|
|
2309
|
+
buildLivekitJoinRoomTelemetryAttributes(session)
|
|
2310
|
+
);
|
|
2311
|
+
try {
|
|
2312
|
+
await room.connect(session.livekit.ws_url, session.livekit.token);
|
|
2313
|
+
endIviTelemetrySpan(joinRoomSpan.span, {
|
|
2314
|
+
"ivi.media.livekit.join_room.result": "connected"
|
|
2315
|
+
});
|
|
2316
|
+
} catch (error) {
|
|
2317
|
+
failIviTelemetrySpan(joinRoomSpan.span, error, {
|
|
2318
|
+
"ivi.media.livekit.join_room.result": "failed"
|
|
2319
|
+
});
|
|
2320
|
+
throw error;
|
|
2321
|
+
}
|
|
2245
2322
|
session.room = room;
|
|
2246
2323
|
session.livekitModule = livekitModule;
|
|
2247
2324
|
session.status = "connected";
|
|
@@ -2376,6 +2453,13 @@ var LivekitSourceManager = class {
|
|
|
2376
2453
|
function buildRemoteTrackKey(identity, trackId) {
|
|
2377
2454
|
return `${identity}::${trackId}`;
|
|
2378
2455
|
}
|
|
2456
|
+
function buildLivekitJoinRoomTelemetryAttributes(session) {
|
|
2457
|
+
return {
|
|
2458
|
+
"ivi.source.id": session.sourceId,
|
|
2459
|
+
"ivi.livekit.room": session.livekit.room,
|
|
2460
|
+
"ivi.livekit.identity": session.livekit.identity
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
2379
2463
|
function enforceContainMedia2(element) {
|
|
2380
2464
|
element.style.setProperty("width", "100%", "important");
|
|
2381
2465
|
element.style.setProperty("height", "100%", "important");
|
|
@@ -2471,7 +2555,7 @@ var IviRuntimeCoordinator = class {
|
|
|
2471
2555
|
* 启动后状态会从 idle/stopped 进入 connecting,连接成功后由事件驱动进入后续状态。
|
|
2472
2556
|
*/
|
|
2473
2557
|
async start() {
|
|
2474
|
-
const telemetrySpan = startIviTelemetrySpan("
|
|
2558
|
+
const telemetrySpan = startIviTelemetrySpan("sdk.runtime.start", this.config.telemetry, {
|
|
2475
2559
|
"ivi.runtime.status": this.state.status,
|
|
2476
2560
|
"ivi.session.id": this.state.session?.id
|
|
2477
2561
|
});
|
|
@@ -2499,7 +2583,7 @@ var IviRuntimeCoordinator = class {
|
|
|
2499
2583
|
* 停止协调器并断开实时连接,同时重置运行态数据为 stopped。
|
|
2500
2584
|
*/
|
|
2501
2585
|
stop() {
|
|
2502
|
-
const telemetrySpan = startIviTelemetrySpan("
|
|
2586
|
+
const telemetrySpan = startIviTelemetrySpan("sdk.runtime.stop", this.config.telemetry, {
|
|
2503
2587
|
"ivi.runtime.status": this.state.status,
|
|
2504
2588
|
"ivi.session.id": this.state.session?.id
|
|
2505
2589
|
});
|
|
@@ -2814,16 +2898,7 @@ var IviRuntimeCoordinator = class {
|
|
|
2814
2898
|
if (this.state.status === composedNextState.status && this.state.session === composedNextState.session && this.state.stage === composedNextState.stage && this.state.tracks === composedNextState.tracks && this.state.sources === composedNextState.sources && this.state.streams === composedNextState.streams && this.state.conversationItems === composedNextState.conversationItems && this.state.conversations === composedNextState.conversations && isSameBootstrapState(this.state.bootstrap, composedNextState.bootstrap)) {
|
|
2815
2899
|
return;
|
|
2816
2900
|
}
|
|
2817
|
-
const previousState = this.state;
|
|
2818
2901
|
this.state = composedNextState;
|
|
2819
|
-
if (previousState.status !== composedNextState.status) {
|
|
2820
|
-
recordIviTelemetrySpan("ivi.runtime.state_change", this.config.telemetry, {
|
|
2821
|
-
"ivi.runtime.status.previous": previousState.status,
|
|
2822
|
-
"ivi.runtime.status.next": composedNextState.status,
|
|
2823
|
-
"ivi.runtime.state_change.reason": "state_update",
|
|
2824
|
-
"ivi.session.id": composedNextState.session?.id ?? previousState.session?.id
|
|
2825
|
-
});
|
|
2826
|
-
}
|
|
2827
2902
|
this.stateListeners.forEach((listener) => listener(this.state));
|
|
2828
2903
|
}
|
|
2829
2904
|
composeBootstrapState(nextState) {
|
|
@@ -3107,7 +3182,7 @@ async function createIVISession(request, options) {
|
|
|
3107
3182
|
throw new Error("fetch is not available. Pass options.fetch to createIVISession.");
|
|
3108
3183
|
}
|
|
3109
3184
|
const telemetrySpan = startIviTelemetrySpan(
|
|
3110
|
-
"
|
|
3185
|
+
"sdk.session.create",
|
|
3111
3186
|
options.telemetry,
|
|
3112
3187
|
buildCreateSessionTelemetryAttributes(request)
|
|
3113
3188
|
);
|
|
@@ -3146,7 +3221,7 @@ async function createIVISession(request, options) {
|
|
|
3146
3221
|
}
|
|
3147
3222
|
}
|
|
3148
3223
|
function createRuntimeFromSession(session, options = {}) {
|
|
3149
|
-
const telemetrySpan = startIviTelemetrySpan("
|
|
3224
|
+
const telemetrySpan = startIviTelemetrySpan("sdk.runtime.create", options.telemetry, {
|
|
3150
3225
|
"ivi.session.id": session.iviSessionId,
|
|
3151
3226
|
"ivi.prebuild.playback.kind": session.prebuiltPlayback?.kind
|
|
3152
3227
|
});
|
|
@@ -4805,7 +4880,7 @@ function IVIHlsVideo(props) {
|
|
|
4805
4880
|
const onVideoError = () => {
|
|
4806
4881
|
const el = videoRef.current;
|
|
4807
4882
|
const mediaErr = el?.error;
|
|
4808
|
-
recordVideoTelemetry("
|
|
4883
|
+
recordVideoTelemetry("sdk.media.video.error", telemetry, sourceId, "hls", mediaErr);
|
|
4809
4884
|
emitHlsLog(onLog, "warn", "<video> \u5143\u7D20\u62A5\u9519", {
|
|
4810
4885
|
code: mediaErr?.code,
|
|
4811
4886
|
message: mediaErr?.message,
|
|
@@ -4816,7 +4891,7 @@ function IVIHlsVideo(props) {
|
|
|
4816
4891
|
};
|
|
4817
4892
|
const onVideoStalled = () => {
|
|
4818
4893
|
recordVideoTelemetry(
|
|
4819
|
-
"
|
|
4894
|
+
"sdk.media.video.stalled",
|
|
4820
4895
|
telemetry,
|
|
4821
4896
|
sourceId,
|
|
4822
4897
|
"hls",
|
|
@@ -5212,7 +5287,7 @@ function SlotVideo(props) {
|
|
|
5212
5287
|
}, [props.paused]);
|
|
5213
5288
|
const onError = (event) => {
|
|
5214
5289
|
recordPlainVideoTelemetry(
|
|
5215
|
-
"
|
|
5290
|
+
"sdk.media.video.error",
|
|
5216
5291
|
props.telemetry,
|
|
5217
5292
|
props.sourceId,
|
|
5218
5293
|
event.currentTarget.error
|
|
@@ -5221,7 +5296,7 @@ function SlotVideo(props) {
|
|
|
5221
5296
|
};
|
|
5222
5297
|
const onStalled = (event) => {
|
|
5223
5298
|
recordPlainVideoTelemetry(
|
|
5224
|
-
"
|
|
5299
|
+
"sdk.media.video.stalled",
|
|
5225
5300
|
props.telemetry,
|
|
5226
5301
|
props.sourceId,
|
|
5227
5302
|
new Error("<video> stalled")
|