@xmaxai/web-sdk 1.0.9 → 1.0.10
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 +8 -1
- package/dist/RecordingProcessor-4TP5NICO.cjs.map +1 -1
- package/dist/{TrajectoryEffectRendering-C7E2KJbV.d.cts → TrajectoryEffectRendering-BKKPO7Uk.d.cts} +2 -2
- package/dist/{TrajectoryEffectRendering-C7E2KJbV.d.ts → TrajectoryEffectRendering-BKKPO7Uk.d.ts} +2 -2
- package/dist/chunk-4DE2IREA.cjs.map +1 -1
- package/dist/{chunk-ILZL4W2G.js → chunk-LOYJFYQT.js} +461 -209
- package/dist/chunk-LOYJFYQT.js.map +1 -0
- package/dist/{chunk-KROY2O4A.cjs → chunk-UF2RD42G.cjs} +580 -328
- package/dist/chunk-UF2RD42G.cjs.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -19
- package/dist/index.d.ts +42 -19
- package/dist/index.js +1 -1
- package/dist/react/index.cjs +3 -3
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-ILZL4W2G.js.map +0 -1
- package/dist/chunk-KROY2O4A.cjs.map +0 -1
|
@@ -205,7 +205,7 @@ var XmaxError = class _XmaxError extends Error {
|
|
|
205
205
|
};
|
|
206
206
|
|
|
207
207
|
// src/Foundation/Runtime/RuntimeInfo.ts
|
|
208
|
-
var XMAX_SDK_VERSION = "1.0.
|
|
208
|
+
var XMAX_SDK_VERSION = "1.0.10";
|
|
209
209
|
var _RuntimeInfo = class _RuntimeInfo {
|
|
210
210
|
/**
|
|
211
211
|
* 序列化为接口传输使用的 snake_case 字段。
|
|
@@ -501,7 +501,7 @@ var RealtimeVideoFormat = class _RealtimeVideoFormat {
|
|
|
501
501
|
* @param init.width 视频宽度,单位为像素。
|
|
502
502
|
* @param init.height 视频高度,单位为像素。
|
|
503
503
|
* @param init.fps 视频帧率,必须大于 0。
|
|
504
|
-
* @param init.minimumBitrate 最低上传码率,单位为 kbps
|
|
504
|
+
* @param init.minimumBitrate 最低上传码率,单位为 kbps;缺省为 100,仅支持该参数的 RTC 链路生效。
|
|
505
505
|
* @param init.maximumBitrate 最高上传码率,单位为 kbps;缺省按最终上传尺寸和帧率计算。
|
|
506
506
|
* @param init.encoderPreference 上传编码策略偏好,默认值为 maintainFramerate。
|
|
507
507
|
*/
|
|
@@ -525,7 +525,7 @@ var RealtimeVideoFormat = class _RealtimeVideoFormat {
|
|
|
525
525
|
* 上传编码配置
|
|
526
526
|
*/
|
|
527
527
|
/**
|
|
528
|
-
* 最低上传码率,单位为 kbps
|
|
528
|
+
* 最低上传码率,单位为 kbps;缺省为 100,0 表示不设最低码率;仅支持该参数的 RTC 链路生效。
|
|
529
529
|
*/
|
|
530
530
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "minimumBitrate");
|
|
531
531
|
/**
|
|
@@ -598,10 +598,6 @@ var RtcProvider = /* @__PURE__ */ ((RtcProvider2) => {
|
|
|
598
598
|
|
|
599
599
|
// src/Service/Realtime/RealtimeModel.ts
|
|
600
600
|
var RealtimeModel = /* @__PURE__ */ ((RealtimeModel2) => {
|
|
601
|
-
RealtimeModel2["x2_0"] = "x2.0";
|
|
602
|
-
RealtimeModel2["x2_0_trtc"] = "x2.0-trtc";
|
|
603
|
-
RealtimeModel2["x2_1_preview"] = "x2.1-preview";
|
|
604
|
-
RealtimeModel2["x2_1_preview_1014"] = "x2.1-preview-1014";
|
|
605
601
|
RealtimeModel2["x2_1_1_preview_cn"] = "x2.1.1-preview-cn";
|
|
606
602
|
RealtimeModel2["x2_1_1_preview_us"] = "x2.1.1-preview-us";
|
|
607
603
|
return RealtimeModel2;
|
|
@@ -613,36 +609,17 @@ function isKnownModel(model) {
|
|
|
613
609
|
return Object.values(RealtimeModel).includes(model);
|
|
614
610
|
}
|
|
615
611
|
function modelDefaults(model) {
|
|
616
|
-
return isKnownModel(model) ? model : "x2.1-preview" /*
|
|
612
|
+
return isKnownModel(model) ? model : "x2.1.1-preview-cn" /* x2_1_1_preview_cn */;
|
|
617
613
|
}
|
|
618
614
|
var MODEL_DISPLAY_NAMES = {
|
|
619
|
-
["x2.0" /* x2_0 */]: "X2.0",
|
|
620
|
-
["x2.0-trtc" /* x2_0_trtc */]: "X2.1-preview-trtc",
|
|
621
|
-
["x2.1-preview" /* x2_1_preview */]: "X2.1-preview-agora",
|
|
622
|
-
["x2.1-preview-1014" /* x2_1_preview_1014 */]: "X2.1-preview-1014",
|
|
623
615
|
["x2.1.1-preview-cn" /* x2_1_1_preview_cn */]: "X2.1.1-preview-cn",
|
|
624
616
|
["x2.1.1-preview-us" /* x2_1_1_preview_us */]: "X2.1.1-preview-us"
|
|
625
617
|
};
|
|
626
618
|
var MODEL_BASE_URLS = {
|
|
627
|
-
["x2.1-preview" /* x2_1_preview */]: "https://cloud.xmax.22duck.cn/open/api/v1",
|
|
628
|
-
["x2.1-preview-1014" /* x2_1_preview_1014 */]: "https://dev.xmaxai.com/open/api/v1",
|
|
629
619
|
["x2.1.1-preview-cn" /* x2_1_1_preview_cn */]: "https://cloud.xmax.22duck.cn/open/api/v1",
|
|
630
620
|
["x2.1.1-preview-us" /* x2_1_1_preview_us */]: "https://api.xmax.ai/open/api/v1"
|
|
631
621
|
};
|
|
632
622
|
var RESOLUTION_BUCKETS = {
|
|
633
|
-
["x2.0" /* x2_0 */]: [],
|
|
634
|
-
["x2.0-trtc" /* x2_0_trtc */]: [
|
|
635
|
-
{ width: 1024, height: 1920 },
|
|
636
|
-
{ width: 1920, height: 1024 }
|
|
637
|
-
],
|
|
638
|
-
["x2.1-preview" /* x2_1_preview */]: [
|
|
639
|
-
{ width: 1024, height: 1920 },
|
|
640
|
-
{ width: 1920, height: 1024 }
|
|
641
|
-
],
|
|
642
|
-
["x2.1-preview-1014" /* x2_1_preview_1014 */]: [
|
|
643
|
-
{ width: 1024, height: 1920 },
|
|
644
|
-
{ width: 1920, height: 1024 }
|
|
645
|
-
],
|
|
646
623
|
["x2.1.1-preview-cn" /* x2_1_1_preview_cn */]: [
|
|
647
624
|
{ width: 1024, height: 1920 },
|
|
648
625
|
{ width: 1920, height: 1024 }
|
|
@@ -653,10 +630,6 @@ var RESOLUTION_BUCKETS = {
|
|
|
653
630
|
]
|
|
654
631
|
};
|
|
655
632
|
var MAXIMUM_INPUT_PIXELS = {
|
|
656
|
-
["x2.0" /* x2_0 */]: 128e4,
|
|
657
|
-
["x2.0-trtc" /* x2_0_trtc */]: 21e5,
|
|
658
|
-
["x2.1-preview" /* x2_1_preview */]: 21e5,
|
|
659
|
-
["x2.1-preview-1014" /* x2_1_preview_1014 */]: 21e5,
|
|
660
633
|
["x2.1.1-preview-cn" /* x2_1_1_preview_cn */]: 21e5,
|
|
661
634
|
["x2.1.1-preview-us" /* x2_1_1_preview_us */]: 21e5
|
|
662
635
|
};
|
|
@@ -682,16 +655,10 @@ function defaultFrameRate(_model) {
|
|
|
682
655
|
return 30;
|
|
683
656
|
}
|
|
684
657
|
function defaultCameraVideoFormat(model) {
|
|
685
|
-
|
|
686
|
-
return new RealtimeVideoFormat({ width: 832, height: 1472, fps: 30 });
|
|
687
|
-
}
|
|
658
|
+
modelDefaults(model);
|
|
688
659
|
return new RealtimeVideoFormat({ width: 1024, height: 1920, fps: 30 });
|
|
689
660
|
}
|
|
690
661
|
var MODEL_RTC_PROVIDERS = {
|
|
691
|
-
["x2.0" /* x2_0 */]: Object.freeze(["vertc" /* vertc */]),
|
|
692
|
-
["x2.0-trtc" /* x2_0_trtc */]: Object.freeze(["trtc" /* trtc */]),
|
|
693
|
-
["x2.1-preview" /* x2_1_preview */]: Object.freeze(["agora" /* agora */]),
|
|
694
|
-
["x2.1-preview-1014" /* x2_1_preview_1014 */]: Object.freeze(["agora" /* agora */]),
|
|
695
662
|
["x2.1.1-preview-cn" /* x2_1_1_preview_cn */]: Object.freeze(["agora" /* agora */]),
|
|
696
663
|
["x2.1.1-preview-us" /* x2_1_1_preview_us */]: Object.freeze(["agora" /* agora */])
|
|
697
664
|
};
|
|
@@ -699,8 +666,8 @@ function supportedRtcProviders(model) {
|
|
|
699
666
|
return isKnownModel(model) ? MODEL_RTC_PROVIDERS[model] : CUSTOM_MODEL_RTC_PROVIDERS;
|
|
700
667
|
}
|
|
701
668
|
var CUSTOM_MODEL_RTC_PROVIDERS = Object.freeze([
|
|
702
|
-
...MODEL_RTC_PROVIDERS["x2.1-preview" /*
|
|
703
|
-
...Object.values(RtcProvider).filter((provider) => !MODEL_RTC_PROVIDERS["x2.1-preview" /*
|
|
669
|
+
...MODEL_RTC_PROVIDERS["x2.1.1-preview-cn" /* x2_1_1_preview_cn */],
|
|
670
|
+
...Object.values(RtcProvider).filter((provider) => !MODEL_RTC_PROVIDERS["x2.1.1-preview-cn" /* x2_1_1_preview_cn */].includes(provider))
|
|
704
671
|
]);
|
|
705
672
|
|
|
706
673
|
// src/Foundation/Media/Video/FrameInterpolationSupport.ts
|
|
@@ -722,9 +689,9 @@ var MediaService = class {
|
|
|
722
689
|
/**
|
|
723
690
|
* 创建媒体服务。
|
|
724
691
|
*
|
|
725
|
-
* @param model 媒体输入规则使用的模型,默认为 `x2.
|
|
692
|
+
* @param model 媒体输入规则使用的模型,默认为 `x2.1.1-preview-cn`。
|
|
726
693
|
*/
|
|
727
|
-
constructor(model = "x2.
|
|
694
|
+
constructor(model = "x2.1.1-preview-cn" /* x2_1_1_preview_cn */) {
|
|
728
695
|
/**
|
|
729
696
|
* 模型约束
|
|
730
697
|
*/
|
|
@@ -3968,7 +3935,9 @@ var RESERVED_PARAMS = /* @__PURE__ */ new Set([
|
|
|
3968
3935
|
"ref_image_path",
|
|
3969
3936
|
"mirror",
|
|
3970
3937
|
"ref_video_path",
|
|
3971
|
-
"sample_method"
|
|
3938
|
+
"sample_method",
|
|
3939
|
+
"min_bitrate",
|
|
3940
|
+
"max_bitrate"
|
|
3972
3941
|
]);
|
|
3973
3942
|
function snapshotExtraParams(params) {
|
|
3974
3943
|
if (params === void 0) return void 0;
|
|
@@ -5980,6 +5949,20 @@ var RenderController = class {
|
|
|
5980
5949
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "track");
|
|
5981
5950
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "target");
|
|
5982
5951
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "interactionEnabled", false);
|
|
5952
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "ready", false);
|
|
5953
|
+
}
|
|
5954
|
+
/**
|
|
5955
|
+
* 当前远端视图是否已完成渲染预热。
|
|
5956
|
+
*/
|
|
5957
|
+
get isReady() {
|
|
5958
|
+
return this.ready;
|
|
5959
|
+
}
|
|
5960
|
+
/**
|
|
5961
|
+
* 新任务重新等待首帧和预热,避免复用上一次任务的展示就绪状态。
|
|
5962
|
+
*/
|
|
5963
|
+
prepareForGeneration() {
|
|
5964
|
+
this.ready = false;
|
|
5965
|
+
_optionalChain([this, 'access', _521 => _521.target, 'optionalAccess', _522 => _522.prepareForGeneration, 'optionalCall', _523 => _523()]);
|
|
5983
5966
|
}
|
|
5984
5967
|
/**
|
|
5985
5968
|
* 注册新轨道并使旧绑定失效;本地轨道不经过该入口。
|
|
@@ -5991,27 +5974,37 @@ var RenderController = class {
|
|
|
5991
5974
|
TrajectoryRegistry.register(track, new TrajectoryBinding(listener, track.videoFormat));
|
|
5992
5975
|
}
|
|
5993
5976
|
VideoRenderRegistry.register(track, {
|
|
5977
|
+
// 临时缓解生成开头卡顿:首帧后继续播放 1000 ms,再渐入。
|
|
5978
|
+
renderWarmupMs: 1e3,
|
|
5979
|
+
renderWarmupCompletedHandler: () => {
|
|
5980
|
+
if (this.track === track) {
|
|
5981
|
+
this.ready = true;
|
|
5982
|
+
_optionalChain([this, 'access', _524 => _524.callbacks, 'access', _525 => _525.onRenderWarmupCompleted, 'optionalCall', _526 => _526()]);
|
|
5983
|
+
}
|
|
5984
|
+
},
|
|
5994
5985
|
frameDisplayHandler: () => {
|
|
5995
5986
|
if (this.track === track) {
|
|
5996
|
-
_optionalChain([this, 'access',
|
|
5987
|
+
_optionalChain([this, 'access', _527 => _527.callbacks, 'access', _528 => _528.onFrameDisplayed, 'optionalCall', _529 => _529()]);
|
|
5997
5988
|
}
|
|
5998
5989
|
},
|
|
5999
5990
|
attachHandler: (view) => {
|
|
6000
5991
|
if (this.track !== track) {
|
|
6001
5992
|
return;
|
|
6002
5993
|
}
|
|
6003
|
-
_optionalChain([this, 'access',
|
|
5994
|
+
_optionalChain([this, 'access', _530 => _530.target, 'optionalAccess', _531 => _531.setFrameInterpolation, 'optionalCall', _532 => _532(void 0)]);
|
|
5995
|
+
this.ready = false;
|
|
6004
5996
|
view.isMirrored = false;
|
|
6005
5997
|
this.target = view;
|
|
6006
|
-
_optionalChain([this, 'access',
|
|
5998
|
+
_optionalChain([this, 'access', _533 => _533.callbacks, 'access', _534 => _534.onAttached, 'optionalCall', _535 => _535()]);
|
|
6007
5999
|
view.setMediaStream(track.mediaStreamTrack ? new MediaStream([track.mediaStreamTrack]) : null);
|
|
6008
6000
|
},
|
|
6009
6001
|
detachHandler: (view) => {
|
|
6010
6002
|
if (this.target === view) {
|
|
6011
|
-
|
|
6003
|
+
this.ready = false;
|
|
6004
|
+
_optionalChain([this, 'access', _536 => _536.callbacks, 'access', _537 => _537.onDetached, 'optionalCall', _538 => _538()]);
|
|
6012
6005
|
this.target = void 0;
|
|
6013
6006
|
}
|
|
6014
|
-
_optionalChain([view, 'access',
|
|
6007
|
+
_optionalChain([view, 'access', _539 => _539.setFrameInterpolation, 'optionalCall', _540 => _540(void 0)]);
|
|
6015
6008
|
view.setMediaStream(null);
|
|
6016
6009
|
}
|
|
6017
6010
|
});
|
|
@@ -6020,16 +6013,17 @@ var RenderController = class {
|
|
|
6020
6013
|
* 更新媒体画面;暂停显示时同时禁用交互。
|
|
6021
6014
|
*/
|
|
6022
6015
|
setRemoteMedia(track) {
|
|
6016
|
+
this.ready = false;
|
|
6023
6017
|
if (this.track) {
|
|
6024
|
-
_optionalChain([TrajectoryRegistry, 'access',
|
|
6018
|
+
_optionalChain([TrajectoryRegistry, 'access', _541 => _541.binding, 'call', _542 => _542(this.track), 'optionalAccess', _543 => _543.update, 'call', _544 => _544(!!track && this.interactionEnabled)]);
|
|
6025
6019
|
}
|
|
6026
|
-
_optionalChain([this, 'access',
|
|
6020
|
+
_optionalChain([this, 'access', _545 => _545.target, 'optionalAccess', _546 => _546.setMediaStream, 'call', _547 => _547(track ? new MediaStream([track]) : null)]);
|
|
6027
6021
|
}
|
|
6028
6022
|
/**
|
|
6029
6023
|
* 转交插帧配置,不重建交互视图。
|
|
6030
6024
|
*/
|
|
6031
6025
|
setFrameInterpolation(options) {
|
|
6032
|
-
_optionalChain([this, 'access',
|
|
6026
|
+
_optionalChain([this, 'access', _548 => _548.target, 'optionalAccess', _549 => _549.setFrameInterpolation, 'optionalCall', _550 => _550(options)]);
|
|
6033
6027
|
}
|
|
6034
6028
|
/**
|
|
6035
6029
|
* 更新交互绑定的输入格式和可用性。
|
|
@@ -6037,13 +6031,14 @@ var RenderController = class {
|
|
|
6037
6031
|
setInteractionEnabled(enabled, format) {
|
|
6038
6032
|
this.interactionEnabled = enabled;
|
|
6039
6033
|
if (this.track) {
|
|
6040
|
-
_optionalChain([TrajectoryRegistry, 'access',
|
|
6034
|
+
_optionalChain([TrajectoryRegistry, 'access', _551 => _551.binding, 'call', _552 => _552(this.track), 'optionalAccess', _553 => _553.update, 'call', _554 => _554(enabled, format)]);
|
|
6041
6035
|
}
|
|
6042
6036
|
}
|
|
6043
6037
|
/**
|
|
6044
6038
|
* 先使能力失效再清空画面,迟到首帧和旧手势不能恢复已结束任务。
|
|
6045
6039
|
*/
|
|
6046
6040
|
resetRemoteTrack() {
|
|
6041
|
+
this.ready = false;
|
|
6047
6042
|
const track = this.track;
|
|
6048
6043
|
this.track = void 0;
|
|
6049
6044
|
this.interactionEnabled = false;
|
|
@@ -6051,8 +6046,8 @@ var RenderController = class {
|
|
|
6051
6046
|
TrajectoryRegistry.unregister(track);
|
|
6052
6047
|
VideoRenderRegistry.unregister(track);
|
|
6053
6048
|
}
|
|
6054
|
-
_optionalChain([this, 'access',
|
|
6055
|
-
_optionalChain([this, 'access',
|
|
6049
|
+
_optionalChain([this, 'access', _555 => _555.target, 'optionalAccess', _556 => _556.setFrameInterpolation, 'optionalCall', _557 => _557(void 0)]);
|
|
6050
|
+
_optionalChain([this, 'access', _558 => _558.target, 'optionalAccess', _559 => _559.setMediaStream, 'call', _560 => _560(null)]);
|
|
6056
6051
|
this.target = void 0;
|
|
6057
6052
|
}
|
|
6058
6053
|
};
|
|
@@ -6080,7 +6075,7 @@ var RealtimeContext = class {
|
|
|
6080
6075
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "referencePath");
|
|
6081
6076
|
this.referenceVideo = init.referenceVideo && Object.freeze({ ...init.referenceVideo });
|
|
6082
6077
|
this.prompt = init.prompt.trim();
|
|
6083
|
-
const normalizedReferencePath = _optionalChain([init, 'access',
|
|
6078
|
+
const normalizedReferencePath = _optionalChain([init, 'access', _561 => _561.referencePath, 'optionalAccess', _562 => _562.trim, 'call', _563 => _563()]);
|
|
6084
6079
|
this.referencePath = normalizedReferencePath || void 0;
|
|
6085
6080
|
}
|
|
6086
6081
|
};
|
|
@@ -6348,7 +6343,7 @@ var RealtimeSessionService = class _RealtimeSessionService {
|
|
|
6348
6343
|
return;
|
|
6349
6344
|
}
|
|
6350
6345
|
_RealtimeSessionService.ensureSessionActive(session);
|
|
6351
|
-
await _optionalChain([handlers, 'access',
|
|
6346
|
+
await _optionalChain([handlers, 'access', _564 => _564.onRefresh, 'optionalCall', _565 => _565(session)]);
|
|
6352
6347
|
} catch (error) {
|
|
6353
6348
|
if (this.heartbeatVersion !== version) {
|
|
6354
6349
|
return;
|
|
@@ -6501,6 +6496,7 @@ var RealtimeConnectionState = /* @__PURE__ */ ((RealtimeConnectionState2) => {
|
|
|
6501
6496
|
RealtimeConnectionState2["ready"] = "Ready";
|
|
6502
6497
|
RealtimeConnectionState2["connecting"] = "Connecting";
|
|
6503
6498
|
RealtimeConnectionState2["connected"] = "Connected";
|
|
6499
|
+
RealtimeConnectionState2["starting"] = "Starting";
|
|
6504
6500
|
RealtimeConnectionState2["generating"] = "Generating";
|
|
6505
6501
|
RealtimeConnectionState2["disconnecting"] = "Disconnecting";
|
|
6506
6502
|
return RealtimeConnectionState2;
|
|
@@ -6561,7 +6557,7 @@ var RealtimeState = class {
|
|
|
6561
6557
|
* @param other 待比较的状态。
|
|
6562
6558
|
*/
|
|
6563
6559
|
equals(other) {
|
|
6564
|
-
return this.connectionState === other.connectionState && this.sessionID === other.sessionID && this.taskID === other.taskID && _optionalChain([this, 'access',
|
|
6560
|
+
return this.connectionState === other.connectionState && this.sessionID === other.sessionID && this.taskID === other.taskID && _optionalChain([this, 'access', _566 => _566.reason, 'optionalAccess', _567 => _567.kind]) === _optionalChain([other, 'access', _568 => _568.reason, 'optionalAccess', _569 => _569.kind]);
|
|
6565
6561
|
}
|
|
6566
6562
|
};
|
|
6567
6563
|
|
|
@@ -6606,6 +6602,8 @@ var RoomEvent = class _RoomEvent {
|
|
|
6606
6602
|
* @param options.videoFormat 模型生成使用的视频规格。
|
|
6607
6603
|
* @param options.context 本次生成条件。
|
|
6608
6604
|
* @param options.targetSize 回传尺寸,缺省时不发送;网络视频默认使用生成尺寸。
|
|
6605
|
+
* @param options.minimumBitrate 服务端回传的最低码率,单位为 kbps。
|
|
6606
|
+
* @param options.maximumBitrate 服务端回传的最高码率,单位为 kbps。
|
|
6609
6607
|
* @param options.mirror 是否由后端镜像输入画面,默认 false。
|
|
6610
6608
|
* @param options.faceRestoration 是否回贴原始人脸,默认 false。
|
|
6611
6609
|
* @param options.extraParams 已校验的本次扩展参数,合并到 params。
|
|
@@ -6616,13 +6614,15 @@ var RoomEvent = class _RoomEvent {
|
|
|
6616
6614
|
event: "start",
|
|
6617
6615
|
params: {
|
|
6618
6616
|
..._RoomEvent.generationParameters(options),
|
|
6617
|
+
min_bitrate: options.minimumBitrate,
|
|
6618
|
+
max_bitrate: options.maximumBitrate,
|
|
6619
6619
|
mirror: _nullishCoalesce(options.mirror, () => ( false)),
|
|
6620
6620
|
...options.context.referenceVideo && {
|
|
6621
6621
|
ref_video_path: options.context.referenceVideo.path,
|
|
6622
6622
|
sample_method: options.context.referenceVideo.sampleMethod,
|
|
6623
6623
|
target_size: [
|
|
6624
|
-
_nullishCoalesce(_optionalChain([options, 'access',
|
|
6625
|
-
_nullishCoalesce(_optionalChain([options, 'access',
|
|
6624
|
+
_nullishCoalesce(_optionalChain([options, 'access', _570 => _570.targetSize, 'optionalAccess', _571 => _571.width]), () => ( options.videoFormat.width)),
|
|
6625
|
+
_nullishCoalesce(_optionalChain([options, 'access', _572 => _572.targetSize, 'optionalAccess', _573 => _573.height]), () => ( options.videoFormat.height))
|
|
6626
6626
|
]
|
|
6627
6627
|
}
|
|
6628
6628
|
},
|
|
@@ -6652,12 +6652,14 @@ var RoomEvent = class _RoomEvent {
|
|
|
6652
6652
|
});
|
|
6653
6653
|
}
|
|
6654
6654
|
/**
|
|
6655
|
-
*
|
|
6655
|
+
* 回传尺寸和码率范围调整信令,码率单位为 kbps。
|
|
6656
6656
|
*/
|
|
6657
6657
|
static changeTargetSize(options) {
|
|
6658
6658
|
return _RoomEvent.encode({
|
|
6659
6659
|
event: "change_target_size",
|
|
6660
6660
|
params: {
|
|
6661
|
+
min_bitrate: options.minimumBitrate,
|
|
6662
|
+
max_bitrate: options.maximumBitrate,
|
|
6661
6663
|
target_size: [
|
|
6662
6664
|
Math.round(options.targetSize.width),
|
|
6663
6665
|
Math.round(options.targetSize.height)
|
|
@@ -6732,6 +6734,114 @@ var RoomEvent = class _RoomEvent {
|
|
|
6732
6734
|
}
|
|
6733
6735
|
};
|
|
6734
6736
|
|
|
6737
|
+
// src/Stream/Encoding/EncodingBitratePolicy.ts
|
|
6738
|
+
var _EncodingBitratePolicy = class _EncodingBitratePolicy {
|
|
6739
|
+
/**
|
|
6740
|
+
* 最低码率固定为 100 kbps,最高码率按尺寸和帧率计算并应用预算系数。
|
|
6741
|
+
*/
|
|
6742
|
+
static resolve(width, height, fps) {
|
|
6743
|
+
new RealtimeVideoFormat({ width, height, fps }).validate();
|
|
6744
|
+
const maximum = Math.round(
|
|
6745
|
+
this.resolveMaximumBitrate(width * height, fps) * this.bitrateScale
|
|
6746
|
+
);
|
|
6747
|
+
if (!Number.isSafeInteger(maximum)) {
|
|
6748
|
+
throw new XmaxError(
|
|
6749
|
+
"INVALID_CONFIGURATION" /* invalidConfiguration */,
|
|
6750
|
+
"Realtime video format exceeds the supported bitrate range"
|
|
6751
|
+
);
|
|
6752
|
+
}
|
|
6753
|
+
return { minimum: 100, maximum: Math.max(100, maximum) };
|
|
6754
|
+
}
|
|
6755
|
+
/**
|
|
6756
|
+
* 按像素面积和帧率插值计算最高码率参考值。
|
|
6757
|
+
*/
|
|
6758
|
+
static resolveMaximumBitrate(pixels, fps) {
|
|
6759
|
+
const bitrate15 = _EncodingBitratePolicy.interpolate(
|
|
6760
|
+
pixels,
|
|
6761
|
+
_EncodingBitratePolicy.referenceBitratesAt15FPS
|
|
6762
|
+
);
|
|
6763
|
+
const first30 = _EncodingBitratePolicy.referenceBitratesAt30FPS[0];
|
|
6764
|
+
let bitrate30;
|
|
6765
|
+
if (pixels < first30.value) {
|
|
6766
|
+
const reference15 = _EncodingBitratePolicy.interpolate(
|
|
6767
|
+
first30.value,
|
|
6768
|
+
_EncodingBitratePolicy.referenceBitratesAt15FPS
|
|
6769
|
+
);
|
|
6770
|
+
bitrate30 = bitrate15 * (first30.bitrate / reference15);
|
|
6771
|
+
} else {
|
|
6772
|
+
bitrate30 = _EncodingBitratePolicy.interpolate(
|
|
6773
|
+
pixels,
|
|
6774
|
+
_EncodingBitratePolicy.referenceBitratesAt30FPS
|
|
6775
|
+
);
|
|
6776
|
+
}
|
|
6777
|
+
const bitrate10 = bitrate15 * (400 / 500);
|
|
6778
|
+
const maximum60 = bitrate30 * (6500 / 3150);
|
|
6779
|
+
return _EncodingBitratePolicy.interpolate(fps, [
|
|
6780
|
+
{ value: 10, bitrate: bitrate10 * 2 },
|
|
6781
|
+
{ value: 15, bitrate: bitrate15 * 2 },
|
|
6782
|
+
{ value: 30, bitrate: bitrate30 * 2 },
|
|
6783
|
+
{ value: 60, bitrate: maximum60 }
|
|
6784
|
+
]);
|
|
6785
|
+
}
|
|
6786
|
+
/**
|
|
6787
|
+
* 在相邻参考点间线性插值,表外按最近端点的比例外推。
|
|
6788
|
+
*/
|
|
6789
|
+
static interpolate(value, points) {
|
|
6790
|
+
const first = points[0];
|
|
6791
|
+
if (value <= first.value) {
|
|
6792
|
+
return first.bitrate * (value / first.value);
|
|
6793
|
+
}
|
|
6794
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
6795
|
+
const upper = points[index];
|
|
6796
|
+
if (value <= upper.value) {
|
|
6797
|
+
const lower = points[index - 1];
|
|
6798
|
+
const ratio = (value - lower.value) / (upper.value - lower.value);
|
|
6799
|
+
return lower.bitrate + (upper.bitrate - lower.bitrate) * ratio;
|
|
6800
|
+
}
|
|
6801
|
+
}
|
|
6802
|
+
const last = points[points.length - 1];
|
|
6803
|
+
return last.bitrate * (value / last.value);
|
|
6804
|
+
}
|
|
6805
|
+
};
|
|
6806
|
+
/**
|
|
6807
|
+
* 最高码率相对参考值的预算系数。
|
|
6808
|
+
*/
|
|
6809
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, _EncodingBitratePolicy, "bitrateScale", 0.6);
|
|
6810
|
+
/**
|
|
6811
|
+
* 流畅优先码率参考,按像素面积升序排列,单位为 kbps。
|
|
6812
|
+
*/
|
|
6813
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, _EncodingBitratePolicy, "referenceBitratesAt15FPS", [
|
|
6814
|
+
{ value: 120 * 120, bitrate: 50 },
|
|
6815
|
+
{ value: 160 * 120, bitrate: 65 },
|
|
6816
|
+
{ value: 180 * 180, bitrate: 100 },
|
|
6817
|
+
{ value: 240 * 180, bitrate: 120 },
|
|
6818
|
+
{ value: 320 * 180, bitrate: 140 },
|
|
6819
|
+
{ value: 320 * 240, bitrate: 200 },
|
|
6820
|
+
{ value: 424 * 240, bitrate: 220 },
|
|
6821
|
+
{ value: 360 * 360, bitrate: 260 },
|
|
6822
|
+
{ value: 480 * 360, bitrate: 320 },
|
|
6823
|
+
{ value: 640 * 360, bitrate: 400 },
|
|
6824
|
+
{ value: 640 * 480, bitrate: 500 },
|
|
6825
|
+
{ value: 848 * 480, bitrate: 610 },
|
|
6826
|
+
{ value: 960 * 720, bitrate: 910 },
|
|
6827
|
+
{ value: 1280 * 720, bitrate: 1130 },
|
|
6828
|
+
{ value: 1920 * 1080, bitrate: 2080 }
|
|
6829
|
+
]);
|
|
6830
|
+
/**
|
|
6831
|
+
* 30 fps 的像素面积与码率参考点,单位为 kbps。
|
|
6832
|
+
*/
|
|
6833
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, _EncodingBitratePolicy, "referenceBitratesAt30FPS", [
|
|
6834
|
+
{ value: 360 * 360, bitrate: 400 },
|
|
6835
|
+
{ value: 480 * 360, bitrate: 490 },
|
|
6836
|
+
{ value: 640 * 360, bitrate: 600 },
|
|
6837
|
+
{ value: 640 * 480, bitrate: 750 },
|
|
6838
|
+
{ value: 848 * 480, bitrate: 930 },
|
|
6839
|
+
{ value: 960 * 720, bitrate: 1380 },
|
|
6840
|
+
{ value: 1280 * 720, bitrate: 1710 },
|
|
6841
|
+
{ value: 1920 * 1080, bitrate: 3150 }
|
|
6842
|
+
]);
|
|
6843
|
+
var EncodingBitratePolicy = _EncodingBitratePolicy;
|
|
6844
|
+
|
|
6735
6845
|
// src/Stream/Room/RoomHeartbeat.ts
|
|
6736
6846
|
var RoomHeartbeat = class {
|
|
6737
6847
|
/**
|
|
@@ -7022,7 +7132,7 @@ var RoomController = class {
|
|
|
7022
7132
|
*
|
|
7023
7133
|
* @throws 已有房间未离开、操作失效或进房失败时抛出错误。
|
|
7024
7134
|
*/
|
|
7025
|
-
async join(connection, ensureActive2) {
|
|
7135
|
+
async join(connection, ensureActive2, measureRtcJoin) {
|
|
7026
7136
|
try {
|
|
7027
7137
|
ensureActive2();
|
|
7028
7138
|
} catch (error) {
|
|
@@ -7041,11 +7151,14 @@ var RoomController = class {
|
|
|
7041
7151
|
if (!this.customCodec) this.codec = new RoomMessageCodec(
|
|
7042
7152
|
connection.provider === "vertc" /* vertc */ ? null : connection.provider === "agora" /* agora */ ? "__agora_chunk__" : "__trtc_chunk__"
|
|
7043
7153
|
);
|
|
7044
|
-
|
|
7154
|
+
const configuration = toRoomJoinConfiguration(connection);
|
|
7155
|
+
const completeRtcJoin = _optionalChain([measureRtcJoin, 'optionalCall', _574 => _574()]);
|
|
7156
|
+
await this.rtcManager.joinRoom(configuration);
|
|
7045
7157
|
ensureActive2();
|
|
7046
7158
|
if (this.state.kind !== "joining" || this.state.operationID !== operationID || this.leaveOperation) {
|
|
7047
7159
|
throw new XmaxError("CANCELLED" /* cancelled */, "RTC room join was cancelled");
|
|
7048
7160
|
}
|
|
7161
|
+
_optionalChain([completeRtcJoin, 'optionalCall', _575 => _575()]);
|
|
7049
7162
|
this.state = { kind: "joined", userID: connection.userID };
|
|
7050
7163
|
this.heartbeat.start(connection.userID);
|
|
7051
7164
|
} catch (error) {
|
|
@@ -7097,7 +7210,8 @@ var RoomController = class {
|
|
|
7097
7210
|
targetSize: options.targetSize,
|
|
7098
7211
|
mirror: _nullishCoalesce(options.mirror, () => ( false)),
|
|
7099
7212
|
faceRestoration: _nullishCoalesce(options.faceRestoration, () => ( false)),
|
|
7100
|
-
extraParams: options.extraParams
|
|
7213
|
+
extraParams: options.extraParams,
|
|
7214
|
+
...this.downlinkBitrates(_nullishCoalesce(options.targetSize, () => ( options.videoFormat)))
|
|
7101
7215
|
})
|
|
7102
7216
|
);
|
|
7103
7217
|
}
|
|
@@ -7136,10 +7250,23 @@ var RoomController = class {
|
|
|
7136
7250
|
RoomEvent.changeTargetSize({
|
|
7137
7251
|
userID: this.requireUserID(),
|
|
7138
7252
|
taskID: options.taskID,
|
|
7139
|
-
targetSize: options.targetSize
|
|
7253
|
+
targetSize: options.targetSize,
|
|
7254
|
+
...this.downlinkBitrates(options.targetSize)
|
|
7140
7255
|
})
|
|
7141
7256
|
);
|
|
7142
7257
|
}
|
|
7258
|
+
/**
|
|
7259
|
+
* 按回传尺寸和 24 fps 估算下行码率,最高值限制在 100~10000 kbps。
|
|
7260
|
+
* 估算不设置服务端帧率,也不沿用显式上传码率。
|
|
7261
|
+
*/
|
|
7262
|
+
downlinkBitrates(size) {
|
|
7263
|
+
const { maximum } = EncodingBitratePolicy.resolve(
|
|
7264
|
+
Math.round(size.width),
|
|
7265
|
+
Math.round(size.height),
|
|
7266
|
+
24
|
|
7267
|
+
);
|
|
7268
|
+
return { minimumBitrate: 100, maximumBitrate: Math.min(1e4, maximum) };
|
|
7269
|
+
}
|
|
7143
7270
|
/**
|
|
7144
7271
|
* 尝试发送生成停止信令;未进房或任务标识为空时忽略。
|
|
7145
7272
|
*/
|
|
@@ -7198,7 +7325,7 @@ var RoomController = class {
|
|
|
7198
7325
|
if (targetUserID && ownUserID && targetUserID !== ownUserID) {
|
|
7199
7326
|
return;
|
|
7200
7327
|
}
|
|
7201
|
-
_optionalChain([this, 'access',
|
|
7328
|
+
_optionalChain([this, 'access', _576 => _576.listener, 'optionalAccess', _577 => _577.onRoomMessage, 'call', _578 => _578(senderUserID, message)]);
|
|
7202
7329
|
}
|
|
7203
7330
|
/**
|
|
7204
7331
|
* 发送房间信令并输出日志。
|
|
@@ -7241,7 +7368,7 @@ var ENCODER_PREFERENCE_MAP = {
|
|
|
7241
7368
|
["maintainFramerate" /* maintainFramerate */]: "maintainFramerate" /* maintainFramerate */,
|
|
7242
7369
|
["maintainQuality" /* maintainQuality */]: "maintainQuality" /* maintainQuality */
|
|
7243
7370
|
};
|
|
7244
|
-
var
|
|
7371
|
+
var EncodingController = class {
|
|
7245
7372
|
/**
|
|
7246
7373
|
* 创建编码控制器。
|
|
7247
7374
|
*
|
|
@@ -7266,21 +7393,13 @@ var _EncodingController = class _EncodingController {
|
|
|
7266
7393
|
minimum = videoFormat.minimumBitrate;
|
|
7267
7394
|
maximum = videoFormat.maximumBitrate;
|
|
7268
7395
|
} else {
|
|
7269
|
-
const
|
|
7270
|
-
videoFormat.width
|
|
7396
|
+
const defaults = EncodingBitratePolicy.resolve(
|
|
7397
|
+
videoFormat.width,
|
|
7398
|
+
videoFormat.height,
|
|
7271
7399
|
videoFormat.fps
|
|
7272
7400
|
);
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
throw new XmaxError(
|
|
7276
|
-
"INVALID_CONFIGURATION" /* invalidConfiguration */,
|
|
7277
|
-
"Realtime video format exceeds the supported bitrate range"
|
|
7278
|
-
);
|
|
7279
|
-
}
|
|
7280
|
-
const defaultMinimum = Math.max(1, Math.round(bitrates.minimum));
|
|
7281
|
-
const defaultMaximum = Math.max(defaultMinimum + 1, maximumBitrate);
|
|
7282
|
-
minimum = _nullishCoalesce(videoFormat.minimumBitrate, () => ( defaultMinimum));
|
|
7283
|
-
maximum = _nullishCoalesce(videoFormat.maximumBitrate, () => ( defaultMaximum));
|
|
7401
|
+
minimum = _nullishCoalesce(videoFormat.minimumBitrate, () => ( defaults.minimum));
|
|
7402
|
+
maximum = _nullishCoalesce(videoFormat.maximumBitrate, () => ( defaults.maximum));
|
|
7284
7403
|
}
|
|
7285
7404
|
if (minimum > maximum) {
|
|
7286
7405
|
throw new XmaxError(
|
|
@@ -7321,97 +7440,7 @@ var _EncodingController = class _EncodingController {
|
|
|
7321
7440
|
}
|
|
7322
7441
|
return format;
|
|
7323
7442
|
}
|
|
7324
|
-
/**
|
|
7325
|
-
* 按像素面积与帧率计算码率区间(kbps):流畅优先为最低,画质优先为最高。
|
|
7326
|
-
*/
|
|
7327
|
-
static resolveBitrates(pixels, fps) {
|
|
7328
|
-
const bitrate15 = _EncodingController.interpolate(
|
|
7329
|
-
pixels,
|
|
7330
|
-
_EncodingController.referenceBitratesAt15FPS
|
|
7331
|
-
);
|
|
7332
|
-
const first30 = _EncodingController.referenceBitratesAt30FPS[0];
|
|
7333
|
-
let bitrate30;
|
|
7334
|
-
if (pixels < first30.value) {
|
|
7335
|
-
const reference15 = _EncodingController.interpolate(
|
|
7336
|
-
first30.value,
|
|
7337
|
-
_EncodingController.referenceBitratesAt15FPS
|
|
7338
|
-
);
|
|
7339
|
-
bitrate30 = bitrate15 * (first30.bitrate / reference15);
|
|
7340
|
-
} else {
|
|
7341
|
-
bitrate30 = _EncodingController.interpolate(
|
|
7342
|
-
pixels,
|
|
7343
|
-
_EncodingController.referenceBitratesAt30FPS
|
|
7344
|
-
);
|
|
7345
|
-
}
|
|
7346
|
-
const bitrate10 = bitrate15 * (400 / 500);
|
|
7347
|
-
const minimum60 = bitrate30 * (4780 / 3150);
|
|
7348
|
-
const maximum60 = bitrate30 * (6500 / 3150);
|
|
7349
|
-
return {
|
|
7350
|
-
minimum: _EncodingController.interpolate(fps, [
|
|
7351
|
-
{ value: 10, bitrate: bitrate10 },
|
|
7352
|
-
{ value: 15, bitrate: bitrate15 },
|
|
7353
|
-
{ value: 30, bitrate: bitrate30 },
|
|
7354
|
-
{ value: 60, bitrate: minimum60 }
|
|
7355
|
-
]),
|
|
7356
|
-
maximum: _EncodingController.interpolate(fps, [
|
|
7357
|
-
{ value: 10, bitrate: bitrate10 * 2 },
|
|
7358
|
-
{ value: 15, bitrate: bitrate15 * 2 },
|
|
7359
|
-
{ value: 30, bitrate: bitrate30 * 2 },
|
|
7360
|
-
{ value: 60, bitrate: maximum60 }
|
|
7361
|
-
])
|
|
7362
|
-
};
|
|
7363
|
-
}
|
|
7364
|
-
/**
|
|
7365
|
-
* 在相邻参考点间线性插值,表外按最近端点的比例外推。
|
|
7366
|
-
*/
|
|
7367
|
-
static interpolate(value, points) {
|
|
7368
|
-
const first = points[0];
|
|
7369
|
-
if (value <= first.value) {
|
|
7370
|
-
return first.bitrate * (value / first.value);
|
|
7371
|
-
}
|
|
7372
|
-
for (let index = 1; index < points.length; index += 1) {
|
|
7373
|
-
const upper = points[index];
|
|
7374
|
-
if (value <= upper.value) {
|
|
7375
|
-
const lower = points[index - 1];
|
|
7376
|
-
const ratio = (value - lower.value) / (upper.value - lower.value);
|
|
7377
|
-
return lower.bitrate + (upper.bitrate - lower.bitrate) * ratio;
|
|
7378
|
-
}
|
|
7379
|
-
}
|
|
7380
|
-
const last = points[points.length - 1];
|
|
7381
|
-
return last.bitrate * (value / last.value);
|
|
7382
|
-
}
|
|
7383
7443
|
};
|
|
7384
|
-
/**
|
|
7385
|
-
* 流畅优先码率参考,按像素面积升序排列,单位为 kbps。
|
|
7386
|
-
*/
|
|
7387
|
-
_chunk4DE2IREAcjs.__publicField.call(void 0, _EncodingController, "referenceBitratesAt15FPS", [
|
|
7388
|
-
{ value: 120 * 120, bitrate: 50 },
|
|
7389
|
-
{ value: 160 * 120, bitrate: 65 },
|
|
7390
|
-
{ value: 180 * 180, bitrate: 100 },
|
|
7391
|
-
{ value: 240 * 180, bitrate: 120 },
|
|
7392
|
-
{ value: 320 * 180, bitrate: 140 },
|
|
7393
|
-
{ value: 320 * 240, bitrate: 200 },
|
|
7394
|
-
{ value: 424 * 240, bitrate: 220 },
|
|
7395
|
-
{ value: 360 * 360, bitrate: 260 },
|
|
7396
|
-
{ value: 480 * 360, bitrate: 320 },
|
|
7397
|
-
{ value: 640 * 360, bitrate: 400 },
|
|
7398
|
-
{ value: 640 * 480, bitrate: 500 },
|
|
7399
|
-
{ value: 848 * 480, bitrate: 610 },
|
|
7400
|
-
{ value: 960 * 720, bitrate: 910 },
|
|
7401
|
-
{ value: 1280 * 720, bitrate: 1130 },
|
|
7402
|
-
{ value: 1920 * 1080, bitrate: 2080 }
|
|
7403
|
-
]);
|
|
7404
|
-
_chunk4DE2IREAcjs.__publicField.call(void 0, _EncodingController, "referenceBitratesAt30FPS", [
|
|
7405
|
-
{ value: 360 * 360, bitrate: 400 },
|
|
7406
|
-
{ value: 480 * 360, bitrate: 490 },
|
|
7407
|
-
{ value: 640 * 360, bitrate: 600 },
|
|
7408
|
-
{ value: 640 * 480, bitrate: 750 },
|
|
7409
|
-
{ value: 848 * 480, bitrate: 930 },
|
|
7410
|
-
{ value: 960 * 720, bitrate: 1380 },
|
|
7411
|
-
{ value: 1280 * 720, bitrate: 1710 },
|
|
7412
|
-
{ value: 1920 * 1080, bitrate: 3150 }
|
|
7413
|
-
]);
|
|
7414
|
-
var EncodingController = _EncodingController;
|
|
7415
7444
|
|
|
7416
7445
|
// src/Stream/StreamController.ts
|
|
7417
7446
|
function makeInitialState() {
|
|
@@ -7480,7 +7509,7 @@ var StreamController = class {
|
|
|
7480
7509
|
this.roomController.setListener({
|
|
7481
7510
|
onRoomMessage: (sender, message) => {
|
|
7482
7511
|
this.handleNetworkVideoCompletion(sender, message);
|
|
7483
|
-
_optionalChain([this, 'access',
|
|
7512
|
+
_optionalChain([this, 'access', _579 => _579.roomListener, 'optionalAccess', _580 => _580.onRoomMessage, 'call', _581 => _581(sender, message)]);
|
|
7484
7513
|
}
|
|
7485
7514
|
});
|
|
7486
7515
|
this.rtcManager.setEventListener({
|
|
@@ -7490,18 +7519,18 @@ var StreamController = class {
|
|
|
7490
7519
|
onError: (error) => this.errorListener(error),
|
|
7491
7520
|
onNetworkStatistics: (statistics) => {
|
|
7492
7521
|
if (this.state.roomID) {
|
|
7493
|
-
_optionalChain([this, 'access',
|
|
7522
|
+
_optionalChain([this, 'access', _582 => _582.networkStatisticsListener, 'optionalCall', _583 => _583(statistics)]);
|
|
7494
7523
|
}
|
|
7495
7524
|
},
|
|
7496
7525
|
onRemoteVideoStatistics: (statistics) => {
|
|
7497
|
-
const userID = _optionalChain([this, 'access',
|
|
7498
|
-
_optionalChain([this, 'access',
|
|
7526
|
+
const userID = _optionalChain([this, 'access', _584 => _584.state, 'access', _585 => _585.activeRemoteStream, 'optionalAccess', _586 => _586.userID]);
|
|
7527
|
+
_optionalChain([this, 'access', _587 => _587.remoteVideoStatisticsListener, 'optionalCall', _588 => _588(
|
|
7499
7528
|
userID ? statistics.find((item) => item.userID === userID) : void 0
|
|
7500
7529
|
)]);
|
|
7501
7530
|
},
|
|
7502
7531
|
onLocalVideoStatistics: (statistics) => {
|
|
7503
7532
|
if (this.state.localVideoPublished) {
|
|
7504
|
-
_optionalChain([this, 'access',
|
|
7533
|
+
_optionalChain([this, 'access', _589 => _589.localVideoStatisticsListener, 'optionalCall', _590 => _590(statistics)]);
|
|
7505
7534
|
}
|
|
7506
7535
|
},
|
|
7507
7536
|
onCustomMessageReceived: (senderUserID, message) => {
|
|
@@ -7522,7 +7551,7 @@ var StreamController = class {
|
|
|
7522
7551
|
* 按活动结果流身份读取原始音视频,避免录制房间内其他用户的媒体。
|
|
7523
7552
|
*/
|
|
7524
7553
|
getRemoteRecordingTracks() {
|
|
7525
|
-
const userID = _optionalChain([this, 'access',
|
|
7554
|
+
const userID = _optionalChain([this, 'access', _591 => _591.state, 'access', _592 => _592.activeRemoteStream, 'optionalAccess', _593 => _593.userID]);
|
|
7526
7555
|
const videoTrack = userID && this.state.remoteVideoTracks.get(userID);
|
|
7527
7556
|
if (!userID || !videoTrack) {
|
|
7528
7557
|
return void 0;
|
|
@@ -7580,16 +7609,16 @@ var StreamController = class {
|
|
|
7580
7609
|
*
|
|
7581
7610
|
* @throws 连接已取消,或 RTC 进房、房间配置与本地流发布失败时抛出错误。
|
|
7582
7611
|
*/
|
|
7583
|
-
async connect(connection, includeLocalAudio, ensureActive2, beforePublish, publishLocalMedia = true) {
|
|
7612
|
+
async connect(connection, includeLocalAudio, ensureActive2, beforePublish, publishLocalMedia = true, measureRtcJoin) {
|
|
7584
7613
|
this.configureRoom({ roomID: connection.roomID, botID: connection.botID });
|
|
7585
|
-
await this.roomController.join(connection, ensureActive2);
|
|
7614
|
+
await this.roomController.join(connection, ensureActive2, measureRtcJoin);
|
|
7586
7615
|
ensureActive2();
|
|
7587
7616
|
XmaxLogger.stream.info(
|
|
7588
7617
|
() => `RTC \u623F\u95F4\u5DF2\u914D\u7F6E (RTC Room Configured)
|
|
7589
7618
|
\u2514\u2500 roomID: ${connection.roomID}, botID: ${_nullishCoalesce(connection.botID, () => ( "(\u672A\u8BBE\u7F6E)"))}`
|
|
7590
7619
|
);
|
|
7591
7620
|
if (publishLocalMedia) {
|
|
7592
|
-
await _optionalChain([beforePublish, 'optionalCall',
|
|
7621
|
+
await _optionalChain([beforePublish, 'optionalCall', _594 => _594()]);
|
|
7593
7622
|
ensureActive2();
|
|
7594
7623
|
await this.publishLocalStream(includeLocalAudio);
|
|
7595
7624
|
}
|
|
@@ -7679,7 +7708,7 @@ var StreamController = class {
|
|
|
7679
7708
|
const state2 = this.state;
|
|
7680
7709
|
const sent = Promise.resolve(sending).then(async () => {
|
|
7681
7710
|
if (this.state !== state2 || state2.generationTaskID !== taskID) return;
|
|
7682
|
-
await _optionalChain([options, 'access',
|
|
7711
|
+
await _optionalChain([options, 'access', _595 => _595.onStartSent, 'optionalCall', _596 => _596()]);
|
|
7683
7712
|
if (this.state !== state2 || state2.generationTaskID !== taskID) return;
|
|
7684
7713
|
for (const userID of state2.publishedRemoteUserIDs) {
|
|
7685
7714
|
void this.handleRemoteVideoPublished(userID, true);
|
|
@@ -7825,7 +7854,7 @@ var StreamController = class {
|
|
|
7825
7854
|
deliverNetworkVideoCompletion() {
|
|
7826
7855
|
const state2 = this.state;
|
|
7827
7856
|
const completion = state2.networkVideoCompletion;
|
|
7828
|
-
if (!_optionalChain([completion, 'optionalAccess',
|
|
7857
|
+
if (!_optionalChain([completion, 'optionalAccess', _597 => _597.finished]) || !completion.onFinish || completion.scheduled) {
|
|
7829
7858
|
return;
|
|
7830
7859
|
}
|
|
7831
7860
|
completion.scheduled = true;
|
|
@@ -7834,7 +7863,7 @@ var StreamController = class {
|
|
|
7834
7863
|
return;
|
|
7835
7864
|
}
|
|
7836
7865
|
try {
|
|
7837
|
-
void Promise.resolve(_optionalChain([completion, 'access',
|
|
7866
|
+
void Promise.resolve(_optionalChain([completion, 'access', _598 => _598.onFinish, 'optionalCall', _599 => _599()])).catch(() => {
|
|
7838
7867
|
});
|
|
7839
7868
|
} catch (e27) {
|
|
7840
7869
|
}
|
|
@@ -7845,7 +7874,7 @@ var StreamController = class {
|
|
|
7845
7874
|
*/
|
|
7846
7875
|
configureRoom(options) {
|
|
7847
7876
|
const roomID = options.roomID.trim();
|
|
7848
|
-
const botID = _nullishCoalesce(_optionalChain([options, 'access',
|
|
7877
|
+
const botID = _nullishCoalesce(_optionalChain([options, 'access', _600 => _600.botID, 'optionalAccess', _601 => _601.trim, 'call', _602 => _602()]), () => ( ""));
|
|
7849
7878
|
if (!roomID) {
|
|
7850
7879
|
throw new XmaxError(
|
|
7851
7880
|
"INVALID_CONFIGURATION" /* invalidConfiguration */,
|
|
@@ -7928,7 +7957,7 @@ var StreamController = class {
|
|
|
7928
7957
|
return;
|
|
7929
7958
|
}
|
|
7930
7959
|
this.state.subscribedRemoteUserIDs.delete(trimmedUserID);
|
|
7931
|
-
if (_optionalChain([this, 'access',
|
|
7960
|
+
if (_optionalChain([this, 'access', _603 => _603.state, 'access', _604 => _604.activeRemoteStream, 'optionalAccess', _605 => _605.userID]) === trimmedUserID) {
|
|
7932
7961
|
await this.unsubscribeRemoteAudio(trimmedUserID);
|
|
7933
7962
|
this.state.activeRemoteStream = void 0;
|
|
7934
7963
|
this.clearRemoteStream();
|
|
@@ -8118,7 +8147,7 @@ var StreamController = class {
|
|
|
8118
8147
|
*/
|
|
8119
8148
|
resolveGenerationStart(taskID) {
|
|
8120
8149
|
const waiter = this.state.generationWaiter;
|
|
8121
|
-
if (this.state.generationTaskID !== taskID || _optionalChain([waiter, 'optionalAccess',
|
|
8150
|
+
if (this.state.generationTaskID !== taskID || _optionalChain([waiter, 'optionalAccess', _606 => _606.taskID]) !== taskID) {
|
|
8122
8151
|
return;
|
|
8123
8152
|
}
|
|
8124
8153
|
this.state.generationWaiter = void 0;
|
|
@@ -8130,7 +8159,7 @@ var StreamController = class {
|
|
|
8130
8159
|
*/
|
|
8131
8160
|
rejectGenerationStart(taskID, error) {
|
|
8132
8161
|
const waiter = this.state.generationWaiter;
|
|
8133
|
-
if (this.state.generationTaskID !== taskID || _optionalChain([waiter, 'optionalAccess',
|
|
8162
|
+
if (this.state.generationTaskID !== taskID || _optionalChain([waiter, 'optionalAccess', _607 => _607.taskID]) !== taskID) {
|
|
8134
8163
|
return;
|
|
8135
8164
|
}
|
|
8136
8165
|
this.state.generationWaiter = void 0;
|
|
@@ -8141,7 +8170,7 @@ var StreamController = class {
|
|
|
8141
8170
|
* 通知渲染层清理远端生成流;失败仅记录日志。
|
|
8142
8171
|
*/
|
|
8143
8172
|
clearRemoteStream() {
|
|
8144
|
-
_optionalChain([this, 'access',
|
|
8173
|
+
_optionalChain([this, 'access', _608 => _608.remoteVideoStatisticsListener, 'optionalCall', _609 => _609(void 0)]);
|
|
8145
8174
|
try {
|
|
8146
8175
|
this.remoteStreamListener(null);
|
|
8147
8176
|
} catch (error) {
|
|
@@ -8180,12 +8209,13 @@ var StreamController = class {
|
|
|
8180
8209
|
|
|
8181
8210
|
// src/Stream/Quality/QualityTiers.ts
|
|
8182
8211
|
var INITIAL_QUALITY_LEVEL = 2;
|
|
8212
|
+
var MINIMUM_QUALITY_SHORT_SIDE = 240;
|
|
8183
8213
|
var QUALITY_TIERS = {
|
|
8184
|
-
L1: { width: 1024, height: 1920, frameRate: 30 },
|
|
8185
|
-
L2: { width:
|
|
8186
|
-
L3: { width:
|
|
8187
|
-
L4: { width: 512, height: 960, frameRate: 20 },
|
|
8188
|
-
L5: { width:
|
|
8214
|
+
L1: { scale: 1, width: 1024, height: 1920, frameRate: 30 },
|
|
8215
|
+
L2: { scale: 0.8, width: 818, height: 1536, frameRate: 24 },
|
|
8216
|
+
L3: { scale: 0.65, width: 664, height: 1248, frameRate: 24 },
|
|
8217
|
+
L4: { scale: 0.5, width: 512, height: 960, frameRate: 20 },
|
|
8218
|
+
L5: { scale: 0.4, width: 408, height: 768, frameRate: 16 }
|
|
8189
8219
|
};
|
|
8190
8220
|
|
|
8191
8221
|
// src/Stream/Quality/QualityPolicy.ts
|
|
@@ -8201,9 +8231,13 @@ var DEFAULT_POLICY = {
|
|
|
8201
8231
|
// src/Stream/Quality/QualityController.ts
|
|
8202
8232
|
var ORDERED_QUALITY_TIERS = Object.values(QUALITY_TIERS);
|
|
8203
8233
|
var QualityController = class {
|
|
8204
|
-
|
|
8234
|
+
/**
|
|
8235
|
+
* 创建调档状态机;候选档位不满足编码约束时保持当前档位,不跨档尝试。
|
|
8236
|
+
*/
|
|
8237
|
+
constructor(apply, now = () => performance.now(), policy = {}, canApply = () => true) {
|
|
8205
8238
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "apply", apply);
|
|
8206
8239
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "now", now);
|
|
8240
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "canApply", canApply);
|
|
8207
8241
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "policy");
|
|
8208
8242
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "active", false);
|
|
8209
8243
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "index", 0);
|
|
@@ -8293,10 +8327,13 @@ var QualityController = class {
|
|
|
8293
8327
|
this.good = this.poor = 0;
|
|
8294
8328
|
}
|
|
8295
8329
|
async change(index, reason) {
|
|
8330
|
+
this.resetCounts();
|
|
8331
|
+
if (!this.canApply(index + 1)) {
|
|
8332
|
+
return;
|
|
8333
|
+
}
|
|
8296
8334
|
const lifecycle = this.lifecycle;
|
|
8297
8335
|
const change = { from: this.index + 1, to: index + 1, ...ORDERED_QUALITY_TIERS[index], reason };
|
|
8298
8336
|
this.switching = true;
|
|
8299
|
-
this.resetCounts();
|
|
8300
8337
|
try {
|
|
8301
8338
|
await this.apply(change, lifecycle.signal);
|
|
8302
8339
|
if (lifecycle.signal.aborted) return;
|
|
@@ -8321,12 +8358,20 @@ var QualityController = class {
|
|
|
8321
8358
|
// src/Stream/Quality/QualityVideoFormat.ts
|
|
8322
8359
|
function qualityVideoSize(baseline, level) {
|
|
8323
8360
|
const tier = Object.values(QUALITY_TIERS)[level - 1];
|
|
8324
|
-
if (!Number.isInteger(level) || !tier)
|
|
8361
|
+
if (!Number.isInteger(level) || !tier) {
|
|
8362
|
+
throw new Error("Unsupported quality level");
|
|
8363
|
+
}
|
|
8325
8364
|
baseline.validate();
|
|
8326
|
-
const
|
|
8327
|
-
const
|
|
8365
|
+
const shortSide = Math.min(baseline.width, baseline.height);
|
|
8366
|
+
const minimum = Math.min(shortSide, MINIMUM_QUALITY_SHORT_SIDE);
|
|
8367
|
+
const scale = Math.max(tier.scale, minimum / shortSide);
|
|
8368
|
+
const even = (value) => Math.max(2, Math.floor(value / 2 + 1e-9) * 2);
|
|
8328
8369
|
return { width: even(baseline.width * scale), height: even(baseline.height * scale) };
|
|
8329
8370
|
}
|
|
8371
|
+
function supportsQualityEncoding(format) {
|
|
8372
|
+
const defaults = EncodingBitratePolicy.resolve(format.width, format.height, format.fps);
|
|
8373
|
+
return (_nullishCoalesce(format.minimumBitrate, () => ( defaults.minimum))) <= (_nullishCoalesce(format.maximumBitrate, () => ( defaults.maximum)));
|
|
8374
|
+
}
|
|
8330
8375
|
function qualityVideoFormat(baseline, level) {
|
|
8331
8376
|
const size = qualityVideoSize(baseline, level);
|
|
8332
8377
|
const tier = Object.values(QUALITY_TIERS)[level - 1];
|
|
@@ -8338,35 +8383,59 @@ function qualityVideoFormat(baseline, level) {
|
|
|
8338
8383
|
}
|
|
8339
8384
|
|
|
8340
8385
|
// src/Stream/Quality/QualityHistory.ts
|
|
8341
|
-
var
|
|
8342
|
-
|
|
8386
|
+
var _QualityHistory = class _QualityHistory {
|
|
8387
|
+
/**
|
|
8388
|
+
* 创建按模型与 RTC 提供方隔离的档位存储。
|
|
8389
|
+
*/
|
|
8390
|
+
constructor(model, provider, now = Date.now) {
|
|
8343
8391
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "model", model);
|
|
8344
8392
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "provider", provider);
|
|
8393
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "now", now);
|
|
8345
8394
|
}
|
|
8346
|
-
/**
|
|
8395
|
+
/**
|
|
8396
|
+
* 无记录、过期、损坏、时钟回退或存储不可用时使用默认 L2。
|
|
8397
|
+
*/
|
|
8347
8398
|
read(direction) {
|
|
8348
8399
|
try {
|
|
8349
|
-
const
|
|
8350
|
-
|
|
8400
|
+
const entry = JSON.parse(_nullishCoalesce(globalThis.localStorage.getItem(this.key(direction)), () => ( "null")));
|
|
8401
|
+
const now = this.now();
|
|
8402
|
+
if (entry && this.isValid(entry.level) && Number.isFinite(entry.savedAt) && entry.savedAt > 0 && now >= entry.savedAt && now - entry.savedAt < _QualityHistory.expirationMs) {
|
|
8403
|
+
return entry.level;
|
|
8404
|
+
}
|
|
8351
8405
|
} catch (e28) {
|
|
8352
8406
|
}
|
|
8353
8407
|
return INITIAL_QUALITY_LEVEL;
|
|
8354
8408
|
}
|
|
8355
|
-
/**
|
|
8409
|
+
/**
|
|
8410
|
+
* 应用成功后保存档位并刷新一小时有效期;下行成功仅表示信令已发送。
|
|
8411
|
+
*/
|
|
8356
8412
|
write(direction, level) {
|
|
8357
|
-
if (!this.isValid(level))
|
|
8413
|
+
if (!this.isValid(level)) {
|
|
8414
|
+
return;
|
|
8415
|
+
}
|
|
8358
8416
|
try {
|
|
8359
|
-
globalThis.localStorage.setItem(this.key(direction),
|
|
8417
|
+
globalThis.localStorage.setItem(this.key(direction), JSON.stringify({ level, savedAt: this.now() }));
|
|
8360
8418
|
} catch (e29) {
|
|
8361
8419
|
}
|
|
8362
8420
|
}
|
|
8421
|
+
/**
|
|
8422
|
+
* 生成当前方向的存储键;无时间戳的旧记录按无效记录处理。
|
|
8423
|
+
*/
|
|
8363
8424
|
key(direction) {
|
|
8364
8425
|
return `xmax:quality:v1:${this.provider}:${encodeURIComponent(this.model)}:${direction}`;
|
|
8365
8426
|
}
|
|
8427
|
+
/**
|
|
8428
|
+
* 校验档位编号。
|
|
8429
|
+
*/
|
|
8366
8430
|
isValid(level) {
|
|
8367
8431
|
return Number.isInteger(level) && level >= 1 && level <= Object.keys(QUALITY_TIERS).length;
|
|
8368
8432
|
}
|
|
8369
8433
|
};
|
|
8434
|
+
/**
|
|
8435
|
+
* 历史档位有效期,单位为毫秒。
|
|
8436
|
+
*/
|
|
8437
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, _QualityHistory, "expirationMs", 60 * 60 * 1e3);
|
|
8438
|
+
var QualityHistory = _QualityHistory;
|
|
8370
8439
|
|
|
8371
8440
|
// src/Core/Realtime/RealtimeCoordinator.ts
|
|
8372
8441
|
function scopeAffects(scope, kind) {
|
|
@@ -8504,7 +8573,7 @@ var RealtimeCoordinator = class _RealtimeCoordinator {
|
|
|
8504
8573
|
await this.errorHandler.report(error);
|
|
8505
8574
|
throw error;
|
|
8506
8575
|
}
|
|
8507
|
-
const operationKind = kind === "generation" /* generation */ && this.state.connectionState === "Generating" /* generating */ ? "configuration" /* configuration */ : kind;
|
|
8576
|
+
const operationKind = kind === "generation" /* generation */ && (this.state.connectionState === "Generating" /* generating */ || this.state.connectionState === "Starting" /* starting */ && !!this.state.taskID) ? "configuration" /* configuration */ : kind;
|
|
8508
8577
|
const lease = new OperationLease(failureScope);
|
|
8509
8578
|
const resultPromise = (async () => body(lease))();
|
|
8510
8579
|
const operation = {
|
|
@@ -8544,6 +8613,19 @@ var RealtimeCoordinator = class _RealtimeCoordinator {
|
|
|
8544
8613
|
new RealtimeState({ connectionState: "Ready" /* ready */ })
|
|
8545
8614
|
);
|
|
8546
8615
|
}
|
|
8616
|
+
/**
|
|
8617
|
+
* 当前生成任务和远端展示均就绪后进入 generating;迟到通知不恢复已结束任务。
|
|
8618
|
+
*/
|
|
8619
|
+
async remotePreviewDidBecomeReady(sessionID, taskID, isCurrent) {
|
|
8620
|
+
if (this.termination || this.state.connectionState !== "Starting" /* starting */ || this.state.sessionID !== sessionID || this.state.taskID !== taskID || !isCurrent()) {
|
|
8621
|
+
return;
|
|
8622
|
+
}
|
|
8623
|
+
await this.setState(new RealtimeState({
|
|
8624
|
+
connectionState: "Generating" /* generating */,
|
|
8625
|
+
sessionID,
|
|
8626
|
+
taskID
|
|
8627
|
+
}));
|
|
8628
|
+
}
|
|
8547
8629
|
/**
|
|
8548
8630
|
* 断开实时连接;尚未提交连接状态的活跃操作也会被取消。
|
|
8549
8631
|
*/
|
|
@@ -8606,7 +8688,7 @@ var RealtimeCoordinator = class _RealtimeCoordinator {
|
|
|
8606
8688
|
}
|
|
8607
8689
|
throw _RealtimeCoordinator.cancelledError();
|
|
8608
8690
|
}
|
|
8609
|
-
const terminationTask = await _asyncNullishCoalesce(await _asyncNullishCoalesce(operation.terminationTask, async () => ( _optionalChain([this, 'access',
|
|
8691
|
+
const terminationTask = await _asyncNullishCoalesce(await _asyncNullishCoalesce(operation.terminationTask, async () => ( _optionalChain([this, 'access', _610 => _610.termination, 'optionalAccess', _611 => _611.task]))), async () => ( await this.requestTermination(
|
|
8610
8692
|
_nullishCoalesce(operation.lease.failureScope, () => ( 0)) /* connection */,
|
|
8611
8693
|
void 0,
|
|
8612
8694
|
RealtimeReason.normal,
|
|
@@ -8735,7 +8817,7 @@ var RealtimeCoordinator = class _RealtimeCoordinator {
|
|
|
8735
8817
|
* 结束指定操作,释放操作准入场。
|
|
8736
8818
|
*/
|
|
8737
8819
|
finish(operation) {
|
|
8738
|
-
if (_optionalChain([this, 'access',
|
|
8820
|
+
if (_optionalChain([this, 'access', _612 => _612.activeOperation, 'optionalAccess', _613 => _613.id]) === operation.id) {
|
|
8739
8821
|
this.activeOperation = void 0;
|
|
8740
8822
|
}
|
|
8741
8823
|
}
|
|
@@ -8747,7 +8829,7 @@ var RealtimeCoordinator = class _RealtimeCoordinator {
|
|
|
8747
8829
|
return;
|
|
8748
8830
|
}
|
|
8749
8831
|
this.state = nextState;
|
|
8750
|
-
_optionalChain([this, 'access',
|
|
8832
|
+
_optionalChain([this, 'access', _614 => _614.stateListener, 'optionalCall', _615 => _615(nextState)]);
|
|
8751
8833
|
}
|
|
8752
8834
|
/**
|
|
8753
8835
|
* 构造统一的操作取消错误。
|
|
@@ -8836,11 +8918,16 @@ var RealtimeLaunchTimer = class {
|
|
|
8836
8918
|
return this.measure("permissionMs", performance.now());
|
|
8837
8919
|
}
|
|
8838
8920
|
/**
|
|
8839
|
-
*
|
|
8840
|
-
|
|
8921
|
+
* 开始创建业务会话的计时。
|
|
8922
|
+
*/
|
|
8923
|
+
startSession() {
|
|
8924
|
+
return this.measure("sessionMs", performance.now());
|
|
8925
|
+
}
|
|
8926
|
+
/**
|
|
8927
|
+
* 开始 RTC 适配器进房调用的计时。
|
|
8841
8928
|
*/
|
|
8842
|
-
|
|
8843
|
-
return this.measure("
|
|
8929
|
+
startRtcJoin() {
|
|
8930
|
+
return this.measure("rtcJoinMs", performance.now());
|
|
8844
8931
|
}
|
|
8845
8932
|
/**
|
|
8846
8933
|
* 开始发布本地流计时,返回发布完成时调用的记录函数。
|
|
@@ -8849,11 +8936,17 @@ var RealtimeLaunchTimer = class {
|
|
|
8849
8936
|
return this.measure("publishMs", performance.now());
|
|
8850
8937
|
}
|
|
8851
8938
|
/**
|
|
8852
|
-
*
|
|
8939
|
+
* 开始等待远端首帧提交合成器,不包含后续渲染预热。
|
|
8853
8940
|
*/
|
|
8854
8941
|
startFirstFrame() {
|
|
8855
8942
|
return this.measure("firstFrameMs", performance.now());
|
|
8856
8943
|
}
|
|
8944
|
+
/**
|
|
8945
|
+
* 首帧就绪后开始渲染预热;结束时记录预热及实际总耗时,不含渐入动画。
|
|
8946
|
+
*/
|
|
8947
|
+
startRenderWarmup() {
|
|
8948
|
+
return this.measure("renderWarmupMs", performance.now());
|
|
8949
|
+
}
|
|
8857
8950
|
/**
|
|
8858
8951
|
* 冻结本轮结果,令尚未完成的回调失效;下一轮相机启动才重置。
|
|
8859
8952
|
*/
|
|
@@ -8874,7 +8967,7 @@ var RealtimeLaunchTimer = class {
|
|
|
8874
8967
|
this.snapshot = Object.freeze({
|
|
8875
8968
|
...this.snapshot,
|
|
8876
8969
|
[key]: now - startedAt,
|
|
8877
|
-
...key === "
|
|
8970
|
+
...key === "renderWarmupMs" ? { totalMs: now - this.startedAt } : {}
|
|
8878
8971
|
});
|
|
8879
8972
|
this.notify();
|
|
8880
8973
|
};
|
|
@@ -8884,7 +8977,7 @@ var RealtimeLaunchTimer = class {
|
|
|
8884
8977
|
*/
|
|
8885
8978
|
notify() {
|
|
8886
8979
|
try {
|
|
8887
|
-
void Promise.resolve(_optionalChain([this, 'access',
|
|
8980
|
+
void Promise.resolve(_optionalChain([this, 'access', _616 => _616.listener, 'optionalCall', _617 => _617(this.snapshot)])).catch(() => {
|
|
8888
8981
|
});
|
|
8889
8982
|
} catch (e30) {
|
|
8890
8983
|
}
|
|
@@ -8915,7 +9008,7 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
8915
9008
|
* 当前活动会话标识;尚未连接或清理完成后为空。
|
|
8916
9009
|
*/
|
|
8917
9010
|
get currentSessionID() {
|
|
8918
|
-
return _optionalChain([this, 'access',
|
|
9011
|
+
return _optionalChain([this, 'access', _618 => _618.activeSession, 'optionalAccess', _619 => _619.id]);
|
|
8919
9012
|
}
|
|
8920
9013
|
/**
|
|
8921
9014
|
* 未配置 API 服务时在连接操作开始前报错,不影响本地预览。
|
|
@@ -8925,8 +9018,8 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
8925
9018
|
}
|
|
8926
9019
|
/**
|
|
8927
9020
|
* 创建会话、配置编码、进房并发布本地媒体,启动心跳后返回远端占位流。
|
|
8928
|
-
*
|
|
8929
|
-
*
|
|
9021
|
+
* 会话创建、RTC 进房和本地流发布分别计时;可选 beforePublish 检查阻塞发布,
|
|
9022
|
+
* 其等待只反映在实际完整启动耗时中。
|
|
8930
9023
|
* @param options.localTrack 当前本地媒体轨道。
|
|
8931
9024
|
* @param options.remoteVideoFormat 原始生成及远端画面规格,缺省使用本地轨道规格。
|
|
8932
9025
|
* @param options.localVideoFormat 发布前实际应用的上行编码格式;与原始生成及远端格式分开。
|
|
@@ -8943,10 +9036,11 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
8943
9036
|
const sessionService = this.requireSessionService();
|
|
8944
9037
|
const streamController = this.dependencies.streamController;
|
|
8945
9038
|
options.ensureCurrent();
|
|
8946
|
-
const
|
|
9039
|
+
const completeSession = this.dependencies.timing.startSession();
|
|
8947
9040
|
const session = await sessionService.createSession(options.model);
|
|
8948
9041
|
this.activeSession = session;
|
|
8949
9042
|
options.ensureCurrent();
|
|
9043
|
+
completeSession();
|
|
8950
9044
|
const connection = session.connection;
|
|
8951
9045
|
if (!connection) {
|
|
8952
9046
|
throw new XmaxError(
|
|
@@ -8970,7 +9064,7 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
8970
9064
|
if (publishLocalMedia) {
|
|
8971
9065
|
await streamController.updateUplinkVideoFormat(videoFormat);
|
|
8972
9066
|
options.ensureCurrent();
|
|
8973
|
-
_optionalChain([options, 'access',
|
|
9067
|
+
_optionalChain([options, 'access', _620 => _620.onVideoEncoderConfigured, 'optionalCall', _621 => _621()]);
|
|
8974
9068
|
}
|
|
8975
9069
|
options.ensureCurrent();
|
|
8976
9070
|
let completePublish;
|
|
@@ -8978,13 +9072,12 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
8978
9072
|
options.ensureCurrent();
|
|
8979
9073
|
}, async () => {
|
|
8980
9074
|
options.ensureCurrent();
|
|
8981
|
-
await _optionalChain([options, 'access',
|
|
8982
|
-
|
|
9075
|
+
await _optionalChain([options, 'access', _622 => _622.beforePublish, 'optionalCall', _623 => _623()]);
|
|
9076
|
+
options.ensureCurrent();
|
|
8983
9077
|
completePublish = this.dependencies.timing.startPublish();
|
|
8984
|
-
}, publishLocalMedia);
|
|
9078
|
+
}, publishLocalMedia, () => this.dependencies.timing.startRtcJoin());
|
|
8985
9079
|
options.ensureCurrent();
|
|
8986
|
-
|
|
8987
|
-
_optionalChain([completePublish, 'optionalCall', _616 => _616()]);
|
|
9080
|
+
_optionalChain([completePublish, 'optionalCall', _624 => _624()]);
|
|
8988
9081
|
options.onPublished();
|
|
8989
9082
|
sessionService.startHeartbeat(session.id, {
|
|
8990
9083
|
onFailure: (sessionID, error) => {
|
|
@@ -9014,11 +9107,11 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
9014
9107
|
*/
|
|
9015
9108
|
stopHeartbeat() {
|
|
9016
9109
|
this.refreshVersion++;
|
|
9017
|
-
_optionalChain([this, 'access',
|
|
9110
|
+
_optionalChain([this, 'access', _625 => _625.credentialController, 'optionalAccess', _626 => _626.abort, 'call', _627 => _627()]);
|
|
9018
9111
|
this.credentialController = void 0;
|
|
9019
9112
|
this.credentialRefresh = void 0;
|
|
9020
9113
|
this.credentialApplication = Promise.resolve();
|
|
9021
|
-
_optionalChain([this, 'access',
|
|
9114
|
+
_optionalChain([this, 'access', _628 => _628.dependencies, 'access', _629 => _629.sessionService, 'optionalAccess', _630 => _630.stopHeartbeat, 'call', _631 => _631()]);
|
|
9022
9115
|
}
|
|
9023
9116
|
/**
|
|
9024
9117
|
* RTC Token 过期时复用会话心跳获取新凭据,并合并同一实例的并发请求。
|
|
@@ -9026,14 +9119,14 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
9026
9119
|
async refreshCredentials() {
|
|
9027
9120
|
if (this.credentialRefresh) return this.credentialRefresh;
|
|
9028
9121
|
const current = this.activeSession;
|
|
9029
|
-
if (!_optionalChain([current, 'optionalAccess',
|
|
9122
|
+
if (!_optionalChain([current, 'optionalAccess', _632 => _632.connection]) || current.connection.provider === "trtc" /* trtc */) return;
|
|
9030
9123
|
const version = this.refreshVersion;
|
|
9031
9124
|
const operation = (async () => {
|
|
9032
9125
|
try {
|
|
9033
9126
|
const session = await this.requireSessionService().heartbeatSession(current.id);
|
|
9034
9127
|
await this.handleSessionRefresh(session, version, true);
|
|
9035
9128
|
} catch (error) {
|
|
9036
|
-
if (version === this.refreshVersion && _optionalChain([this, 'access',
|
|
9129
|
+
if (version === this.refreshVersion && _optionalChain([this, 'access', _633 => _633.activeSession, 'optionalAccess', _634 => _634.id]) === current.id) {
|
|
9037
9130
|
this.dependencies.onHeartbeatFailure(current.id, XmaxError.from(error));
|
|
9038
9131
|
}
|
|
9039
9132
|
}
|
|
@@ -9050,7 +9143,7 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
9050
9143
|
*/
|
|
9051
9144
|
async waitUntilRemoteTrackReady(timeoutMs, signal) {
|
|
9052
9145
|
if (signal.aborted) throw RealtimeCoordinator.cancelledError();
|
|
9053
|
-
const mediaTrack = _optionalChain([this, 'access',
|
|
9146
|
+
const mediaTrack = _optionalChain([this, 'access', _635 => _635.activeRemoteTrack, 'optionalAccess', _636 => _636.mediaStreamTrack]);
|
|
9054
9147
|
if (!mediaTrack || !mediaTrack.muted) return;
|
|
9055
9148
|
await new Promise((resolve, reject) => {
|
|
9056
9149
|
const cleanup = () => {
|
|
@@ -9144,7 +9237,7 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
9144
9237
|
return;
|
|
9145
9238
|
}
|
|
9146
9239
|
if (next.provider !== "trtc" /* trtc */ && (force || !previous || previous.provider === "trtc" /* trtc */ || next.roomToken !== previous.roomToken)) {
|
|
9147
|
-
await this.dependencies.streamController.updateCredentials(next, _optionalChain([this, 'access',
|
|
9240
|
+
await this.dependencies.streamController.updateCredentials(next, _optionalChain([this, 'access', _637 => _637.credentialController, 'optionalAccess', _638 => _638.signal]));
|
|
9148
9241
|
if (version !== this.refreshVersion || this.activeSession !== current) return;
|
|
9149
9242
|
}
|
|
9150
9243
|
this.activeSession = new RealtimeSession({
|
|
@@ -9159,7 +9252,7 @@ var XmaxRealtimeConnectionManager = class {
|
|
|
9159
9252
|
* 尽力清理全部连接资源,即使退房失败也关闭服务端会话。
|
|
9160
9253
|
*/
|
|
9161
9254
|
async disconnect() {
|
|
9162
|
-
const sessionID = _optionalChain([this, 'access',
|
|
9255
|
+
const sessionID = _optionalChain([this, 'access', _639 => _639.activeSession, 'optionalAccess', _640 => _640.id]);
|
|
9163
9256
|
this.stopHeartbeat();
|
|
9164
9257
|
this.clearRemoteMedia();
|
|
9165
9258
|
try {
|
|
@@ -9271,7 +9364,7 @@ var XmaxRealtimeGenerationManager = class _XmaxRealtimeGenerationManager {
|
|
|
9271
9364
|
this.currentContext = context;
|
|
9272
9365
|
await options.waitUntilRemoteReady();
|
|
9273
9366
|
options.ensureCurrent();
|
|
9274
|
-
_optionalChain([options, 'access',
|
|
9367
|
+
_optionalChain([options, 'access', _641 => _641.onRemoteReady, 'optionalCall', _642 => _642(taskID)]);
|
|
9275
9368
|
options.ensureCurrent();
|
|
9276
9369
|
await this.streamController.activateRemoteAudio();
|
|
9277
9370
|
options.ensureCurrent();
|
|
@@ -9333,7 +9426,7 @@ var XmaxRealtimeGenerationManager = class _XmaxRealtimeGenerationManager {
|
|
|
9333
9426
|
try {
|
|
9334
9427
|
await completion;
|
|
9335
9428
|
} finally {
|
|
9336
|
-
if (_optionalChain([this, 'access',
|
|
9429
|
+
if (_optionalChain([this, 'access', _643 => _643.pendingStop, 'optionalAccess', _644 => _644.completion]) === completion) this.pendingStop = void 0;
|
|
9337
9430
|
}
|
|
9338
9431
|
}
|
|
9339
9432
|
/**
|
|
@@ -9426,6 +9519,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9426
9519
|
*/
|
|
9427
9520
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "launchTimer", new RealtimeLaunchTimer());
|
|
9428
9521
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "remoteFrameDisplayHandler");
|
|
9522
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "remoteRenderWarmupCompletedHandler");
|
|
9429
9523
|
/**
|
|
9430
9524
|
* 媒体权限弹窗观察
|
|
9431
9525
|
*/
|
|
@@ -9462,11 +9556,11 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9462
9556
|
this.options = options;
|
|
9463
9557
|
this.mediaService = new MediaService(options.model);
|
|
9464
9558
|
this.interpolationRequested = options.isFrameInterpolationEnabled;
|
|
9465
|
-
this.supportsInterpolation = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess',
|
|
9559
|
+
this.supportsInterpolation = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess', _645 => _645.supportsFrameInterpolation]), () => ( (async (size) => await frameInterpolationAdapter(size) !== null)));
|
|
9466
9560
|
this.errorHandler = new RealtimeErrorHandler();
|
|
9467
|
-
const rtcManager = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess',
|
|
9468
|
-
const sessionService = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess',
|
|
9469
|
-
this.streamController = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess',
|
|
9561
|
+
const rtcManager = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess', _646 => _646.rtcManager]), () => ( createRtcManager(options.provider, _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess', _647 => _647.environment]), () => ( "china")) /* china */)));
|
|
9562
|
+
const sessionService = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess', _648 => _648.sessionService]), () => ( (_optionalChain([dependencies, 'optionalAccess', _649 => _649.apiService]) ? new RealtimeSessionService({ apiService: dependencies.apiService, provider: options.provider }) : void 0)));
|
|
9563
|
+
this.streamController = _nullishCoalesce(_optionalChain([dependencies, 'optionalAccess', _650 => _650.streamController]), () => ( new StreamController({
|
|
9470
9564
|
rtcManager,
|
|
9471
9565
|
onCredentialsRequired: () => {
|
|
9472
9566
|
void this.connectionManager.refreshCredentials();
|
|
@@ -9485,7 +9579,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9485
9579
|
this.mediaController = new MediaController({
|
|
9486
9580
|
rtcManager,
|
|
9487
9581
|
mediaService: this.mediaService,
|
|
9488
|
-
cameraController: _optionalChain([dependencies, 'optionalAccess',
|
|
9582
|
+
cameraController: _optionalChain([dependencies, 'optionalAccess', _651 => _651.cameraController]),
|
|
9489
9583
|
onCameraError: (error) => {
|
|
9490
9584
|
void this.errorHandler.report(error);
|
|
9491
9585
|
},
|
|
@@ -9501,7 +9595,11 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9501
9595
|
interactionListener: (taskID, points) => this.streamController.sendTracks(taskID, points)
|
|
9502
9596
|
});
|
|
9503
9597
|
this.renderController = new RenderController({
|
|
9504
|
-
onFrameDisplayed: () => _optionalChain([this, 'access',
|
|
9598
|
+
onFrameDisplayed: () => _optionalChain([this, 'access', _652 => _652.remoteFrameDisplayHandler, 'optionalCall', _653 => _653()]),
|
|
9599
|
+
onRenderWarmupCompleted: () => {
|
|
9600
|
+
_optionalChain([this, 'access', _654 => _654.remoteRenderWarmupCompletedHandler, 'optionalCall', _655 => _655()]);
|
|
9601
|
+
void this.completeGenerationPresentation().catch((error) => this.errorHandler.report(error));
|
|
9602
|
+
},
|
|
9505
9603
|
onAttached: () => this.applyRemoteInterpolation(),
|
|
9506
9604
|
onDetached: () => {
|
|
9507
9605
|
this.interpolationRevision++;
|
|
@@ -9530,6 +9628,10 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9530
9628
|
await this.coordinator.run("configuration" /* configuration */, void 0, async (token) => {
|
|
9531
9629
|
await this.applyUplinkQuality(change.to, token, signal);
|
|
9532
9630
|
});
|
|
9631
|
+
}, void 0, {}, (level) => {
|
|
9632
|
+
const track = this.currentUplinkTrack;
|
|
9633
|
+
const state2 = track && this.qualityStates.get(track);
|
|
9634
|
+
return !!state2 && supportsQualityEncoding(this.uplinkQualityFormat(state2.baseline, level));
|
|
9533
9635
|
});
|
|
9534
9636
|
this.downlinkQualityController = new QualityController(async (change, signal) => {
|
|
9535
9637
|
await this.coordinator.run("configuration" /* configuration */, void 0, async (token) => {
|
|
@@ -9574,7 +9676,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9574
9676
|
*/
|
|
9575
9677
|
async setFrameInterpolationEnabled(enabled) {
|
|
9576
9678
|
await this.coordinator.run("configuration" /* configuration */, void 0, async (token) => {
|
|
9577
|
-
const format = _nullishCoalesce(_nullishCoalesce(_optionalChain([this, 'access',
|
|
9679
|
+
const format = _nullishCoalesce(_nullishCoalesce(_optionalChain([this, 'access', _656 => _656.downlinkQualityState, 'optionalAccess', _657 => _657.size]), () => ( this.generationVideoFormat)), () => ( _optionalChain([this, 'access', _658 => _658.currentLocalTrack, 'optionalAccess', _659 => _659.videoFormat])));
|
|
9578
9680
|
const size = format && enabled ? this.mediaService.resolveFrameInterpolationSize(format) : void 0;
|
|
9579
9681
|
if (enabled && !await this.checkInterpolationSupport(size, token)) {
|
|
9580
9682
|
token.ensureCurrent();
|
|
@@ -9600,6 +9702,9 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9600
9702
|
}
|
|
9601
9703
|
const level = Math.max(1, Math.min(Object.keys(QUALITY_TIERS).length, state2.level + (direction === "upgrade" ? -1 : 1)));
|
|
9602
9704
|
if (level === state2.level) return;
|
|
9705
|
+
if (!supportsQualityEncoding(this.uplinkQualityFormat(state2.baseline, level))) {
|
|
9706
|
+
throw new XmaxError("INVALID_CONFIGURATION" /* invalidConfiguration */, "Quality level conflicts with explicit bitrate constraints");
|
|
9707
|
+
}
|
|
9603
9708
|
this.adaptiveQualityRevision++;
|
|
9604
9709
|
controller.resetSamples();
|
|
9605
9710
|
await this.applyUplinkQuality(level, token);
|
|
@@ -9611,7 +9716,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9611
9716
|
const state2 = track && this.qualityStates.get(track);
|
|
9612
9717
|
const ensureActive2 = () => {
|
|
9613
9718
|
token.ensureCurrent();
|
|
9614
|
-
if (_optionalChain([signal, 'optionalAccess',
|
|
9719
|
+
if (_optionalChain([signal, 'optionalAccess', _660 => _660.aborted]) || !track || !state2 || track !== this.currentUplinkTrack || state2 !== this.qualityStates.get(track) || this.currentState.connectionState !== "Generating" /* generating */) {
|
|
9615
9720
|
throw new XmaxError("CANCELLED" /* cancelled */, "Adaptive video format update was cancelled");
|
|
9616
9721
|
}
|
|
9617
9722
|
};
|
|
@@ -9629,7 +9734,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9629
9734
|
_nullishCoalesce(this.generationVideoFormat, () => ( (this.generationVideoFormat = state2.baseline)));
|
|
9630
9735
|
track.updateVideoFormat(format);
|
|
9631
9736
|
state2.level = level;
|
|
9632
|
-
_optionalChain([this, 'access',
|
|
9737
|
+
_optionalChain([this, 'access', _661 => _661.qualityHistory, 'optionalAccess', _662 => _662.write, 'call', _663 => _663("uplink", level)]);
|
|
9633
9738
|
}
|
|
9634
9739
|
/** 手动调试与自动调档使用同一尺寸信令路径,不修改生成或上行配置。 */
|
|
9635
9740
|
async adjustDownlinkQuality(direction) {
|
|
@@ -9651,7 +9756,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9651
9756
|
const state2 = this.downlinkQualityState;
|
|
9652
9757
|
const ensureActive2 = () => {
|
|
9653
9758
|
token.ensureCurrent();
|
|
9654
|
-
if (_optionalChain([signal, 'optionalAccess',
|
|
9759
|
+
if (_optionalChain([signal, 'optionalAccess', _664 => _664.aborted]) || !state2 || state2 !== this.downlinkQualityState || this.currentState.connectionState !== "Generating" /* generating */ || this.currentState.taskID !== state2.taskID) {
|
|
9655
9760
|
throw new XmaxError("CANCELLED" /* cancelled */, "Target size update was cancelled");
|
|
9656
9761
|
}
|
|
9657
9762
|
};
|
|
@@ -9662,7 +9767,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9662
9767
|
ensureActive2();
|
|
9663
9768
|
state2.level = level;
|
|
9664
9769
|
state2.size = size;
|
|
9665
|
-
_optionalChain([this, 'access',
|
|
9770
|
+
_optionalChain([this, 'access', _665 => _665.qualityHistory, 'optionalAccess', _666 => _666.write, 'call', _667 => _667("downlink", level)]);
|
|
9666
9771
|
if (this.interpolationRequested) {
|
|
9667
9772
|
this.interpolationSize = size;
|
|
9668
9773
|
this.applyRemoteInterpolation();
|
|
@@ -9781,7 +9886,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9781
9886
|
*/
|
|
9782
9887
|
notifyRemoteVideoStatistics() {
|
|
9783
9888
|
try {
|
|
9784
|
-
void Promise.resolve(_optionalChain([this, 'access',
|
|
9889
|
+
void Promise.resolve(_optionalChain([this, 'access', _668 => _668.remoteVideoStatisticsListener, 'optionalCall', _669 => _669(this.remoteVideoStatistics)])).catch(() => {
|
|
9785
9890
|
});
|
|
9786
9891
|
} catch (e31) {
|
|
9787
9892
|
}
|
|
@@ -9798,7 +9903,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9798
9903
|
*/
|
|
9799
9904
|
notifyNetworkStatistics() {
|
|
9800
9905
|
try {
|
|
9801
|
-
void Promise.resolve(_optionalChain([this, 'access',
|
|
9906
|
+
void Promise.resolve(_optionalChain([this, 'access', _670 => _670.networkStatisticsListener, 'optionalCall', _671 => _671(this.networkStatistics)])).catch(() => {
|
|
9802
9907
|
});
|
|
9803
9908
|
} catch (e32) {
|
|
9804
9909
|
}
|
|
@@ -9818,7 +9923,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9818
9923
|
*/
|
|
9819
9924
|
notifyLocalVideoStatistics() {
|
|
9820
9925
|
try {
|
|
9821
|
-
void Promise.resolve(_optionalChain([this, 'access',
|
|
9926
|
+
void Promise.resolve(_optionalChain([this, 'access', _672 => _672.localVideoStatisticsListener, 'optionalCall', _673 => _673(this.localVideoStatistics)])).catch(() => {
|
|
9822
9927
|
});
|
|
9823
9928
|
} catch (e33) {
|
|
9824
9929
|
}
|
|
@@ -9827,8 +9932,8 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9827
9932
|
* 停止接收媒体统计并清空各类快照,仅对曾有数据的统计发出清空通知。
|
|
9828
9933
|
*/
|
|
9829
9934
|
clearVideoStatistics() {
|
|
9830
|
-
_optionalChain([this, 'access',
|
|
9831
|
-
_optionalChain([this, 'access',
|
|
9935
|
+
_optionalChain([this, 'access', _674 => _674.qualityController, 'optionalAccess', _675 => _675.stop, 'call', _676 => _676()]);
|
|
9936
|
+
_optionalChain([this, 'access', _677 => _677.downlinkQualityController, 'optionalAccess', _678 => _678.stop, 'call', _679 => _679()]);
|
|
9832
9937
|
this.downlinkQualityState = void 0;
|
|
9833
9938
|
this.adaptiveQualityRevision++;
|
|
9834
9939
|
this.acceptsVideoStatistics = false;
|
|
@@ -9900,7 +10005,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9900
10005
|
const completeCamera = this.launchTimer.startCamera();
|
|
9901
10006
|
this.clearVideoStatistics();
|
|
9902
10007
|
this.disposePermissionWatch();
|
|
9903
|
-
const permissionWatch = await watchMediaPermissionPrompt(_nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
10008
|
+
const permissionWatch = await watchMediaPermissionPrompt(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _680 => _680.useMicrophone]), () => ( false)));
|
|
9904
10009
|
if (permissionWatch) {
|
|
9905
10010
|
const completePermission = this.launchTimer.startPermission();
|
|
9906
10011
|
void permissionWatch.decided.then(() => completePermission()).catch(() => {
|
|
@@ -9917,7 +10022,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9917
10022
|
throw error;
|
|
9918
10023
|
}
|
|
9919
10024
|
token.ensureCurrent();
|
|
9920
|
-
this.generationVideoFormat = _optionalChain([stream, 'access',
|
|
10025
|
+
this.generationVideoFormat = _optionalChain([stream, 'access', _681 => _681.videoTrack, 'optionalAccess', _682 => _682.videoFormat]);
|
|
9921
10026
|
completeCamera();
|
|
9922
10027
|
this.mediaController.setCameraPreviewReadyHandler((isCurrent) => {
|
|
9923
10028
|
void this.coordinator.localPreviewDidBecomeReady(isCurrent);
|
|
@@ -9942,7 +10047,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9942
10047
|
this.clearVideoStatistics();
|
|
9943
10048
|
await this.mediaController.prepareSource(() => token.ensureCurrent());
|
|
9944
10049
|
token.ensureCurrent();
|
|
9945
|
-
this.generationVideoFormat = _optionalChain([stream, 'access',
|
|
10050
|
+
this.generationVideoFormat = _optionalChain([stream, 'access', _683 => _683.videoTrack, 'optionalAccess', _684 => _684.videoFormat]);
|
|
9946
10051
|
await this.coordinator.commit(new RealtimeState({ connectionState: "Ready" /* ready */ }), token);
|
|
9947
10052
|
return stream;
|
|
9948
10053
|
});
|
|
@@ -9964,7 +10069,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9964
10069
|
const stream = await this.mediaController.createLocalVideoStream(options, token.signal);
|
|
9965
10070
|
token.ensureCurrent();
|
|
9966
10071
|
await this.mediaController.prepareSource(() => token.ensureCurrent());
|
|
9967
|
-
this.generationVideoFormat = _optionalChain([stream, 'access',
|
|
10072
|
+
this.generationVideoFormat = _optionalChain([stream, 'access', _685 => _685.videoTrack, 'optionalAccess', _686 => _686.videoFormat]);
|
|
9968
10073
|
await this.coordinator.commit(new RealtimeState({ connectionState: "Ready" /* ready */ }), token);
|
|
9969
10074
|
return stream;
|
|
9970
10075
|
});
|
|
@@ -9982,7 +10087,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
9982
10087
|
const stream = await this.mediaController.createLocalImageStream(options, token.signal);
|
|
9983
10088
|
token.ensureCurrent();
|
|
9984
10089
|
await this.mediaController.prepareSource(() => token.ensureCurrent());
|
|
9985
|
-
this.generationVideoFormat = _optionalChain([stream, 'access',
|
|
10090
|
+
this.generationVideoFormat = _optionalChain([stream, 'access', _687 => _687.videoTrack, 'optionalAccess', _688 => _688.videoFormat]);
|
|
9986
10091
|
await this.coordinator.commit(new RealtimeState({ connectionState: "Ready" /* ready */ }), token);
|
|
9987
10092
|
return stream;
|
|
9988
10093
|
});
|
|
@@ -10001,7 +10106,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10001
10106
|
this.launchTimer.start();
|
|
10002
10107
|
this.clearVideoStatistics();
|
|
10003
10108
|
await this.mediaController.prepareSource(() => token.ensureCurrent());
|
|
10004
|
-
this.generationVideoFormat = _optionalChain([stream, 'access',
|
|
10109
|
+
this.generationVideoFormat = _optionalChain([stream, 'access', _689 => _689.videoTrack, 'optionalAccess', _690 => _690.videoFormat]);
|
|
10005
10110
|
await this.coordinator.commit(new RealtimeState({ connectionState: "Ready" /* ready */ }), token);
|
|
10006
10111
|
return stream;
|
|
10007
10112
|
});
|
|
@@ -10018,7 +10123,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10018
10123
|
* 移除媒体权限弹窗观察;授权决定已记录或不再需要观察时调用。
|
|
10019
10124
|
*/
|
|
10020
10125
|
disposePermissionWatch() {
|
|
10021
|
-
_optionalChain([this, 'access',
|
|
10126
|
+
_optionalChain([this, 'access', _691 => _691.permissionWatchDispose, 'optionalCall', _692 => _692()]);
|
|
10022
10127
|
this.permissionWatchDispose = void 0;
|
|
10023
10128
|
}
|
|
10024
10129
|
/**
|
|
@@ -10030,38 +10135,38 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10030
10135
|
async updateUplinkVideoFormat(videoFormat) {
|
|
10031
10136
|
await this.coordinator.run("configuration" /* configuration */, void 0, async (token) => {
|
|
10032
10137
|
const track = this.currentUplinkTrack;
|
|
10033
|
-
const previousFormat = _optionalChain([track, 'optionalAccess',
|
|
10138
|
+
const previousFormat = _optionalChain([track, 'optionalAccess', _693 => _693.videoFormat]);
|
|
10034
10139
|
if (!track || !previousFormat) {
|
|
10035
10140
|
throw new XmaxError("INVALID_CONFIGURATION" /* invalidConfiguration */, "Local camera, external or file video stream is not started");
|
|
10036
10141
|
}
|
|
10037
10142
|
videoFormat.validate();
|
|
10038
|
-
_optionalChain([this, 'access',
|
|
10143
|
+
_optionalChain([this, 'access', _694 => _694.qualityController, 'optionalAccess', _695 => _695.stop, 'call', _696 => _696()]);
|
|
10039
10144
|
await this.streamController.updateUplinkVideoFormat(videoFormat);
|
|
10040
10145
|
token.ensureCurrent();
|
|
10041
10146
|
_nullishCoalesce(this.generationVideoFormat, () => ( (this.generationVideoFormat = previousFormat)));
|
|
10042
10147
|
track.updateVideoFormat(videoFormat);
|
|
10043
10148
|
this.qualityStates.set(track, { baseline: videoFormat, level: 1 });
|
|
10044
|
-
_optionalChain([this, 'access',
|
|
10149
|
+
_optionalChain([this, 'access', _697 => _697.qualityHistory, 'optionalAccess', _698 => _698.write, 'call', _699 => _699("uplink", 1)]);
|
|
10045
10150
|
});
|
|
10046
10151
|
}
|
|
10047
10152
|
/** 已连接时仅替换帧率;与其他配置及生命周期操作共享同一操作租约。 */
|
|
10048
10153
|
async updateUplinkFrameRate(fps) {
|
|
10049
10154
|
await this.coordinator.run("configuration" /* configuration */, void 0, async (token) => {
|
|
10050
|
-
_optionalChain([this, 'access',
|
|
10155
|
+
_optionalChain([this, 'access', _700 => _700.qualityController, 'optionalAccess', _701 => _701.stop, 'call', _702 => _702()]);
|
|
10051
10156
|
await this.applyUplinkFrameRate(fps, token);
|
|
10052
10157
|
const track = this.currentLocalTrack;
|
|
10053
|
-
if (_optionalChain([track, 'optionalAccess',
|
|
10158
|
+
if (_optionalChain([track, 'optionalAccess', _703 => _703.videoFormat])) {
|
|
10054
10159
|
this.qualityStates.set(track, { baseline: track.videoFormat, level: 1 });
|
|
10055
|
-
_optionalChain([this, 'access',
|
|
10160
|
+
_optionalChain([this, 'access', _704 => _704.qualityHistory, 'optionalAccess', _705 => _705.write, 'call', _706 => _706("uplink", 1)]);
|
|
10056
10161
|
}
|
|
10057
10162
|
});
|
|
10058
10163
|
}
|
|
10059
10164
|
/** 手动仅调帧接口,成功后的当前格式将成为新的自适应 L1 基准。 */
|
|
10060
10165
|
async applyUplinkFrameRate(fps, token) {
|
|
10061
10166
|
const track = this.currentUplinkTrack;
|
|
10062
|
-
const previous = _optionalChain([track, 'optionalAccess',
|
|
10167
|
+
const previous = _optionalChain([track, 'optionalAccess', _707 => _707.videoFormat]);
|
|
10063
10168
|
const state2 = this.currentState.connectionState;
|
|
10064
|
-
if (!track || !previous || state2 !== "Connected" /* connected */ && state2 !== "Generating" /* generating */) {
|
|
10169
|
+
if (!track || !previous || state2 !== "Connected" /* connected */ && state2 !== "Starting" /* starting */ && state2 !== "Generating" /* generating */) {
|
|
10065
10170
|
throw new XmaxError("INVALID_CONFIGURATION" /* invalidConfiguration */, "Frame rate updates require a connected local camera, external or file stream");
|
|
10066
10171
|
}
|
|
10067
10172
|
if (!Number.isFinite(fps) || fps <= 0) {
|
|
@@ -10157,7 +10262,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10157
10262
|
if (this.mediaController.source === "externalVideo") {
|
|
10158
10263
|
throw new XmaxError("INVALID_CONFIGURATION" /* invalidConfiguration */, "External video capture is managed by the caller");
|
|
10159
10264
|
}
|
|
10160
|
-
_optionalChain([this, 'access',
|
|
10265
|
+
_optionalChain([this, 'access', _708 => _708.qualityController, 'optionalAccess', _709 => _709.stop, 'call', _710 => _710()]);
|
|
10161
10266
|
const stream = await this.mediaController.switchCamera();
|
|
10162
10267
|
token.ensureCurrent();
|
|
10163
10268
|
return stream;
|
|
@@ -10182,7 +10287,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10182
10287
|
void 0,
|
|
10183
10288
|
async (token) => {
|
|
10184
10289
|
const connectionState = this.coordinator.currentState.connectionState;
|
|
10185
|
-
if (connectionState === "Connecting" /* connecting */ || connectionState === "Connected" /* connected */ || connectionState === "Generating" /* generating */) {
|
|
10290
|
+
if (connectionState === "Connecting" /* connecting */ || connectionState === "Connected" /* connected */ || connectionState === "Starting" /* starting */ || connectionState === "Generating" /* generating */) {
|
|
10186
10291
|
throw new XmaxError(
|
|
10187
10292
|
"INVALID_CONFIGURATION" /* invalidConfiguration */,
|
|
10188
10293
|
"A realtime connection is already active"
|
|
@@ -10197,6 +10302,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10197
10302
|
*
|
|
10198
10303
|
* 尚未连接时先建立实时连接;已在生成时默认更新条件,restart 为 true 时重新开始生成。
|
|
10199
10304
|
* 首次生成必须提供条件上下文,之后缺省时复用最近一次缓存的上下文。
|
|
10305
|
+
* 返回后请将远端流挂载到 SDK 视频视图;首帧及渲染预热完成后状态才进入 generating。
|
|
10200
10306
|
*
|
|
10201
10307
|
* @param options.localStream 由当前 Manager 创建的摄像头、外部视频轨、本地文件或网络视频源。
|
|
10202
10308
|
* @param options.context 本次生成使用的条件上下文;缺省时复用缓存。
|
|
@@ -10204,7 +10310,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10204
10310
|
* @param options.faceRestoration 是否启用原始人脸回贴,默认 false;正在生成时通过 change_condition 更新。
|
|
10205
10311
|
* @param options.extraParams 合并到本次 start 或 change_condition 的 params;不缓存,自动恢复时不携带,不允许覆盖 SDK 字段。
|
|
10206
10312
|
* @param options.record 是否录制远端原始音视频约 20 秒,默认 false;仅 start 有效,条件更新时忽略,重启录制暂不支持。
|
|
10207
|
-
* @returns
|
|
10313
|
+
* @returns 可挂载的远端媒体流,不等待渲染预热;展示就绪以 generating 状态为准。
|
|
10208
10314
|
* @throws extraParams 包含非 JSON 数据、循环引用或 SDK 保留字段时,在连接或更新前抛出 invalidConfiguration。
|
|
10209
10315
|
* @throws 本地流不属于当前 Manager、缺少可用的条件上下文、信令发送
|
|
10210
10316
|
* 或生成确认失败时抛出错误;失败时自动停止生成任务并释放连接资源。
|
|
@@ -10230,12 +10336,12 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10230
10336
|
);
|
|
10231
10337
|
}
|
|
10232
10338
|
const currentState = this.coordinator.currentState;
|
|
10233
|
-
const
|
|
10234
|
-
if (
|
|
10339
|
+
const hasGeneration = currentState.connectionState === "Generating" /* generating */ || currentState.connectionState === "Starting" /* starting */ && !!currentState.taskID;
|
|
10340
|
+
if (hasGeneration && options.restart !== true) {
|
|
10235
10341
|
await this.generationManager.update(currentState.taskID, {
|
|
10236
10342
|
videoFormat,
|
|
10237
10343
|
context: options.context,
|
|
10238
|
-
targetSize: this.downlinkQualityController ? _optionalChain([this, 'access',
|
|
10344
|
+
targetSize: this.downlinkQualityController ? _optionalChain([this, 'access', _711 => _711.downlinkQualityState, 'optionalAccess', _712 => _712.size]) : void 0,
|
|
10239
10345
|
faceRestoration: _nullishCoalesce(options.faceRestoration, () => ( false)),
|
|
10240
10346
|
extraParams
|
|
10241
10347
|
});
|
|
@@ -10248,7 +10354,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10248
10354
|
throw new XmaxError("INVALID_CONFIGURATION" /* invalidConfiguration */, "Create a network video stream before using a reference video");
|
|
10249
10355
|
}
|
|
10250
10356
|
const context = referenceVideo ? new RealtimeContext({ ...supplied, referenceVideo }) : supplied;
|
|
10251
|
-
if (currentState.connectionState !== "Connected" /* connected */ && !
|
|
10357
|
+
if (currentState.connectionState !== "Connected" /* connected */ && !hasGeneration) {
|
|
10252
10358
|
await this.performConnect(options.localStream, token);
|
|
10253
10359
|
}
|
|
10254
10360
|
return this.performStartGeneration(
|
|
@@ -10300,7 +10406,11 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10300
10406
|
if (this.qualityStates.has(track)) return void 0;
|
|
10301
10407
|
const baseline = track.videoFormat;
|
|
10302
10408
|
if (!baseline) return void 0;
|
|
10303
|
-
|
|
10409
|
+
let level = this.qualityHistory.read("uplink");
|
|
10410
|
+
while (level > 1 && !supportsQualityEncoding(this.uplinkQualityFormat(baseline, level))) {
|
|
10411
|
+
level--;
|
|
10412
|
+
}
|
|
10413
|
+
return { baseline, level };
|
|
10304
10414
|
}
|
|
10305
10415
|
/**
|
|
10306
10416
|
* 建立实时连接:创建会话、进房发布、启动心跳并准备远端渲染轨道。
|
|
@@ -10348,7 +10458,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10348
10458
|
_nullishCoalesce(this.generationVideoFormat, () => ( (this.generationVideoFormat = initialQuality.baseline)));
|
|
10349
10459
|
localTrack.updateVideoFormat(initialFormat);
|
|
10350
10460
|
this.qualityStates.set(localTrack, initialQuality);
|
|
10351
|
-
_optionalChain([this, 'access',
|
|
10461
|
+
_optionalChain([this, 'access', _713 => _713.qualityHistory, 'optionalAccess', _714 => _714.write, 'call', _715 => _715("uplink", initialQuality.level)]);
|
|
10352
10462
|
},
|
|
10353
10463
|
model: this.options.model,
|
|
10354
10464
|
includeLocalAudio: this.mediaController.hasAudio,
|
|
@@ -10386,16 +10496,30 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10386
10496
|
*/
|
|
10387
10497
|
async performStartGeneration(token, videoFormat, context, restart, faceRestoration, extraParams, record2 = false) {
|
|
10388
10498
|
token.setFailureScope(0 /* connection */);
|
|
10499
|
+
const sessionID = this.connectionManager.currentSessionID;
|
|
10500
|
+
if (!sessionID) {
|
|
10501
|
+
throw new XmaxError("SESSION_ERROR" /* sessionError */, "Realtime session is unavailable");
|
|
10502
|
+
}
|
|
10503
|
+
await this.coordinator.commit(
|
|
10504
|
+
new RealtimeState({ connectionState: "Starting" /* starting */, sessionID }),
|
|
10505
|
+
token
|
|
10506
|
+
);
|
|
10507
|
+
token.ensureCurrent();
|
|
10389
10508
|
if (restart) {
|
|
10390
10509
|
void this.recordingController.stop("restarted" /* restarted */);
|
|
10391
10510
|
}
|
|
10392
|
-
const initialLevel = _nullishCoalesce(_optionalChain([this, 'access',
|
|
10511
|
+
const initialLevel = _nullishCoalesce(_optionalChain([this, 'access', _716 => _716.qualityHistory, 'optionalAccess', _717 => _717.read, 'call', _718 => _718("downlink")]), () => ( 1));
|
|
10393
10512
|
const targetSize = this.downlinkQualityController ? qualityVideoSize(videoFormat, initialLevel) : void 0;
|
|
10394
10513
|
await this.prepareFrameInterpolation(_nullishCoalesce(targetSize, () => ( videoFormat)), token);
|
|
10395
10514
|
const completeFirstFrame = this.launchTimer.startFirstFrame();
|
|
10515
|
+
this.remoteRenderWarmupCompletedHandler = void 0;
|
|
10396
10516
|
this.remoteFrameDisplayHandler = () => {
|
|
10397
|
-
if (!token.signal.aborted)
|
|
10517
|
+
if (!token.signal.aborted) {
|
|
10518
|
+
completeFirstFrame();
|
|
10519
|
+
_nullishCoalesce(this.remoteRenderWarmupCompletedHandler, () => ( (this.remoteRenderWarmupCompletedHandler = this.launchTimer.startRenderWarmup())));
|
|
10520
|
+
}
|
|
10398
10521
|
};
|
|
10522
|
+
this.renderController.prepareForGeneration();
|
|
10399
10523
|
const taskID = await this.generationManager.start({
|
|
10400
10524
|
videoFormat,
|
|
10401
10525
|
signal: token.signal,
|
|
@@ -10417,7 +10541,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10417
10541
|
}
|
|
10418
10542
|
} : void 0,
|
|
10419
10543
|
targetSize,
|
|
10420
|
-
mirror: this.mediaController.source === "camera" && _optionalChain([this, 'access',
|
|
10544
|
+
mirror: this.mediaController.source === "camera" && _optionalChain([this, 'access', _719 => _719.currentLocalTrack, 'optionalAccess', _720 => _720.position]) === "front" /* front */,
|
|
10421
10545
|
faceRestoration,
|
|
10422
10546
|
onStartSent: this.mediaController.source === "localVideo" ? async () => {
|
|
10423
10547
|
token.ensureCurrent();
|
|
@@ -10426,11 +10550,8 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10426
10550
|
} : void 0,
|
|
10427
10551
|
extraParams
|
|
10428
10552
|
});
|
|
10429
|
-
|
|
10430
|
-
|
|
10431
|
-
throw new XmaxError("SESSION_ERROR" /* sessionError */, "Realtime session is unavailable");
|
|
10432
|
-
}
|
|
10433
|
-
_optionalChain([this, 'access', _711 => _711.downlinkQualityController, 'optionalAccess', _712 => _712.stop, 'call', _713 => _713()]);
|
|
10553
|
+
token.ensureCurrent();
|
|
10554
|
+
_optionalChain([this, 'access', _721 => _721.downlinkQualityController, 'optionalAccess', _722 => _722.stop, 'call', _723 => _723()]);
|
|
10434
10555
|
this.downlinkQualityState = {
|
|
10435
10556
|
taskID,
|
|
10436
10557
|
baseline: videoFormat,
|
|
@@ -10438,21 +10559,38 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10438
10559
|
size: _nullishCoalesce(targetSize, () => ( { width: videoFormat.width, height: videoFormat.height }))
|
|
10439
10560
|
};
|
|
10440
10561
|
await this.coordinator.commit(
|
|
10441
|
-
new RealtimeState({ connectionState: "
|
|
10562
|
+
new RealtimeState({ connectionState: "Starting" /* starting */, sessionID, taskID }),
|
|
10442
10563
|
token
|
|
10443
10564
|
);
|
|
10444
|
-
|
|
10565
|
+
token.ensureCurrent();
|
|
10566
|
+
await this.completeGenerationPresentation();
|
|
10567
|
+
token.ensureCurrent();
|
|
10568
|
+
_optionalChain([this, 'access', _724 => _724.qualityHistory, 'optionalAccess', _725 => _725.write, 'call', _726 => _726("downlink", initialLevel)]);
|
|
10445
10569
|
const onFinish = this.mediaController.onNetworkVideoFinish;
|
|
10446
10570
|
if (this.mediaController.source === "networkVideo") {
|
|
10447
10571
|
this.streamController.activateNetworkVideoCompletion(() => {
|
|
10448
|
-
if (this.currentState.taskID === taskID && this.currentState.connectionState === "Generating" /* generating */) {
|
|
10572
|
+
if (this.currentState.taskID === taskID && (this.currentState.connectionState === "Starting" /* starting */ || this.currentState.connectionState === "Generating" /* generating */)) {
|
|
10449
10573
|
void this.recordingController.stop("generationEnded" /* generationEnded */);
|
|
10450
|
-
return _optionalChain([onFinish, 'optionalCall',
|
|
10574
|
+
return _optionalChain([onFinish, 'optionalCall', _727 => _727()]);
|
|
10451
10575
|
}
|
|
10452
10576
|
});
|
|
10453
10577
|
}
|
|
10454
10578
|
return this.connectionManager.makeRemoteStream();
|
|
10455
10579
|
}
|
|
10580
|
+
/**
|
|
10581
|
+
* 任务启动成功且当前视图完成预热后提交展示就绪状态,不阻塞远端流返回。
|
|
10582
|
+
*/
|
|
10583
|
+
async completeGenerationPresentation() {
|
|
10584
|
+
const { sessionID, taskID } = this.currentState;
|
|
10585
|
+
if (!sessionID || !taskID) {
|
|
10586
|
+
return;
|
|
10587
|
+
}
|
|
10588
|
+
await this.coordinator.remotePreviewDidBecomeReady(
|
|
10589
|
+
sessionID,
|
|
10590
|
+
taskID,
|
|
10591
|
+
() => this.renderController.isReady
|
|
10592
|
+
);
|
|
10593
|
+
}
|
|
10456
10594
|
/**
|
|
10457
10595
|
* 心跳失败或会话失效:结束当前连接生命周期并通过最终状态给出原因。
|
|
10458
10596
|
*/
|
|
@@ -10471,6 +10609,7 @@ var XmaxRealtimeManager = class _XmaxRealtimeManager {
|
|
|
10471
10609
|
this.mediaController.pauseLocalVideo();
|
|
10472
10610
|
this.launchTimer.cancel();
|
|
10473
10611
|
this.remoteFrameDisplayHandler = void 0;
|
|
10612
|
+
this.remoteRenderWarmupCompletedHandler = void 0;
|
|
10474
10613
|
this.clearVideoStatistics();
|
|
10475
10614
|
this.interpolationSize = void 0;
|
|
10476
10615
|
this.applyRemoteInterpolation();
|
|
@@ -10586,7 +10725,7 @@ var NonRealtimeTaskService = class {
|
|
|
10586
10725
|
* 提交一次任务;请求结果不确定时也不自动重试,以免重复扣费。
|
|
10587
10726
|
*/
|
|
10588
10727
|
async submitTask(options) {
|
|
10589
|
-
const model = _optionalChain([options, 'access',
|
|
10728
|
+
const model = _optionalChain([options, 'access', _728 => _728.model, 'optionalAccess', _729 => _729.trim, 'call', _730 => _730()]);
|
|
10590
10729
|
if (!model) {
|
|
10591
10730
|
invalid("Model must not be empty");
|
|
10592
10731
|
}
|
|
@@ -10726,7 +10865,7 @@ function parseTask(value) {
|
|
|
10726
10865
|
const uid = field(data, "uid", "string");
|
|
10727
10866
|
const status = field(data, "status", "string");
|
|
10728
10867
|
const quality = field(data, "quality", "string");
|
|
10729
|
-
if (!_optionalChain([uid, 'optionalAccess',
|
|
10868
|
+
if (!_optionalChain([uid, 'optionalAccess', _731 => _731.trim, 'call', _732 => _732()]) || !Object.values(NonRealtimeTaskStatus).includes(status)) {
|
|
10730
10869
|
malformed("Missing task UID or invalid status");
|
|
10731
10870
|
}
|
|
10732
10871
|
if (quality !== void 0 && !Object.values(NonRealtimeQuality).includes(quality)) {
|
|
@@ -10808,7 +10947,7 @@ var XmaxNonRealtimeManager = class {
|
|
|
10808
10947
|
* 取得任务快照,不把服务端失败终态当成查询失败。
|
|
10809
10948
|
*/
|
|
10810
10949
|
getTask(taskUid, options) {
|
|
10811
|
-
return this.tasks.getTask(taskUid, _optionalChain([options, 'optionalAccess',
|
|
10950
|
+
return this.tasks.getTask(taskUid, _optionalChain([options, 'optionalAccess', _733 => _733.signal]));
|
|
10812
10951
|
}
|
|
10813
10952
|
/**
|
|
10814
10953
|
* 批量取得任务快照。
|
|
@@ -10842,8 +10981,8 @@ var XmaxNonRealtimeManager = class {
|
|
|
10842
10981
|
const controller = new AbortController();
|
|
10843
10982
|
let timedOut = false;
|
|
10844
10983
|
const abort = () => controller.abort();
|
|
10845
|
-
_optionalChain([options, 'access',
|
|
10846
|
-
if (_optionalChain([options, 'access',
|
|
10984
|
+
_optionalChain([options, 'access', _734 => _734.signal, 'optionalAccess', _735 => _735.addEventListener, 'call', _736 => _736("abort", abort, { once: true })]);
|
|
10985
|
+
if (_optionalChain([options, 'access', _737 => _737.signal, 'optionalAccess', _738 => _738.aborted])) {
|
|
10847
10986
|
abort();
|
|
10848
10987
|
}
|
|
10849
10988
|
const timer = options.timeoutMs === void 0 ? void 0 : setTimeout(() => {
|
|
@@ -10869,7 +11008,7 @@ var XmaxNonRealtimeManager = class {
|
|
|
10869
11008
|
ensureActive(controller.signal);
|
|
10870
11009
|
failures = 0;
|
|
10871
11010
|
try {
|
|
10872
|
-
void Promise.resolve(_optionalChain([options, 'access',
|
|
11011
|
+
void Promise.resolve(_optionalChain([options, 'access', _739 => _739.onTaskUpdated, 'optionalCall', _740 => _740(task)])).catch(() => {
|
|
10873
11012
|
});
|
|
10874
11013
|
} catch (e35) {
|
|
10875
11014
|
}
|
|
@@ -10899,7 +11038,7 @@ var XmaxNonRealtimeManager = class {
|
|
|
10899
11038
|
throw error;
|
|
10900
11039
|
} finally {
|
|
10901
11040
|
clearTimeout(timer);
|
|
10902
|
-
_optionalChain([options, 'access',
|
|
11041
|
+
_optionalChain([options, 'access', _741 => _741.signal, 'optionalAccess', _742 => _742.removeEventListener, 'call', _743 => _743("abort", abort)]);
|
|
10903
11042
|
}
|
|
10904
11043
|
}
|
|
10905
11044
|
};
|
|
@@ -10943,7 +11082,7 @@ function isTransient(error) {
|
|
|
10943
11082
|
}
|
|
10944
11083
|
function isResultAvailable(task) {
|
|
10945
11084
|
const result = task.result;
|
|
10946
|
-
if (!_optionalChain([result, 'optionalAccess',
|
|
11085
|
+
if (!_optionalChain([result, 'optionalAccess', _744 => _744.url, 'optionalAccess', _745 => _745.trim, 'call', _746 => _746()]) || _optionalChain([result, 'access', _747 => _747.uploadError, 'optionalAccess', _748 => _748.trim, 'call', _749 => _749()]) || result.uploadStatus !== void 0 && result.uploadStatus !== "success") {
|
|
10947
11086
|
return false;
|
|
10948
11087
|
}
|
|
10949
11088
|
try {
|
|
@@ -11013,9 +11152,9 @@ var XmaxClient = class {
|
|
|
11013
11152
|
/**
|
|
11014
11153
|
* 创建媒体处理与能力查询 Service。
|
|
11015
11154
|
*
|
|
11016
|
-
* @param model 媒体输入规则使用的模型,默认为 `x2.
|
|
11155
|
+
* @param model 媒体输入规则使用的模型,默认为 `x2.1.1-preview-cn`。
|
|
11017
11156
|
*/
|
|
11018
|
-
createMediaService(model = "x2.
|
|
11157
|
+
createMediaService(model = "x2.1.1-preview-cn" /* x2_1_1_preview_cn */) {
|
|
11019
11158
|
return new MediaService(model);
|
|
11020
11159
|
}
|
|
11021
11160
|
/**
|
|
@@ -11033,7 +11172,7 @@ var RealtimeConfiguration = class {
|
|
|
11033
11172
|
/**
|
|
11034
11173
|
* 创建实时业务配置。
|
|
11035
11174
|
*
|
|
11036
|
-
* @param init.model 实时生成业务使用的模型;未知名称原样透传,默认配置同 x2.1-preview。
|
|
11175
|
+
* @param init.model 实时生成业务使用的模型;未知名称原样透传,默认配置同 x2.1.1-preview-cn。
|
|
11037
11176
|
* @param init.provider RTC 提供方,默认按模型定义选择;必须受模型支持,创建后不可切换。
|
|
11038
11177
|
* @param init.isFrameInterpolationEnabled 是否默认开启远端生成画面的插帧,默认 false。
|
|
11039
11178
|
*/
|
|
@@ -11200,12 +11339,81 @@ var RenderStatisticsController = class {
|
|
|
11200
11339
|
*/
|
|
11201
11340
|
notify(statistics) {
|
|
11202
11341
|
try {
|
|
11203
|
-
_optionalChain([this, 'access',
|
|
11342
|
+
_optionalChain([this, 'access', _750 => _750.handler, 'optionalCall', _751 => _751(statistics)]);
|
|
11204
11343
|
} catch (e37) {
|
|
11205
11344
|
}
|
|
11206
11345
|
}
|
|
11207
11346
|
};
|
|
11208
11347
|
|
|
11348
|
+
// src/Render/Video/RenderWarmupController.ts
|
|
11349
|
+
var RenderWarmupController = class {
|
|
11350
|
+
/**
|
|
11351
|
+
* 创建视图预热控制器。
|
|
11352
|
+
*/
|
|
11353
|
+
constructor(element) {
|
|
11354
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "element", element);
|
|
11355
|
+
/**
|
|
11356
|
+
* 预热配置与生命周期
|
|
11357
|
+
*/
|
|
11358
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "durationMs");
|
|
11359
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "timer");
|
|
11360
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "started", false);
|
|
11361
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "completed", false);
|
|
11362
|
+
}
|
|
11363
|
+
/**
|
|
11364
|
+
* 是否仍在等待首帧或预热完成;期间不允许对不可见画面交互。
|
|
11365
|
+
*/
|
|
11366
|
+
get isPending() {
|
|
11367
|
+
return this.durationMs !== void 0 && !this.completed;
|
|
11368
|
+
}
|
|
11369
|
+
/**
|
|
11370
|
+
* 为新媒体隐藏画面;undefined 表示直接显示,不启用预热。
|
|
11371
|
+
*/
|
|
11372
|
+
prepare(durationMs) {
|
|
11373
|
+
this.reset();
|
|
11374
|
+
this.durationMs = durationMs;
|
|
11375
|
+
if (durationMs === void 0) {
|
|
11376
|
+
return;
|
|
11377
|
+
}
|
|
11378
|
+
this.element.style.transition = "none";
|
|
11379
|
+
this.element.style.opacity = "0";
|
|
11380
|
+
this.element.style.pointerEvents = "none";
|
|
11381
|
+
}
|
|
11382
|
+
/**
|
|
11383
|
+
* 首帧就绪后开始一次性预热,结束时通知并渐入画面。
|
|
11384
|
+
*/
|
|
11385
|
+
start(onCompleted) {
|
|
11386
|
+
if (this.durationMs === void 0 || this.started) {
|
|
11387
|
+
return;
|
|
11388
|
+
}
|
|
11389
|
+
this.started = true;
|
|
11390
|
+
this.timer = setTimeout(() => {
|
|
11391
|
+
this.timer = void 0;
|
|
11392
|
+
this.completed = true;
|
|
11393
|
+
const reduceMotion = _optionalChain([globalThis, 'access', _752 => _752.matchMedia, 'optionalCall', _753 => _753("(prefers-reduced-motion: reduce)"), 'access', _754 => _754.matches]);
|
|
11394
|
+
this.element.style.transition = reduceMotion ? "none" : "opacity 300ms ease-in-out";
|
|
11395
|
+
this.element.style.opacity = "1";
|
|
11396
|
+
this.element.style.pointerEvents = "";
|
|
11397
|
+
onCompleted();
|
|
11398
|
+
}, this.durationMs);
|
|
11399
|
+
}
|
|
11400
|
+
/**
|
|
11401
|
+
* 换流或卸载时取消预热和渐入,防止旧任务显示新画面。
|
|
11402
|
+
*/
|
|
11403
|
+
reset() {
|
|
11404
|
+
clearTimeout(this.timer);
|
|
11405
|
+
this.timer = void 0;
|
|
11406
|
+
this.started = false;
|
|
11407
|
+
this.completed = false;
|
|
11408
|
+
if (this.durationMs !== void 0) {
|
|
11409
|
+
this.element.style.transition = "";
|
|
11410
|
+
this.element.style.opacity = "";
|
|
11411
|
+
this.element.style.pointerEvents = "";
|
|
11412
|
+
}
|
|
11413
|
+
this.durationMs = void 0;
|
|
11414
|
+
}
|
|
11415
|
+
};
|
|
11416
|
+
|
|
11209
11417
|
// ../../node_modules/.pnpm/framegen@1.4.0/node_modules/framegen/rt.js
|
|
11210
11418
|
var WG = 8;
|
|
11211
11419
|
var texBgSeq = 0;
|
|
@@ -13328,11 +13536,11 @@ var _FrameInterpolationManager = class _FrameInterpolationManager {
|
|
|
13328
13536
|
if (this.destroyed) return;
|
|
13329
13537
|
this.destroyed = true;
|
|
13330
13538
|
this.device.removeEventListener("uncapturederror", this.onGPUError);
|
|
13331
|
-
_optionalChain([this, 'access',
|
|
13539
|
+
_optionalChain([this, 'access', _755 => _755.runtime, 'optionalAccess', _756 => _756.destroy, 'call', _757 => _757()]);
|
|
13332
13540
|
this.runtime = void 0;
|
|
13333
13541
|
this.textures.forEach((texture) => texture.destroy());
|
|
13334
13542
|
this.textures = [];
|
|
13335
|
-
_optionalChain([this, 'access',
|
|
13543
|
+
_optionalChain([this, 'access', _758 => _758.context, 'optionalAccess', _759 => _759.unconfigure, 'call', _760 => _760()]);
|
|
13336
13544
|
this.device.destroy();
|
|
13337
13545
|
}
|
|
13338
13546
|
};
|
|
@@ -13509,7 +13717,7 @@ var RemoteVideoFramePipeline = class {
|
|
|
13509
13717
|
this.displayedTime = frame.time;
|
|
13510
13718
|
this.canvas.style.visibility = "visible";
|
|
13511
13719
|
this.setActive(true);
|
|
13512
|
-
_optionalChain([this, 'access',
|
|
13720
|
+
_optionalChain([this, 'access', _761 => _761.options, 'access', _762 => _762.onFramePresented, 'optionalCall', _763 => _763(_nullishCoalesce(frame.interpolated, () => ( false)))]);
|
|
13513
13721
|
}
|
|
13514
13722
|
async initialize() {
|
|
13515
13723
|
this.loading = true;
|
|
@@ -13537,7 +13745,7 @@ var RemoteVideoFramePipeline = class {
|
|
|
13537
13745
|
setActive(active) {
|
|
13538
13746
|
if (active === this.active) return;
|
|
13539
13747
|
this.active = active;
|
|
13540
|
-
_optionalChain([this, 'access',
|
|
13748
|
+
_optionalChain([this, 'access', _764 => _764.options, 'access', _765 => _765.onActiveChange, 'optionalCall', _766 => _766(active)]);
|
|
13541
13749
|
}
|
|
13542
13750
|
resetTimeline(preserveGpuTimeout = false) {
|
|
13543
13751
|
this.generation++;
|
|
@@ -13570,7 +13778,7 @@ var RemoteVideoFramePipeline = class {
|
|
|
13570
13778
|
this.callback = void 0;
|
|
13571
13779
|
clearTimeout(this.initializationTimer);
|
|
13572
13780
|
this.resetTimeline();
|
|
13573
|
-
_optionalChain([this, 'access',
|
|
13781
|
+
_optionalChain([this, 'access', _767 => _767.processor, 'optionalAccess', _768 => _768.destroy, 'call', _769 => _769()]);
|
|
13574
13782
|
this.processor = void 0;
|
|
13575
13783
|
}
|
|
13576
13784
|
};
|
|
@@ -13651,9 +13859,9 @@ var TrajectoryOverlayView = class {
|
|
|
13651
13859
|
* 卸载时取消采样、动画、捕获和事件监听;Renderer 可以再次挂载。
|
|
13652
13860
|
*/
|
|
13653
13861
|
dispose() {
|
|
13654
|
-
_optionalChain([this, 'access',
|
|
13862
|
+
_optionalChain([this, 'access', _770 => _770.binding, 'optionalAccess', _771 => _771.detach, 'call', _772 => _772(this)]);
|
|
13655
13863
|
this.cancel();
|
|
13656
|
-
_optionalChain([this, 'access',
|
|
13864
|
+
_optionalChain([this, 'access', _773 => _773.resizeObserver, 'optionalAccess', _774 => _774.disconnect, 'call', _775 => _775()]);
|
|
13657
13865
|
document.removeEventListener("visibilitychange", this.visibilityChanged);
|
|
13658
13866
|
this.element.removeEventListener("pointerdown", this.onDown);
|
|
13659
13867
|
this.element.removeEventListener("pointermove", this.onMove);
|
|
@@ -13805,7 +14013,7 @@ var TrajectoryOverlayView = class {
|
|
|
13805
14013
|
return;
|
|
13806
14014
|
}
|
|
13807
14015
|
this.lastSample = now;
|
|
13808
|
-
_optionalChain([this, 'access',
|
|
14016
|
+
_optionalChain([this, 'access', _776 => _776.binding, 'optionalAccess', _777 => _777.submit, 'call', _778 => _778({
|
|
13809
14017
|
points: [...this.pointers.values()].map((point) => point.location),
|
|
13810
14018
|
viewportSize: this.viewport,
|
|
13811
14019
|
contentMode: this.contentMode,
|
|
@@ -13919,7 +14127,7 @@ var DefaultTrajectoryEffectRenderer = class {
|
|
|
13919
14127
|
this.hasTrailPixels = false;
|
|
13920
14128
|
this.idleFadeFrames = 0;
|
|
13921
14129
|
for (const canvas of [this.trailCanvas, this.effectCanvas]) {
|
|
13922
|
-
_optionalChain([canvas, 'access',
|
|
14130
|
+
_optionalChain([canvas, 'access', _779 => _779.getContext, 'call', _780 => _780("2d"), 'optionalAccess', _781 => _781.clearRect, 'call', _782 => _782(0, 0, canvas.width, canvas.height)]);
|
|
13923
14131
|
}
|
|
13924
14132
|
}
|
|
13925
14133
|
/**
|
|
@@ -14120,6 +14328,10 @@ var XmaxVideoView = class {
|
|
|
14120
14328
|
* 呈现统计组件
|
|
14121
14329
|
*/
|
|
14122
14330
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "statisticsController");
|
|
14331
|
+
/**
|
|
14332
|
+
* 远端画面预热与渐入组件
|
|
14333
|
+
*/
|
|
14334
|
+
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "warmupController");
|
|
14123
14335
|
/**
|
|
14124
14336
|
* DOM 挂载状态
|
|
14125
14337
|
*/
|
|
@@ -14130,12 +14342,13 @@ var XmaxVideoView = class {
|
|
|
14130
14342
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "interactionEnabled", true);
|
|
14131
14343
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "customTrajectoryRenderer");
|
|
14132
14344
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "trajectoryOverlay");
|
|
14133
|
-
this.contentMode = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
14134
|
-
this.interactionEnabled = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
14345
|
+
this.contentMode = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _783 => _783.videoContentMode]), () => ( "fill")) /* fill */;
|
|
14346
|
+
this.interactionEnabled = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _784 => _784.isInteractionEnabled]), () => ( true));
|
|
14135
14347
|
this.element = document.createElement("div");
|
|
14136
14348
|
this.element.style.position = "relative";
|
|
14137
14349
|
this.element.style.overflow = "hidden";
|
|
14138
14350
|
this.element.style.backgroundColor = "black";
|
|
14351
|
+
this.warmupController = new RenderWarmupController(this.element);
|
|
14139
14352
|
this.videoElement = document.createElement("video");
|
|
14140
14353
|
this.statisticsController = new RenderStatisticsController(this.videoElement);
|
|
14141
14354
|
this.videoElement.autoplay = true;
|
|
@@ -14159,7 +14372,7 @@ var XmaxVideoView = class {
|
|
|
14159
14372
|
*/
|
|
14160
14373
|
set isInteractionEnabled(enabled) {
|
|
14161
14374
|
this.interactionEnabled = enabled;
|
|
14162
|
-
_optionalChain([this, 'access',
|
|
14375
|
+
_optionalChain([this, 'access', _785 => _785.trajectoryOverlay, 'optionalAccess', _786 => _786.configure, 'call', _787 => _787(this.contentMode, this.mirrored, enabled && !this.warmupController.isPending)]);
|
|
14163
14376
|
}
|
|
14164
14377
|
/**
|
|
14165
14378
|
* 自定义轨迹视觉效果;undefined 表示使用 SDK 默认效果。
|
|
@@ -14260,6 +14473,7 @@ var XmaxVideoView = class {
|
|
|
14260
14473
|
this.startInterpolation();
|
|
14261
14474
|
this.startRenderStatistics();
|
|
14262
14475
|
if ((this.videoElement.srcObject || this.videoElement.getAttribute("src")) && !this.hasNotifiedFrameDisplay) {
|
|
14476
|
+
this.prepareRenderWarmup();
|
|
14263
14477
|
this.armFrameDisplayNotification();
|
|
14264
14478
|
}
|
|
14265
14479
|
}
|
|
@@ -14272,6 +14486,8 @@ var XmaxVideoView = class {
|
|
|
14272
14486
|
this.statisticsController.stop();
|
|
14273
14487
|
this.stopInterpolation();
|
|
14274
14488
|
this.cancelFrameDisplayNotification();
|
|
14489
|
+
this.warmupController.reset();
|
|
14490
|
+
this.hasNotifiedFrameDisplay = false;
|
|
14275
14491
|
if (this.videoElement.getAttribute("src")) {
|
|
14276
14492
|
this.videoElement.pause();
|
|
14277
14493
|
}
|
|
@@ -14281,6 +14497,7 @@ var XmaxVideoView = class {
|
|
|
14281
14497
|
* 设置网络视频预览;静音播放一次,不捕获或发布媒体轨道。 @internal
|
|
14282
14498
|
*/
|
|
14283
14499
|
setVideoURL(url) {
|
|
14500
|
+
this.warmupController.reset();
|
|
14284
14501
|
this.statisticsController.stop();
|
|
14285
14502
|
this.stopInterpolation();
|
|
14286
14503
|
this.cancelFrameDisplayNotification();
|
|
@@ -14309,13 +14526,27 @@ var XmaxVideoView = class {
|
|
|
14309
14526
|
this.cancelFrameDisplayNotification();
|
|
14310
14527
|
this.hasNotifiedFrameDisplay = false;
|
|
14311
14528
|
this.videoElement.srcObject = stream;
|
|
14529
|
+
this.warmupController.reset();
|
|
14312
14530
|
if (stream) {
|
|
14313
14531
|
this.videoElement.autoplay = true;
|
|
14532
|
+
this.prepareRenderWarmup();
|
|
14314
14533
|
this.armFrameDisplayNotification();
|
|
14315
14534
|
this.startInterpolation();
|
|
14316
14535
|
this.startRenderStatistics();
|
|
14317
14536
|
}
|
|
14318
14537
|
}
|
|
14538
|
+
/**
|
|
14539
|
+
* 新生成任务重新等待首帧和预热,不替换正在播放的媒体流。 @internal
|
|
14540
|
+
*/
|
|
14541
|
+
prepareForGeneration() {
|
|
14542
|
+
this.cancelFrameDisplayNotification();
|
|
14543
|
+
this.warmupController.reset();
|
|
14544
|
+
this.hasNotifiedFrameDisplay = false;
|
|
14545
|
+
this.prepareRenderWarmup();
|
|
14546
|
+
if (!this.detached && this.videoElement.srcObject) {
|
|
14547
|
+
this.armFrameDisplayNotification();
|
|
14548
|
+
}
|
|
14549
|
+
}
|
|
14319
14550
|
/**
|
|
14320
14551
|
* 由远端绑定注入配置;本地预览不走此管线。 @internal
|
|
14321
14552
|
*/
|
|
@@ -14348,11 +14579,11 @@ var XmaxVideoView = class {
|
|
|
14348
14579
|
...options,
|
|
14349
14580
|
onActiveChange: (active) => {
|
|
14350
14581
|
this.statisticsController.setInterpolationActive(active);
|
|
14351
|
-
_optionalChain([options, 'access',
|
|
14582
|
+
_optionalChain([options, 'access', _788 => _788.onActiveChange, 'optionalCall', _789 => _789(active)]);
|
|
14352
14583
|
},
|
|
14353
14584
|
onFramePresented: (interpolated) => {
|
|
14354
14585
|
this.statisticsController.recordCanvasFrame(interpolated);
|
|
14355
|
-
_optionalChain([options, 'access',
|
|
14586
|
+
_optionalChain([options, 'access', _790 => _790.onFramePresented, 'optionalCall', _791 => _791(interpolated)]);
|
|
14356
14587
|
}
|
|
14357
14588
|
});
|
|
14358
14589
|
this.interpolationPipeline = pipeline;
|
|
@@ -14364,8 +14595,8 @@ var XmaxVideoView = class {
|
|
|
14364
14595
|
stopInterpolation() {
|
|
14365
14596
|
const pipeline = this.interpolationPipeline;
|
|
14366
14597
|
this.interpolationPipeline = void 0;
|
|
14367
|
-
_optionalChain([pipeline, 'optionalAccess',
|
|
14368
|
-
_optionalChain([this, 'access',
|
|
14598
|
+
_optionalChain([pipeline, 'optionalAccess', _792 => _792.stop, 'call', _793 => _793()]);
|
|
14599
|
+
_optionalChain([this, 'access', _794 => _794.interpolationCanvas, 'optionalAccess', _795 => _795.remove, 'call', _796 => _796()]);
|
|
14369
14600
|
this.interpolationCanvas = void 0;
|
|
14370
14601
|
}
|
|
14371
14602
|
/**
|
|
@@ -14390,11 +14621,12 @@ var XmaxVideoView = class {
|
|
|
14390
14621
|
* 解绑当前轨道并清空渲染内容。
|
|
14391
14622
|
*/
|
|
14392
14623
|
detachCurrentTrack() {
|
|
14624
|
+
this.warmupController.reset();
|
|
14393
14625
|
this.disposeTrajectory();
|
|
14394
14626
|
this.statisticsController.stop();
|
|
14395
14627
|
const track = this.currentTrack;
|
|
14396
14628
|
if (track) {
|
|
14397
|
-
_optionalChain([VideoRenderRegistry, 'access',
|
|
14629
|
+
_optionalChain([VideoRenderRegistry, 'access', _797 => _797.binding, 'call', _798 => _798(track), 'optionalAccess', _799 => _799.detachHandler, 'call', _800 => _800(this)]);
|
|
14398
14630
|
}
|
|
14399
14631
|
this.setFrameInterpolation(void 0);
|
|
14400
14632
|
this.cancelFrameDisplayNotification();
|
|
@@ -14417,8 +14649,15 @@ var XmaxVideoView = class {
|
|
|
14417
14649
|
}
|
|
14418
14650
|
this.hasNotifiedFrameDisplay = true;
|
|
14419
14651
|
this.cancelFrameDisplayNotification();
|
|
14420
|
-
|
|
14421
|
-
_optionalChain([
|
|
14652
|
+
const notifiedSequence = this.frameNotificationSequence;
|
|
14653
|
+
_optionalChain([binding, 'optionalAccess', _801 => _801.frameDisplayHandler, 'optionalCall', _802 => _802()]);
|
|
14654
|
+
_optionalChain([this, 'access', _803 => _803.frameDisplayHandler, 'optionalCall', _804 => _804()]);
|
|
14655
|
+
if (notifiedSequence === this.frameNotificationSequence) {
|
|
14656
|
+
this.warmupController.start(() => {
|
|
14657
|
+
this.applyContentMode();
|
|
14658
|
+
_optionalChain([binding, 'optionalAccess', _805 => _805.renderWarmupCompletedHandler, 'optionalCall', _806 => _806()]);
|
|
14659
|
+
});
|
|
14660
|
+
}
|
|
14422
14661
|
};
|
|
14423
14662
|
if (typeof this.videoElement.requestVideoFrameCallback === "function") {
|
|
14424
14663
|
this.videoFrameCallbackID = this.videoElement.requestVideoFrameCallback(notify);
|
|
@@ -14446,11 +14685,19 @@ var XmaxVideoView = class {
|
|
|
14446
14685
|
this.onPlaying = void 0;
|
|
14447
14686
|
}
|
|
14448
14687
|
}
|
|
14688
|
+
/**
|
|
14689
|
+
* 仅远端渲染绑定启用预热,本地预览和普通媒体直接显示。
|
|
14690
|
+
*/
|
|
14691
|
+
prepareRenderWarmup() {
|
|
14692
|
+
const binding = this.currentTrack ? VideoRenderRegistry.binding(this.currentTrack) : void 0;
|
|
14693
|
+
this.warmupController.prepare(_optionalChain([binding, 'optionalAccess', _807 => _807.renderWarmupMs]));
|
|
14694
|
+
this.applyContentMode();
|
|
14695
|
+
}
|
|
14449
14696
|
/**
|
|
14450
14697
|
* 应用显示模式与镜像样式。
|
|
14451
14698
|
*/
|
|
14452
14699
|
applyContentMode() {
|
|
14453
|
-
_optionalChain([this, 'access',
|
|
14700
|
+
_optionalChain([this, 'access', _808 => _808.trajectoryOverlay, 'optionalAccess', _809 => _809.configure, 'call', _810 => _810(this.contentMode, this.mirrored, this.interactionEnabled && !this.warmupController.isPending)]);
|
|
14454
14701
|
this.videoElement.style.objectFit = OBJECT_FIT[this.contentMode];
|
|
14455
14702
|
this.videoElement.style.transform = this.mirrored ? "scaleX(-1)" : "";
|
|
14456
14703
|
if (this.interpolationCanvas) {
|
|
@@ -14477,7 +14724,7 @@ var XmaxVideoView = class {
|
|
|
14477
14724
|
}
|
|
14478
14725
|
const overlay = new TrajectoryOverlayView(_nullishCoalesce(this.customTrajectoryRenderer, () => ( new DefaultTrajectoryEffectRenderer())));
|
|
14479
14726
|
this.trajectoryOverlay = overlay;
|
|
14480
|
-
overlay.configure(this.contentMode, this.mirrored, this.interactionEnabled);
|
|
14727
|
+
overlay.configure(this.contentMode, this.mirrored, this.interactionEnabled && !this.warmupController.isPending);
|
|
14481
14728
|
this.element.appendChild(overlay.element);
|
|
14482
14729
|
binding.attach(overlay);
|
|
14483
14730
|
}
|
|
@@ -14485,7 +14732,7 @@ var XmaxVideoView = class {
|
|
|
14485
14732
|
* 换轨或卸载时移除全部交互资源;再次挂载时重新建立绑定。
|
|
14486
14733
|
*/
|
|
14487
14734
|
disposeTrajectory() {
|
|
14488
|
-
_optionalChain([this, 'access',
|
|
14735
|
+
_optionalChain([this, 'access', _811 => _811.trajectoryOverlay, 'optionalAccess', _812 => _812.dispose, 'call', _813 => _813()]);
|
|
14489
14736
|
this.trajectoryOverlay = void 0;
|
|
14490
14737
|
}
|
|
14491
14738
|
};
|
|
@@ -14519,15 +14766,15 @@ var XmaxRealtimeVideoView = class {
|
|
|
14519
14766
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "currentLocalTrack");
|
|
14520
14767
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "currentRemoteTrack");
|
|
14521
14768
|
_chunk4DE2IREAcjs.__publicField.call(void 0, this, "contentMode");
|
|
14522
|
-
this.contentMode = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
14523
|
-
this.currentLocalTrack = _optionalChain([options, 'optionalAccess',
|
|
14524
|
-
this.currentRemoteTrack = _optionalChain([options, 'optionalAccess',
|
|
14769
|
+
this.contentMode = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _814 => _814.videoContentMode]), () => ( "fill")) /* fill */;
|
|
14770
|
+
this.currentLocalTrack = _optionalChain([options, 'optionalAccess', _815 => _815.localTrack]);
|
|
14771
|
+
this.currentRemoteTrack = _optionalChain([options, 'optionalAccess', _816 => _816.remoteTrack]);
|
|
14525
14772
|
this.element = document.createElement("div");
|
|
14526
14773
|
this.element.style.position = "relative";
|
|
14527
14774
|
this.element.style.overflow = "hidden";
|
|
14528
14775
|
this.element.style.backgroundColor = "black";
|
|
14529
14776
|
this.localVideoView = new XmaxVideoView({ videoContentMode: this.contentMode, isInteractionEnabled: false });
|
|
14530
|
-
this.remoteVideoView = new XmaxVideoView({ videoContentMode: this.contentMode, isInteractionEnabled: _optionalChain([options, 'optionalAccess',
|
|
14777
|
+
this.remoteVideoView = new XmaxVideoView({ videoContentMode: this.contentMode, isInteractionEnabled: _optionalChain([options, 'optionalAccess', _817 => _817.isInteractionEnabled]) });
|
|
14531
14778
|
for (const view of [this.localVideoView, this.remoteVideoView]) {
|
|
14532
14779
|
view.element.style.position = "absolute";
|
|
14533
14780
|
view.element.style.inset = "0";
|
|
@@ -14578,7 +14825,7 @@ var XmaxRealtimeVideoView = class {
|
|
|
14578
14825
|
}
|
|
14579
14826
|
/**
|
|
14580
14827
|
* 当前显示的远端生成视频轨道。
|
|
14581
|
-
*
|
|
14828
|
+
* SDK 远端轨道等待首帧及预热后渐入;置空时立即恢复本地预览。
|
|
14582
14829
|
*/
|
|
14583
14830
|
get remoteTrack() {
|
|
14584
14831
|
return this.currentRemoteTrack;
|
|
@@ -14639,18 +14886,23 @@ var XmaxRealtimeVideoView = class {
|
|
|
14639
14886
|
this.element.remove();
|
|
14640
14887
|
}
|
|
14641
14888
|
/**
|
|
14642
|
-
*
|
|
14889
|
+
* 更新远端轨道绑定;SDK 轨道共用单轨视图的预热,普通轨道等待首帧后渐入。
|
|
14643
14890
|
*/
|
|
14644
14891
|
updateRemoteTrack() {
|
|
14645
14892
|
const remoteTrack = this.currentRemoteTrack;
|
|
14646
14893
|
this.remoteVideoView.frameDisplayHandler = void 0;
|
|
14894
|
+
this.remoteVideoView.track = void 0;
|
|
14647
14895
|
this.remoteVideoView.element.style.transition = "";
|
|
14648
14896
|
this.remoteVideoView.element.style.opacity = "0";
|
|
14649
14897
|
this.remoteVideoView.element.style.visibility = "hidden";
|
|
14650
|
-
this.remoteVideoView.track = void 0;
|
|
14651
14898
|
if (!remoteTrack) {
|
|
14652
14899
|
return;
|
|
14653
14900
|
}
|
|
14901
|
+
if (_optionalChain([VideoRenderRegistry, 'access', _818 => _818.binding, 'call', _819 => _819(remoteTrack), 'optionalAccess', _820 => _820.renderWarmupMs]) !== void 0) {
|
|
14902
|
+
this.remoteVideoView.element.style.visibility = "visible";
|
|
14903
|
+
this.remoteVideoView.track = remoteTrack;
|
|
14904
|
+
return;
|
|
14905
|
+
}
|
|
14654
14906
|
this.remoteVideoView.frameDisplayHandler = () => {
|
|
14655
14907
|
if (this.currentRemoteTrack !== remoteTrack) {
|
|
14656
14908
|
return;
|
|
@@ -14713,4 +14965,4 @@ var XmaxRealtimeVideoView = class {
|
|
|
14713
14965
|
|
|
14714
14966
|
|
|
14715
14967
|
exports.XmaxEnvironment = XmaxEnvironment; exports.apiBaseURL = apiBaseURL; exports.XmaxLoggerOption = XmaxLoggerOption; exports.XmaxLogger = XmaxLogger; exports.XmaxErrorCode = XmaxErrorCode; exports.XmaxError = XmaxError; exports.RealtimeVideoEncoderPreference = RealtimeVideoEncoderPreference; exports.RealtimeVideoFormat = RealtimeVideoFormat; exports.RtcProvider = RtcProvider; exports.RealtimeModel = RealtimeModel; exports.modelDisplayName = modelDisplayName; exports.defaultFrameRate = defaultFrameRate; exports.defaultCameraVideoFormat = defaultCameraVideoFormat; exports.supportedRtcProviders = supportedRtcProviders; exports.MediaService = MediaService; exports.StoredFile = StoredFile; exports.StorageService = StorageService; exports.CameraPosition = CameraPosition; exports.RealtimeVideoTrack = RealtimeVideoTrack; exports.RealtimeMediaStream = RealtimeMediaStream; exports.RealtimeVideoSampleMethod = RealtimeVideoSampleMethod; exports.VideoContentMode = VideoContentMode; exports.RealtimeRecordingEventType = RealtimeRecordingEventType; exports.RealtimeRecordingFinishReason = RealtimeRecordingFinishReason; exports.RealtimeContext = RealtimeContext; exports.RealtimeConnectionState = RealtimeConnectionState; exports.RealtimeReason = RealtimeReason; exports.RealtimeState = RealtimeState; exports.XmaxConfiguration = XmaxConfiguration; exports.NonRealtimeQuality = NonRealtimeQuality; exports.NonRealtimeTaskStatus = NonRealtimeTaskStatus; exports.NonRealtimeTaskError = NonRealtimeTaskError; exports.XmaxClient = XmaxClient; exports.RealtimeConfiguration = RealtimeConfiguration; exports.XmaxVideoView = XmaxVideoView; exports.XmaxRealtimeVideoView = XmaxRealtimeVideoView;
|
|
14716
|
-
//# sourceMappingURL=chunk-
|
|
14968
|
+
//# sourceMappingURL=chunk-UF2RD42G.cjs.map
|