@minto-ai/tools 1.0.57 → 1.0.59
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/dist/browser/create-audio-permission.d.ts +154 -27
- package/dist/index.js +346 -98
- package/package.json +1 -9
|
@@ -1,45 +1,172 @@
|
|
|
1
|
+
declare enum AudioPermissionErrorType {
|
|
2
|
+
NO_USER_INTERACTION_ERROR = "NoUserInteractionError",
|
|
3
|
+
AUTOPLAY_BLOCKED = "AutoplayBlocked",
|
|
4
|
+
AUTOPLAY_UNKNOWN_ERROR = "AutoplayUnknownError",
|
|
5
|
+
SECURE_CONTEXT_ERROR = "SecureContextError",
|
|
6
|
+
PERMISSION_DENIED_PERMANENTLY = "PermissionDeniedPermanently",
|
|
7
|
+
NOT_ALLOWED_ERROR = "NotAllowedError",
|
|
8
|
+
MEDIA_DEVICES_API_UNAVAILABLE = "MediaDevicesApiUnavailable",
|
|
9
|
+
NOT_FOUND_ERROR = "NotFoundError",
|
|
10
|
+
NOT_READABLE_ERROR = "NotReadableError",
|
|
11
|
+
OVERCONSTRAINED_ERROR = "OverconstrainedError",
|
|
12
|
+
SECURITY_ERROR = "SecurityError",
|
|
13
|
+
MICROPHONE_UNKNOWN_ERROR = "MicrophoneUnknownError"
|
|
14
|
+
}
|
|
15
|
+
declare class AudioPermissionError extends Error {
|
|
16
|
+
name: AudioPermissionErrorType;
|
|
17
|
+
private constructor();
|
|
18
|
+
static create(name: AudioPermissionErrorType, message?: string): AudioPermissionError;
|
|
19
|
+
}
|
|
1
20
|
/**
|
|
2
|
-
*
|
|
21
|
+
* 音频播放权限管理类
|
|
3
22
|
*
|
|
4
|
-
*
|
|
23
|
+
* 根据MDN文档,音频播放权限需要满足以下条件之一:
|
|
24
|
+
* 1. 音频被静音或音量为0
|
|
25
|
+
* 2. 用户已与网站产生交互(点击、触摸、按键等)
|
|
26
|
+
* 3. 网站已被加入自动播放白名单
|
|
27
|
+
* 4. 通过Permissions Policy授权
|
|
5
28
|
*
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* -
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
29
|
+
* 跨平台实现策略:
|
|
30
|
+
* - PC端:预检测AudioContext状态,如果suspended则监听用户交互
|
|
31
|
+
* - iOS Safari:必须在用户交互事件的调用栈中调用resume(),需要50ms延迟确保状态变更
|
|
32
|
+
* - Android:直接在用户交互后检测AudioContext状态
|
|
33
|
+
*
|
|
34
|
+
* 自动播放策略限制:
|
|
35
|
+
* - Chrome 66+:需要用户交互或MEI(Media Engagement Index)足够高
|
|
36
|
+
* - Safari:严格要求用户交互,AudioContext创建时默认为suspended状态
|
|
37
|
+
* - Firefox:相对宽松,但仍会阻止明显的自动播放行为
|
|
38
|
+
*
|
|
39
|
+
*
|
|
40
|
+
*
|
|
41
|
+
* 实现原理:
|
|
42
|
+
* PC:
|
|
43
|
+
* 1.在PC端首先预检测AudioContext状态:
|
|
44
|
+
* 如果状态是 “running” 状态则可以播放音频,
|
|
45
|
+
* 如果状态不是 “running” 状态则需要监听用户交互事件,
|
|
46
|
+
* 2.用户交互事件触发后,再检测AudioContext状态:
|
|
47
|
+
* 如果状态是 “running” 状态则可以播放音频,
|
|
48
|
+
* 如果状态不是 “running” 状态则抛出异常。
|
|
49
|
+
*
|
|
50
|
+
* IOS:
|
|
51
|
+
* 1.用户交互事件触发后,再检测AudioContext状态:
|
|
52
|
+
* 如果状态是 “suspended” 则需要调用 resume 方法,并且需要延迟 50ms,
|
|
53
|
+
* 如果状态不是 “suspended” 状态进行下一步判断,
|
|
54
|
+
* 2.获取AudioContext状态:
|
|
55
|
+
* 如果状态是 “running” 状态则可以播放音频,
|
|
56
|
+
* 如果状态不是 “running” 状态则抛出异常。
|
|
57
|
+
*
|
|
58
|
+
* Android:
|
|
59
|
+
* 1.用户交互事件触发后,再检测AudioContext状态:
|
|
60
|
+
* 如果状态是 “running” 状态则可以播放音频,
|
|
61
|
+
* 如果状态不是 “running” 状态则抛出异常。
|
|
17
62
|
*/
|
|
18
|
-
declare class
|
|
63
|
+
declare class AudioPlaybackPermission {
|
|
19
64
|
private userInteracted;
|
|
20
|
-
private audioPermissionGranted;
|
|
21
65
|
constructor();
|
|
22
66
|
/**
|
|
23
|
-
*
|
|
24
|
-
* 根据不同平台采用相应的权限检测策略
|
|
67
|
+
* 初始化播放权限检测
|
|
25
68
|
*/
|
|
26
|
-
private
|
|
69
|
+
private initPlaybackPermission;
|
|
27
70
|
/**
|
|
28
|
-
*
|
|
29
|
-
* 监听多种交互事件类型,确保在各种设备上都能正确检测到用户操作
|
|
71
|
+
* 检测初始AudioContext状态(仅PC平台)
|
|
30
72
|
*/
|
|
31
|
-
private
|
|
73
|
+
private checkInitialAudioContextState;
|
|
32
74
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* @returns Promise<boolean> 返回权限获取结果,true表示成功,false表示失败
|
|
75
|
+
* 设置用户交互监听器
|
|
36
76
|
*/
|
|
37
|
-
|
|
77
|
+
private setupUserInteractionListeners;
|
|
78
|
+
/**
|
|
79
|
+
* 请求播放权限
|
|
80
|
+
* 根据Web Audio API最佳实践实现
|
|
81
|
+
*/
|
|
82
|
+
requestPlaybackPermission(): Promise<void>;
|
|
38
83
|
}
|
|
39
84
|
/**
|
|
40
|
-
*
|
|
85
|
+
* 麦克风权限管理类
|
|
86
|
+
*
|
|
87
|
+
* 根据MDN文档,getUserMedia需要满足:
|
|
88
|
+
* 1. 安全上下文(HTTPS)
|
|
89
|
+
* 2. 用户明确授权
|
|
90
|
+
* 3. 顶级文档上下文或通过Permissions Policy授权的iframe
|
|
91
|
+
*
|
|
92
|
+
*
|
|
93
|
+
* 权限状态说明:
|
|
94
|
+
* - granted: 用户已授权,可直接访问麦克风
|
|
95
|
+
* - denied: 用户已拒绝,需要用户手动在浏览器设置中重新开启
|
|
96
|
+
* - prompt: 首次访问,会弹出授权对话框
|
|
97
|
+
*
|
|
98
|
+
*
|
|
99
|
+
* 平台差异:
|
|
100
|
+
* - 桌面端:通过浏览器原生授权对话框处理
|
|
101
|
+
* - iOS Safari:权限被拒绝后,需要用户在系统设置中重新开启
|
|
102
|
+
* - Android Chrome:权限处理与桌面端类似,但某些版本可能有缓存问题
|
|
103
|
+
*
|
|
104
|
+
*
|
|
105
|
+
* 注意事项:
|
|
106
|
+
* 1. 浏览器会永久缓存用户的权限决定
|
|
107
|
+
* 2. 在非HTTPS环境下(除localhost外)会直接失败
|
|
108
|
+
* 3. 某些浏览器在隐私模式下可能有不同行为
|
|
109
|
+
* 4. iframe中使用需要正确配置Permissions Policy
|
|
110
|
+
*
|
|
41
111
|
*
|
|
42
|
-
*
|
|
112
|
+
* 实现原理:
|
|
113
|
+
* - PC平台:
|
|
114
|
+
* 1. 通过授权弹框申请权限:
|
|
115
|
+
* 如果用户拒绝了权限,会抛出异常
|
|
116
|
+
* 如果用户点击了允许,会返回成功
|
|
117
|
+
* 2.第二次申请权限,会根据用户第一次申请权限的结果:
|
|
118
|
+
* 如果用户第一次申请权限失败,会抛出异常
|
|
119
|
+
* 如果用户第一次申请权限成功,会返回成功
|
|
120
|
+
* - 移动端:
|
|
121
|
+
* 1. 通过授权弹框申请权限:
|
|
122
|
+
* 如果用户拒绝了权限,会抛出异常
|
|
123
|
+
* 如果用户点击了允许,会返回成功
|
|
124
|
+
* 2.第二次申请权限,会根据用户第一次申请权限的结果:
|
|
125
|
+
* 如果用户第一次申请权限失败,会抛出异常
|
|
126
|
+
* 如果用户第一次申请权限成功,会返回成功
|
|
127
|
+
*
|
|
128
|
+
* iOS平台:
|
|
129
|
+
* 1. 通过授权弹框申请权限:
|
|
130
|
+
* 如果用户拒绝了权限,会抛出异常
|
|
131
|
+
* 如果用户点击了允许,会返回成功
|
|
132
|
+
* 2.第二次申请权限,会根据用户第一次申请权限的结果:
|
|
133
|
+
* 如果用户第一次申请权限失败,会抛出异常
|
|
134
|
+
* 如果用户第一次申请权限成功,会返回成功
|
|
135
|
+
*
|
|
136
|
+
*
|
|
137
|
+
*/
|
|
138
|
+
declare class MicrophonePermission {
|
|
139
|
+
private microphonePermissionGranted;
|
|
140
|
+
private permissionDeniedPermanently;
|
|
141
|
+
/**
|
|
142
|
+
* 检查是否在安全上下文中
|
|
143
|
+
*/
|
|
144
|
+
private isSecureContext;
|
|
145
|
+
/**
|
|
146
|
+
* 请求麦克风权限
|
|
147
|
+
* 根据MediaDevices.getUserMedia规范实现
|
|
148
|
+
*/
|
|
149
|
+
requestMicrophonePermission(): Promise<void>;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* 统一的音频权限管理类
|
|
153
|
+
*/
|
|
154
|
+
declare class AudioPermission {
|
|
155
|
+
private playbackPermission;
|
|
156
|
+
private microphonePermission;
|
|
157
|
+
constructor();
|
|
158
|
+
/**
|
|
159
|
+
* 请求音频播放权限
|
|
160
|
+
*/
|
|
161
|
+
requestPlaybackPermission(): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* 请求麦克风权限
|
|
164
|
+
*/
|
|
165
|
+
requestMicrophonePermission(): Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* 创建或获取音频权限管理实例
|
|
43
169
|
*/
|
|
44
170
|
declare function createAudioPermission(): AudioPermission;
|
|
45
171
|
export default createAudioPermission;
|
|
172
|
+
export { AudioPermission, AudioPermissionError, AudioPermissionErrorType, AudioPlaybackPermission, MicrophonePermission };
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,13 @@ function _callSuper(t, o, e) {
|
|
|
46
46
|
function _classCallCheck(a, n) {
|
|
47
47
|
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
|
|
48
48
|
}
|
|
49
|
+
function _construct(t, e, r) {
|
|
50
|
+
if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
|
|
51
|
+
var o = [null];
|
|
52
|
+
o.push.apply(o, e);
|
|
53
|
+
var p = new (t.bind.apply(t, o))();
|
|
54
|
+
return r && _setPrototypeOf(p, r.prototype), p;
|
|
55
|
+
}
|
|
49
56
|
function _defineProperties(e, r) {
|
|
50
57
|
for (var t = 0; t < r.length; t++) {
|
|
51
58
|
var o = r[t];
|
|
@@ -53,7 +60,7 @@ function _defineProperties(e, r) {
|
|
|
53
60
|
}
|
|
54
61
|
}
|
|
55
62
|
function _createClass(e, r, t) {
|
|
56
|
-
return r && _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", {
|
|
63
|
+
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
|
|
57
64
|
writable: false
|
|
58
65
|
}), e;
|
|
59
66
|
}
|
|
@@ -128,6 +135,13 @@ function _inherits(t, e) {
|
|
|
128
135
|
writable: false
|
|
129
136
|
}), e && _setPrototypeOf(t, e);
|
|
130
137
|
}
|
|
138
|
+
function _isNativeFunction(t) {
|
|
139
|
+
try {
|
|
140
|
+
return -1 !== Function.toString.call(t).indexOf("[native code]");
|
|
141
|
+
} catch (n) {
|
|
142
|
+
return "function" == typeof t;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
131
145
|
function _isNativeReflectConstruct() {
|
|
132
146
|
try {
|
|
133
147
|
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {
|
|
@@ -488,6 +502,28 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
488
502
|
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
489
503
|
}
|
|
490
504
|
}
|
|
505
|
+
function _wrapNativeSuper(t) {
|
|
506
|
+
var r = "function" == typeof Map ? /* @__PURE__ */ new Map() : void 0;
|
|
507
|
+
return _wrapNativeSuper = function(t2) {
|
|
508
|
+
if (null === t2 || !_isNativeFunction(t2)) return t2;
|
|
509
|
+
if ("function" != typeof t2) throw new TypeError("Super expression must either be null or a function");
|
|
510
|
+
if (void 0 !== r) {
|
|
511
|
+
if (r.has(t2)) return r.get(t2);
|
|
512
|
+
r.set(t2, Wrapper);
|
|
513
|
+
}
|
|
514
|
+
function Wrapper() {
|
|
515
|
+
return _construct(t2, arguments, _getPrototypeOf(this).constructor);
|
|
516
|
+
}
|
|
517
|
+
return Wrapper.prototype = Object.create(t2.prototype, {
|
|
518
|
+
constructor: {
|
|
519
|
+
value: Wrapper,
|
|
520
|
+
enumerable: false,
|
|
521
|
+
writable: true,
|
|
522
|
+
configurable: true
|
|
523
|
+
}
|
|
524
|
+
}), _setPrototypeOf(Wrapper, t2);
|
|
525
|
+
}, _wrapNativeSuper(t);
|
|
526
|
+
}
|
|
491
527
|
var check = function check2(it) {
|
|
492
528
|
return it && it.Math === Math && it;
|
|
493
529
|
};
|
|
@@ -13238,157 +13274,361 @@ function copyText(text) {
|
|
|
13238
13274
|
}
|
|
13239
13275
|
});
|
|
13240
13276
|
}
|
|
13241
|
-
function
|
|
13242
|
-
|
|
13243
|
-
|
|
13244
|
-
|
|
13245
|
-
|
|
13246
|
-
|
|
13247
|
-
|
|
13248
|
-
|
|
13249
|
-
|
|
13250
|
-
|
|
13251
|
-
|
|
13277
|
+
var AudioPermissionError = /* @__PURE__ */ function(_Error) {
|
|
13278
|
+
function AudioPermissionError2(name, message) {
|
|
13279
|
+
var _this;
|
|
13280
|
+
_classCallCheck(this, AudioPermissionError2);
|
|
13281
|
+
_this = _callSuper(this, AudioPermissionError2, [message]);
|
|
13282
|
+
_defineProperty(_this, "name", void 0);
|
|
13283
|
+
_this.name = name;
|
|
13284
|
+
return _this;
|
|
13285
|
+
}
|
|
13286
|
+
_inherits(AudioPermissionError2, _Error);
|
|
13287
|
+
return _createClass(AudioPermissionError2, null, [{
|
|
13288
|
+
key: "create",
|
|
13289
|
+
value: function create4(name, message) {
|
|
13290
|
+
var _codeMessageMap;
|
|
13291
|
+
var codeMessageMap = (_codeMessageMap = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_codeMessageMap, "NoUserInteractionError", "需要用户交互才能播放音频"), "AutoplayBlocked", "自动播放被浏览器阻止"), "AutoplayUnknownError", "未知自动播放错误"), "SecureContextError", "麦克风权限需要在安全上下文(HTTPS)中使用"), "PermissionDeniedPermanently", "音频权限已被永久拒绝,需在浏览器设置中开启麦克风权限"), "MediaDevicesApiUnavailable", "MediaDevices API不可用"), "NotAllowedError", "麦克风权限被拒绝"), "NotReadableError", "音频设备被其他应用程序占用"), "NotFoundError", "未找到音频输入设备"), "SecurityError", "安全策略阻止访问麦克风"), _defineProperty(_defineProperty(_codeMessageMap, "OverconstrainedError", "音频设备不满足指定的约束条件"), "MicrophoneUnknownError", "未知麦克风权限错误"));
|
|
13292
|
+
return new AudioPermissionError2(name, message || codeMessageMap[name]);
|
|
13293
|
+
}
|
|
13294
|
+
}]);
|
|
13295
|
+
}(/* @__PURE__ */ _wrapNativeSuper(Error));
|
|
13296
|
+
var AudioPlaybackPermission = /* @__PURE__ */ function() {
|
|
13297
|
+
function AudioPlaybackPermission2() {
|
|
13298
|
+
_classCallCheck(this, AudioPlaybackPermission2);
|
|
13252
13299
|
_defineProperty(this, "userInteracted", false);
|
|
13253
|
-
|
|
13254
|
-
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13300
|
+
this.initPlaybackPermission();
|
|
13301
|
+
}
|
|
13302
|
+
return _createClass(AudioPlaybackPermission2, [{
|
|
13303
|
+
key: "initPlaybackPermission",
|
|
13304
|
+
value: function initPlaybackPermission() {
|
|
13305
|
+
var _this2 = this;
|
|
13306
|
+
if (!isIos() && !isAndroid()) {
|
|
13307
|
+
this.checkInitialAudioContextState()["catch"](function() {
|
|
13308
|
+
_this2.setupUserInteractionListeners();
|
|
13309
|
+
});
|
|
13310
|
+
} else {
|
|
13311
|
+
this.setupUserInteractionListeners();
|
|
13312
|
+
}
|
|
13313
|
+
}
|
|
13314
|
+
/**
|
|
13315
|
+
* 检测初始AudioContext状态(仅PC平台)
|
|
13316
|
+
*/
|
|
13317
|
+
}, {
|
|
13318
|
+
key: "checkInitialAudioContextState",
|
|
13258
13319
|
value: function() {
|
|
13259
|
-
var
|
|
13260
|
-
var
|
|
13320
|
+
var _checkInitialAudioContextState = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee() {
|
|
13321
|
+
var testContext;
|
|
13261
13322
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
13262
13323
|
while (1) switch (_context.prev = _context.next) {
|
|
13263
13324
|
case 0:
|
|
13264
|
-
|
|
13265
|
-
|
|
13266
|
-
|
|
13267
|
-
try {
|
|
13268
|
-
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
|
13269
|
-
if (audioContext.state === "running") {
|
|
13270
|
-
this.userInteracted = true;
|
|
13271
|
-
this.audioPermissionGranted = true;
|
|
13272
|
-
audioContext.close();
|
|
13273
|
-
} else {
|
|
13274
|
-
audioContext.close();
|
|
13275
|
-
this.waitForUserInteraction();
|
|
13276
|
-
}
|
|
13277
|
-
} catch (error2) {
|
|
13278
|
-
console.warn("AudioContext创建失败,回退到用户交互模式:", error2);
|
|
13279
|
-
this.waitForUserInteraction();
|
|
13280
|
-
}
|
|
13325
|
+
testContext = new (window.AudioContext || window.webkitAudioContext)();
|
|
13326
|
+
if (testContext.state === "running") {
|
|
13327
|
+
this.userInteracted = true;
|
|
13281
13328
|
}
|
|
13282
|
-
|
|
13329
|
+
_context.next = 4;
|
|
13330
|
+
return testContext.close();
|
|
13331
|
+
case 4:
|
|
13332
|
+
if (!this.userInteracted) {
|
|
13333
|
+
_context.next = 8;
|
|
13334
|
+
break;
|
|
13335
|
+
}
|
|
13336
|
+
return _context.abrupt("return", Promise.resolve());
|
|
13337
|
+
case 8:
|
|
13338
|
+
return _context.abrupt("return", Promise.reject());
|
|
13339
|
+
case 9:
|
|
13283
13340
|
case "end":
|
|
13284
13341
|
return _context.stop();
|
|
13285
13342
|
}
|
|
13286
13343
|
}, _callee, this);
|
|
13287
13344
|
}));
|
|
13288
|
-
function
|
|
13289
|
-
return
|
|
13345
|
+
function checkInitialAudioContextState() {
|
|
13346
|
+
return _checkInitialAudioContextState.apply(this, arguments);
|
|
13290
13347
|
}
|
|
13291
|
-
return
|
|
13348
|
+
return checkInitialAudioContextState;
|
|
13292
13349
|
}()
|
|
13293
13350
|
}, {
|
|
13294
|
-
key: "
|
|
13295
|
-
value: function
|
|
13296
|
-
var
|
|
13351
|
+
key: "setupUserInteractionListeners",
|
|
13352
|
+
value: function setupUserInteractionListeners() {
|
|
13353
|
+
var _this3 = this;
|
|
13297
13354
|
var interactionEvents = ["click", "touchstart", "touchend", "keydown", "mousedown", "pointerdown"];
|
|
13298
13355
|
var _handleInteraction = function handleInteraction() {
|
|
13299
|
-
|
|
13356
|
+
_this3.userInteracted = true;
|
|
13357
|
+
console.log(_this3.userInteracted);
|
|
13300
13358
|
interactionEvents.forEach(function(eventType) {
|
|
13301
13359
|
document.removeEventListener(eventType, _handleInteraction);
|
|
13302
13360
|
});
|
|
13303
13361
|
};
|
|
13304
13362
|
interactionEvents.forEach(function(eventType) {
|
|
13305
13363
|
document.addEventListener(eventType, _handleInteraction, {
|
|
13306
|
-
passive: true
|
|
13364
|
+
passive: true,
|
|
13365
|
+
once: true
|
|
13307
13366
|
});
|
|
13308
13367
|
});
|
|
13309
13368
|
}
|
|
13310
13369
|
/**
|
|
13311
|
-
*
|
|
13312
|
-
*
|
|
13313
|
-
* @returns Promise<boolean> 返回权限获取结果,true表示成功,false表示失败
|
|
13370
|
+
* 请求播放权限
|
|
13371
|
+
* 根据Web Audio API最佳实践实现
|
|
13314
13372
|
*/
|
|
13315
13373
|
}, {
|
|
13316
|
-
key: "
|
|
13374
|
+
key: "requestPlaybackPermission",
|
|
13317
13375
|
value: function() {
|
|
13318
|
-
var
|
|
13319
|
-
var
|
|
13376
|
+
var _requestPlaybackPermission = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee2() {
|
|
13377
|
+
var audioContext, unknownError;
|
|
13320
13378
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
13321
13379
|
while (1) switch (_context2.prev = _context2.next) {
|
|
13322
13380
|
case 0:
|
|
13381
|
+
audioContext = null;
|
|
13382
|
+
_context2.prev = 1;
|
|
13323
13383
|
if (this.userInteracted) {
|
|
13324
|
-
_context2.next =
|
|
13384
|
+
_context2.next = 4;
|
|
13325
13385
|
break;
|
|
13326
13386
|
}
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13387
|
+
throw AudioPermissionError.create(
|
|
13388
|
+
"NoUserInteractionError"
|
|
13389
|
+
/* NO_USER_INTERACTION_ERROR */
|
|
13390
|
+
);
|
|
13391
|
+
case 4:
|
|
13392
|
+
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
|
13393
|
+
if (!(isIos() && audioContext.state === "suspended")) {
|
|
13394
|
+
_context2.next = 10;
|
|
13332
13395
|
break;
|
|
13333
13396
|
}
|
|
13334
|
-
return _context2.abrupt("return", true);
|
|
13335
|
-
case 5:
|
|
13336
|
-
_context2.prev = 5;
|
|
13337
13397
|
_context2.next = 8;
|
|
13338
|
-
return
|
|
13339
|
-
audio: true
|
|
13340
|
-
});
|
|
13398
|
+
return audioContext.resume();
|
|
13341
13399
|
case 8:
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13400
|
+
_context2.next = 10;
|
|
13401
|
+
return new Promise(function(resolve2) {
|
|
13402
|
+
return setTimeout(resolve2, 50);
|
|
13403
|
+
});
|
|
13404
|
+
case 10:
|
|
13405
|
+
if (!(audioContext.state !== "running")) {
|
|
13406
|
+
_context2.next = 12;
|
|
13346
13407
|
break;
|
|
13347
13408
|
}
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13409
|
+
throw AudioPermissionError.create(
|
|
13410
|
+
"AutoplayBlocked"
|
|
13411
|
+
/* AUTOPLAY_BLOCKED */
|
|
13412
|
+
);
|
|
13413
|
+
case 12:
|
|
13414
|
+
return _context2.abrupt("return", Promise.resolve());
|
|
13415
|
+
case 15:
|
|
13416
|
+
_context2.prev = 15;
|
|
13417
|
+
_context2.t0 = _context2["catch"](1);
|
|
13418
|
+
if (!(_context2.t0 instanceof AudioPermissionError)) {
|
|
13419
|
+
_context2.next = 19;
|
|
13420
|
+
break;
|
|
13421
|
+
}
|
|
13422
|
+
return _context2.abrupt("return", Promise.reject(_context2.t0));
|
|
13423
|
+
case 19:
|
|
13424
|
+
unknownError = AudioPermissionError.create("AutoplayUnknownError", _context2.t0 instanceof Error ? _context2.t0.message : void 0);
|
|
13425
|
+
return _context2.abrupt("return", Promise.reject(unknownError));
|
|
13426
|
+
case 21:
|
|
13427
|
+
_context2.prev = 21;
|
|
13428
|
+
if (!(audioContext && audioContext.state !== "closed")) {
|
|
13429
|
+
_context2.next = 30;
|
|
13430
|
+
break;
|
|
13431
|
+
}
|
|
13432
|
+
_context2.prev = 23;
|
|
13433
|
+
_context2.next = 26;
|
|
13434
|
+
return audioContext.close();
|
|
13435
|
+
case 26:
|
|
13436
|
+
_context2.next = 30;
|
|
13437
|
+
break;
|
|
13438
|
+
case 28:
|
|
13439
|
+
_context2.prev = 28;
|
|
13440
|
+
_context2.t1 = _context2["catch"](23);
|
|
13441
|
+
case 30:
|
|
13442
|
+
return _context2.finish(21);
|
|
13443
|
+
case 31:
|
|
13444
|
+
case "end":
|
|
13445
|
+
return _context2.stop();
|
|
13446
|
+
}
|
|
13447
|
+
}, _callee2, this, [[1, 15, 21, 31], [23, 28]]);
|
|
13448
|
+
}));
|
|
13449
|
+
function requestPlaybackPermission() {
|
|
13450
|
+
return _requestPlaybackPermission.apply(this, arguments);
|
|
13451
|
+
}
|
|
13452
|
+
return requestPlaybackPermission;
|
|
13453
|
+
}()
|
|
13454
|
+
}]);
|
|
13455
|
+
}();
|
|
13456
|
+
var MicrophonePermission = /* @__PURE__ */ function() {
|
|
13457
|
+
function MicrophonePermission2() {
|
|
13458
|
+
_classCallCheck(this, MicrophonePermission2);
|
|
13459
|
+
_defineProperty(this, "microphonePermissionGranted", false);
|
|
13460
|
+
_defineProperty(this, "permissionDeniedPermanently", false);
|
|
13461
|
+
}
|
|
13462
|
+
return _createClass(MicrophonePermission2, [{
|
|
13463
|
+
key: "isSecureContext",
|
|
13464
|
+
value: (
|
|
13465
|
+
/**
|
|
13466
|
+
* 检查是否在安全上下文中
|
|
13467
|
+
*/
|
|
13468
|
+
function isSecureContext() {
|
|
13469
|
+
return window.isSecureContext || location.protocol === "https:" || location.hostname === "localhost";
|
|
13470
|
+
}
|
|
13471
|
+
)
|
|
13472
|
+
/**
|
|
13473
|
+
* 请求麦克风权限
|
|
13474
|
+
* 根据MediaDevices.getUserMedia规范实现
|
|
13475
|
+
*/
|
|
13476
|
+
}, {
|
|
13477
|
+
key: "requestMicrophonePermission",
|
|
13478
|
+
value: function() {
|
|
13479
|
+
var _requestMicrophonePermission = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee3() {
|
|
13480
|
+
var stream, errorType, audioError, unknownError;
|
|
13481
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
13482
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
13483
|
+
case 0:
|
|
13484
|
+
_context3.prev = 0;
|
|
13485
|
+
if (this.isSecureContext()) {
|
|
13486
|
+
_context3.next = 3;
|
|
13487
|
+
break;
|
|
13488
|
+
}
|
|
13489
|
+
throw AudioPermissionError.create(
|
|
13490
|
+
"SecureContextError"
|
|
13491
|
+
/* SECURE_CONTEXT_ERROR */
|
|
13492
|
+
);
|
|
13493
|
+
case 3:
|
|
13494
|
+
if (!this.permissionDeniedPermanently) {
|
|
13495
|
+
_context3.next = 5;
|
|
13496
|
+
break;
|
|
13497
|
+
}
|
|
13498
|
+
throw AudioPermissionError.create(
|
|
13499
|
+
"PermissionDeniedPermanently"
|
|
13500
|
+
/* PERMISSION_DENIED_PERMANENTLY */
|
|
13501
|
+
);
|
|
13502
|
+
case 5:
|
|
13503
|
+
if (!this.microphonePermissionGranted) {
|
|
13504
|
+
_context3.next = 7;
|
|
13505
|
+
break;
|
|
13506
|
+
}
|
|
13507
|
+
return _context3.abrupt("return", Promise.resolve());
|
|
13508
|
+
case 7:
|
|
13509
|
+
if (!(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia)) {
|
|
13510
|
+
_context3.next = 9;
|
|
13511
|
+
break;
|
|
13512
|
+
}
|
|
13513
|
+
throw AudioPermissionError.create(
|
|
13514
|
+
"MediaDevicesApiUnavailable"
|
|
13515
|
+
/* MEDIA_DEVICES_API_UNAVAILABLE */
|
|
13516
|
+
);
|
|
13517
|
+
case 9:
|
|
13518
|
+
_context3.next = 11;
|
|
13519
|
+
return navigator.mediaDevices.getUserMedia({
|
|
13520
|
+
audio: {
|
|
13521
|
+
echoCancellation: true,
|
|
13522
|
+
noiseSuppression: true,
|
|
13523
|
+
autoGainControl: true
|
|
13524
|
+
}
|
|
13525
|
+
});
|
|
13526
|
+
case 11:
|
|
13527
|
+
stream = _context3.sent;
|
|
13528
|
+
this.microphonePermissionGranted = true;
|
|
13352
13529
|
stream.getTracks().forEach(function(track2) {
|
|
13353
|
-
|
|
13530
|
+
track2.stop();
|
|
13354
13531
|
});
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
_context2.next = 33;
|
|
13532
|
+
return _context3.abrupt("return", Promise.resolve());
|
|
13533
|
+
case 17:
|
|
13534
|
+
_context3.prev = 17;
|
|
13535
|
+
_context3.t0 = _context3["catch"](0);
|
|
13536
|
+
this.microphonePermissionGranted = false;
|
|
13537
|
+
if (!(_context3.t0 instanceof AudioPermissionError)) {
|
|
13538
|
+
_context3.next = 22;
|
|
13363
13539
|
break;
|
|
13364
13540
|
}
|
|
13365
|
-
|
|
13366
|
-
|
|
13541
|
+
return _context3.abrupt("return", Promise.reject(_context3.t0));
|
|
13542
|
+
case 22:
|
|
13543
|
+
if (!(_context3.t0 instanceof DOMException)) {
|
|
13544
|
+
_context3.next = 40;
|
|
13545
|
+
break;
|
|
13546
|
+
}
|
|
13547
|
+
_context3.t1 = _context3.t0.name;
|
|
13548
|
+
_context3.next = _context3.t1 === "NotFoundError" ? 26 : _context3.t1 === "NotAllowedError" ? 28 : _context3.t1 === "NotReadableError" ? 31 : _context3.t1 === "OverconstrainedError" ? 33 : _context3.t1 === "SecurityError" ? 35 : 37;
|
|
13367
13549
|
break;
|
|
13368
13550
|
case 26:
|
|
13369
|
-
|
|
13370
|
-
return
|
|
13551
|
+
errorType = "NotFoundError";
|
|
13552
|
+
return _context3.abrupt("break", 38);
|
|
13371
13553
|
case 28:
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
console.warn("未知的权限请求错误:", _context2.t0.message);
|
|
13554
|
+
this.permissionDeniedPermanently = true;
|
|
13555
|
+
errorType = "NotAllowedError";
|
|
13556
|
+
return _context3.abrupt("break", 38);
|
|
13557
|
+
case 31:
|
|
13558
|
+
errorType = "NotReadableError";
|
|
13559
|
+
return _context3.abrupt("break", 38);
|
|
13379
13560
|
case 33:
|
|
13380
|
-
|
|
13381
|
-
return
|
|
13561
|
+
errorType = "OverconstrainedError";
|
|
13562
|
+
return _context3.abrupt("break", 38);
|
|
13382
13563
|
case 35:
|
|
13564
|
+
errorType = "SecurityError";
|
|
13565
|
+
return _context3.abrupt("break", 38);
|
|
13566
|
+
case 37:
|
|
13567
|
+
errorType = "MicrophoneUnknownError";
|
|
13568
|
+
case 38:
|
|
13569
|
+
audioError = AudioPermissionError.create(errorType);
|
|
13570
|
+
return _context3.abrupt("return", Promise.reject(audioError));
|
|
13571
|
+
case 40:
|
|
13572
|
+
unknownError = AudioPermissionError.create("MicrophoneUnknownError", _context3.t0 instanceof Error ? _context3.t0.message : void 0);
|
|
13573
|
+
return _context3.abrupt("return", Promise.reject(unknownError));
|
|
13574
|
+
case 42:
|
|
13383
13575
|
case "end":
|
|
13384
|
-
return
|
|
13576
|
+
return _context3.stop();
|
|
13385
13577
|
}
|
|
13386
|
-
},
|
|
13578
|
+
}, _callee3, this, [[0, 17]]);
|
|
13387
13579
|
}));
|
|
13388
|
-
function
|
|
13389
|
-
return
|
|
13580
|
+
function requestMicrophonePermission() {
|
|
13581
|
+
return _requestMicrophonePermission.apply(this, arguments);
|
|
13390
13582
|
}
|
|
13391
|
-
return
|
|
13583
|
+
return requestMicrophonePermission;
|
|
13584
|
+
}()
|
|
13585
|
+
}]);
|
|
13586
|
+
}();
|
|
13587
|
+
var AudioPermission = /* @__PURE__ */ function() {
|
|
13588
|
+
function AudioPermission2() {
|
|
13589
|
+
_classCallCheck(this, AudioPermission2);
|
|
13590
|
+
_defineProperty(this, "playbackPermission", void 0);
|
|
13591
|
+
_defineProperty(this, "microphonePermission", void 0);
|
|
13592
|
+
this.playbackPermission = new AudioPlaybackPermission();
|
|
13593
|
+
this.microphonePermission = new MicrophonePermission();
|
|
13594
|
+
}
|
|
13595
|
+
return _createClass(AudioPermission2, [{
|
|
13596
|
+
key: "requestPlaybackPermission",
|
|
13597
|
+
value: function() {
|
|
13598
|
+
var _requestPlaybackPermission2 = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee4() {
|
|
13599
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
13600
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
13601
|
+
case 0:
|
|
13602
|
+
return _context4.abrupt("return", this.playbackPermission.requestPlaybackPermission());
|
|
13603
|
+
case 1:
|
|
13604
|
+
case "end":
|
|
13605
|
+
return _context4.stop();
|
|
13606
|
+
}
|
|
13607
|
+
}, _callee4, this);
|
|
13608
|
+
}));
|
|
13609
|
+
function requestPlaybackPermission() {
|
|
13610
|
+
return _requestPlaybackPermission2.apply(this, arguments);
|
|
13611
|
+
}
|
|
13612
|
+
return requestPlaybackPermission;
|
|
13613
|
+
}()
|
|
13614
|
+
}, {
|
|
13615
|
+
key: "requestMicrophonePermission",
|
|
13616
|
+
value: function() {
|
|
13617
|
+
var _requestMicrophonePermission2 = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee5() {
|
|
13618
|
+
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
13619
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
13620
|
+
case 0:
|
|
13621
|
+
return _context5.abrupt("return", this.microphonePermission.requestMicrophonePermission());
|
|
13622
|
+
case 1:
|
|
13623
|
+
case "end":
|
|
13624
|
+
return _context5.stop();
|
|
13625
|
+
}
|
|
13626
|
+
}, _callee5, this);
|
|
13627
|
+
}));
|
|
13628
|
+
function requestMicrophonePermission() {
|
|
13629
|
+
return _requestMicrophonePermission2.apply(this, arguments);
|
|
13630
|
+
}
|
|
13631
|
+
return requestMicrophonePermission;
|
|
13392
13632
|
}()
|
|
13393
13633
|
}]);
|
|
13394
13634
|
}();
|
|
@@ -13399,6 +13639,14 @@ function createAudioPermission() {
|
|
|
13399
13639
|
}
|
|
13400
13640
|
return audioPermissionInstance;
|
|
13401
13641
|
}
|
|
13642
|
+
function isAndroid() {
|
|
13643
|
+
var userAgent2 = navigator.userAgent.toLowerCase();
|
|
13644
|
+
return /android/.test(userAgent2);
|
|
13645
|
+
}
|
|
13646
|
+
function isIos() {
|
|
13647
|
+
var userAgent2 = navigator.userAgent.toLowerCase();
|
|
13648
|
+
return /iphone|ipad|ipod/.test(userAgent2);
|
|
13649
|
+
}
|
|
13402
13650
|
function isMobile() {
|
|
13403
13651
|
return isAndroid() || isIos();
|
|
13404
13652
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minto-ai/tools",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.59",
|
|
5
5
|
"description": "明途公共工具库",
|
|
6
6
|
"author": "hcc",
|
|
7
7
|
"license": "ISC",
|
|
@@ -12,14 +12,6 @@
|
|
|
12
12
|
"publishConfig": {
|
|
13
13
|
"access": "public"
|
|
14
14
|
},
|
|
15
|
-
"exports": {
|
|
16
|
-
".": {
|
|
17
|
-
"types": "./dist/index.d.ts",
|
|
18
|
-
"import": "./dist/index.js",
|
|
19
|
-
"require": "./dist/index.js"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"main": "./dist/index.js",
|
|
23
15
|
"module": "./dist/index.js",
|
|
24
16
|
"types": "./dist/index.d.ts",
|
|
25
17
|
"files": [
|