@authme/util 2.8.31 → 2.8.32
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/index.cjs +61 -144
- package/index.js +61 -144
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -1448,50 +1448,6 @@ const videoConstraintsFactory = (isPC, facingMode) => {
|
|
|
1448
1448
|
}
|
|
1449
1449
|
};
|
|
1450
1450
|
};
|
|
1451
|
-
/**
|
|
1452
|
-
* 等待camera完全就緒
|
|
1453
|
-
* 用於解決外接camera初始化延遲問題
|
|
1454
|
-
* @param videoTrack - MediaStreamTrack 實例
|
|
1455
|
-
* @param maxWaitMs - 最大等待時間(毫秒)
|
|
1456
|
-
* @returns Promise<boolean> - true表示camera已就緒,false表示超時
|
|
1457
|
-
*/
|
|
1458
|
-
function waitForCameraReady(videoTrack, maxWaitMs = 100) {
|
|
1459
|
-
var _a, _b, _c, _d;
|
|
1460
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1461
|
-
const startTime = Date.now();
|
|
1462
|
-
const checkInterval = 50; // 每50ms檢查一次
|
|
1463
|
-
const minStableTime = 50; // 最小穩定時間:即使檢測到就緒,也要等待一小段時間
|
|
1464
|
-
while (Date.now() - startTime < maxWaitMs) {
|
|
1465
|
-
const _settings = videoTrack.getSettings();
|
|
1466
|
-
const capabilities = (_a = videoTrack.getCapabilities) === null || _a === void 0 ? void 0 : _a.call(videoTrack);
|
|
1467
|
-
// 檢查camera是否已提供完整資訊
|
|
1468
|
-
// 1. 必須有基本的寬高設定
|
|
1469
|
-
// 2. 如果支援 getCapabilities,確認有最大解析度資訊
|
|
1470
|
-
const hasBasicSettings = _settings.width && _settings.height;
|
|
1471
|
-
const hasCapabilities = !capabilities || ((_b = capabilities === null || capabilities === void 0 ? void 0 : capabilities.width) === null || _b === void 0 ? void 0 : _b.max) && ((_c = capabilities === null || capabilities === void 0 ? void 0 : capabilities.height) === null || _c === void 0 ? void 0 : _c.max);
|
|
1472
|
-
if (hasBasicSettings && hasCapabilities) {
|
|
1473
|
-
const elapsedTime = Date.now() - startTime;
|
|
1474
|
-
// ⚠️ 關鍵修正:即使檢測到就緒,也要確保經過最小等待時間
|
|
1475
|
-
// 這對外接相機特別重要,它們需要額外的硬體初始化時間
|
|
1476
|
-
if (elapsedTime < minStableTime) {
|
|
1477
|
-
const remainingTime = minStableTime - elapsedTime;
|
|
1478
|
-
console.log(`⏳ Camera基本就緒,額外等待 ${remainingTime}ms 確保穩定 (當前: ${_settings.width}x${_settings.height})`);
|
|
1479
|
-
yield new Promise(resolve => setTimeout(resolve, remainingTime));
|
|
1480
|
-
}
|
|
1481
|
-
console.log(`✅ Camera就緒 (耗時: ${Date.now() - startTime}ms, 解析度: ${_settings.width}x${_settings.height})`);
|
|
1482
|
-
return true;
|
|
1483
|
-
}
|
|
1484
|
-
yield new Promise(resolve => setTimeout(resolve, checkInterval));
|
|
1485
|
-
}
|
|
1486
|
-
const settings = videoTrack.getSettings();
|
|
1487
|
-
console.warn(`⚠️ Camera未在時限內完全就緒 (${maxWaitMs}ms), 當前狀態:`, {
|
|
1488
|
-
width: settings.width,
|
|
1489
|
-
height: settings.height,
|
|
1490
|
-
hasCapabilities: !!((_d = videoTrack.getCapabilities) === null || _d === void 0 ? void 0 : _d.call(videoTrack))
|
|
1491
|
-
});
|
|
1492
|
-
return false;
|
|
1493
|
-
});
|
|
1494
|
-
}
|
|
1495
1451
|
function inferFacingModeFromLabel(label) {
|
|
1496
1452
|
const pattern = /rear|back|rück|arrière|trasera|trás|traseira|posteriore|后|後|背|задней|الخلفية|후|arka|achterzijde|หลัง|baksidan|bagside|sau|bak|tylny|takakamera|belakang|אחורית|πίσω|spate|hátsó|zadní|darrere|zadná|задня|stražnja|belakang|बैक/i;
|
|
1497
1453
|
if (pattern.test(label !== null && label !== void 0 ? label : '')) {
|
|
@@ -1545,8 +1501,53 @@ function arrayFromAsync(asyncIterable) {
|
|
|
1545
1501
|
return result;
|
|
1546
1502
|
});
|
|
1547
1503
|
}
|
|
1504
|
+
function upgradeResolution(videoTrack) {
|
|
1505
|
+
var _a;
|
|
1506
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1507
|
+
const targetConstraints = {
|
|
1508
|
+
width: {
|
|
1509
|
+
ideal: 1920,
|
|
1510
|
+
max: 3840
|
|
1511
|
+
},
|
|
1512
|
+
height: {
|
|
1513
|
+
ideal: 1080,
|
|
1514
|
+
max: 2160
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
const minAcceptableWidth = 1280; // 最低可接受的解析度寬度
|
|
1518
|
+
const maxAttempts = 300; // 最多嘗試10次
|
|
1519
|
+
const retryDelay = 100; // 每次重試間隔1秒
|
|
1520
|
+
console.log('🚀 開始提升解析度...');
|
|
1521
|
+
const startTime = Date.now();
|
|
1522
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1523
|
+
try {
|
|
1524
|
+
yield videoTrack.applyConstraints(targetConstraints);
|
|
1525
|
+
const settings = videoTrack.getSettings();
|
|
1526
|
+
const currentWidth = (_a = settings.width) !== null && _a !== void 0 ? _a : 0;
|
|
1527
|
+
console.log(`嘗試 ${attempt}/${maxAttempts} - 解析度: ${currentWidth}x${settings.height}`);
|
|
1528
|
+
// 檢查是否達到可接受的解析度
|
|
1529
|
+
if (currentWidth >= minAcceptableWidth) {
|
|
1530
|
+
const elapsedTime = Date.now() - startTime;
|
|
1531
|
+
console.log(`✅ 解析度提升成功!最終: ${currentWidth}x${settings.height} (耗時: ${elapsedTime}ms)`);
|
|
1532
|
+
return; // 成功,退出
|
|
1533
|
+
}
|
|
1534
|
+
// 解析度還不夠,繼續重試
|
|
1535
|
+
console.log(`⚠️ 解析度 ${currentWidth} < ${minAcceptableWidth},繼續重試...`);
|
|
1536
|
+
} catch (e) {
|
|
1537
|
+
console.warn(`⚠️ 第 ${attempt} 次嘗試失敗:`, e);
|
|
1538
|
+
}
|
|
1539
|
+
// 如果不是最後一次嘗試,等待後重試
|
|
1540
|
+
if (attempt < maxAttempts) {
|
|
1541
|
+
yield new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
// 所有嘗試都失敗
|
|
1545
|
+
const finalSettings = videoTrack.getSettings();
|
|
1546
|
+
console.warn(`⚠️ 達到最大重試次數,使用當前解析度: ${finalSettings.width}x${finalSettings.height}`);
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1548
1549
|
function switchCamera(deviceId, video) {
|
|
1549
|
-
var _a, _b
|
|
1550
|
+
var _a, _b;
|
|
1550
1551
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1551
1552
|
const startTime = performance.now();
|
|
1552
1553
|
try {
|
|
@@ -1562,104 +1563,20 @@ function switchCamera(deviceId, video) {
|
|
|
1562
1563
|
};
|
|
1563
1564
|
const constraint = localStorage.getItem('camera_constraint');
|
|
1564
1565
|
stream = yield navigator.mediaDevices.getUserMedia(basicConstraints);
|
|
1565
|
-
// 第二階段:等待就緒策略 + 漸進式重試提升解析度
|
|
1566
1566
|
if (!constraint && stream) {
|
|
1567
1567
|
const videoTrack = stream.getVideoTracks()[0];
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
max: 2160
|
|
1581
|
-
}
|
|
1582
|
-
};
|
|
1583
|
-
const maxRetries = 3;
|
|
1584
|
-
const delays = [0, 100, 300]; // 第一次立即嘗試,後續間隔遞增
|
|
1585
|
-
const minAcceptableWidth = 1280; // 最低可接受的解析度寬度
|
|
1586
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
1587
|
-
try {
|
|
1588
|
-
if (delays[attempt] > 0) {
|
|
1589
|
-
yield new Promise(resolve => setTimeout(resolve, delays[attempt]));
|
|
1590
|
-
}
|
|
1591
|
-
const beforeSettings = videoTrack.getSettings();
|
|
1592
|
-
yield videoTrack.applyConstraints(targetConstraints);
|
|
1593
|
-
// ⚠️ 關鍵:驗證解析度是否真的改變
|
|
1594
|
-
const afterSettings = videoTrack.getSettings();
|
|
1595
|
-
const afterWidth = (_a = afterSettings.width) !== null && _a !== void 0 ? _a : 0;
|
|
1596
|
-
const beforeWidth = (_b = beforeSettings.width) !== null && _b !== void 0 ? _b : 0;
|
|
1597
|
-
// 成功條件:
|
|
1598
|
-
// 1. 如果初始解析度 < 最低標準 → 必須提升且達到最低標準
|
|
1599
|
-
// 2. 如果初始解析度 >= 最低標準 → 只要有提升就算成功
|
|
1600
|
-
const needsImprovement = beforeWidth < minAcceptableWidth;
|
|
1601
|
-
const resolutionImproved = needsImprovement ? afterWidth > beforeWidth && afterWidth >= minAcceptableWidth : afterWidth > beforeWidth;
|
|
1602
|
-
if (resolutionImproved) {
|
|
1603
|
-
console.log(`✅ 解析度提升成功 (嘗試 ${attempt + 1}/${maxRetries})`, {
|
|
1604
|
-
before: `${beforeWidth}x${beforeSettings.height}`,
|
|
1605
|
-
after: `${afterWidth}x${afterSettings.height}`,
|
|
1606
|
-
deviceLabel: videoTrack.label
|
|
1607
|
-
});
|
|
1608
|
-
break; // 真正成功才跳出
|
|
1609
|
-
} else {
|
|
1610
|
-
// applyConstraints 沒報錯,但解析度沒變 → 視為失敗,觸發重試
|
|
1611
|
-
console.warn(`⚠️ 解析度未改善 (嘗試 ${attempt + 1}/${maxRetries})`, {
|
|
1612
|
-
before: `${beforeWidth}x${beforeSettings.height}`,
|
|
1613
|
-
after: `${afterWidth}x${afterSettings.height}`,
|
|
1614
|
-
expected: needsImprovement ? `>= ${minAcceptableWidth}` : '任何提升'
|
|
1615
|
-
});
|
|
1616
|
-
if (attempt === maxRetries - 1) {
|
|
1617
|
-
console.warn(`⚠️ 達到最大重試次數,使用當前解析度 (${afterWidth}x${afterSettings.height})`);
|
|
1618
|
-
} else {
|
|
1619
|
-
// 繼續重試
|
|
1620
|
-
continue;
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
} catch (error) {
|
|
1624
|
-
if (attempt === maxRetries - 1) {
|
|
1625
|
-
// 最後一次嘗試失敗,記錄警告但不影響功能
|
|
1626
|
-
const settings = videoTrack.getSettings();
|
|
1627
|
-
console.warn(`⚠️ 無法提升解析度,使用基本設定 (${settings.width}x${settings.height})`, error);
|
|
1628
|
-
} else {
|
|
1629
|
-
console.log(`⏳ 解析度提升嘗試 ${attempt + 1} 失敗,準備重試...`, error);
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
} else {
|
|
1634
|
-
// Camera未完全就緒,但仍嘗試套用約束
|
|
1635
|
-
console.warn('⚠️ Camera未完全就緒,嘗試套用解析度約束...');
|
|
1636
|
-
try {
|
|
1637
|
-
yield videoTrack.applyConstraints({
|
|
1638
|
-
width: {
|
|
1639
|
-
ideal: 1920,
|
|
1640
|
-
max: 3840
|
|
1641
|
-
},
|
|
1642
|
-
height: {
|
|
1643
|
-
ideal: 1080,
|
|
1644
|
-
max: 2160
|
|
1645
|
-
}
|
|
1646
|
-
});
|
|
1647
|
-
} catch (error) {
|
|
1648
|
-
console.warn('⚠️ 解析度提升失敗,使用預設解析度', error);
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
// 🆕 記錄最終解析度資訊
|
|
1652
|
-
const finalSettings = videoTrack.getSettings();
|
|
1653
|
-
const initTime = (performance.now() - startTime).toFixed(2);
|
|
1654
|
-
console.log('📹 Camera初始化完成', {
|
|
1655
|
-
deviceId,
|
|
1656
|
-
deviceLabel: videoTrack.label,
|
|
1657
|
-
resolution: `${finalSettings.width}x${finalSettings.height}`,
|
|
1658
|
-
frameRate: finalSettings.frameRate,
|
|
1659
|
-
facingMode: finalSettings.facingMode,
|
|
1660
|
-
initTime: `${initTime}ms`
|
|
1661
|
-
});
|
|
1662
|
-
}
|
|
1568
|
+
yield upgradeResolution(videoTrack); // ✅ 加上 await 等待解析度提升完成
|
|
1569
|
+
// 🆕 記錄最終解析度資訊
|
|
1570
|
+
const finalSettings = videoTrack.getSettings();
|
|
1571
|
+
const initTime = (performance.now() - startTime).toFixed(2);
|
|
1572
|
+
console.log('📹 Camera初始化完成', {
|
|
1573
|
+
deviceId,
|
|
1574
|
+
deviceLabel: videoTrack.label,
|
|
1575
|
+
resolution: `${finalSettings.width}x${finalSettings.height}`,
|
|
1576
|
+
frameRate: finalSettings.frameRate,
|
|
1577
|
+
facingMode: finalSettings.facingMode,
|
|
1578
|
+
initTime: `${initTime}ms`
|
|
1579
|
+
});
|
|
1663
1580
|
}
|
|
1664
1581
|
// try {
|
|
1665
1582
|
// stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
@@ -1713,7 +1630,7 @@ function switchCamera(deviceId, video) {
|
|
|
1713
1630
|
errorMessage: e === null || e === void 0 ? void 0 : e.message,
|
|
1714
1631
|
initTime: `${initTime}ms`,
|
|
1715
1632
|
streamExists: !!stream,
|
|
1716
|
-
trackCount: (
|
|
1633
|
+
trackCount: (_b = (_a = stream === null || stream === void 0 ? void 0 : stream.getTracks()) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0
|
|
1717
1634
|
});
|
|
1718
1635
|
throw new AuthmeError(exports.ErrorCode.CAMERA_NOT_SUPPORT, e);
|
|
1719
1636
|
}
|
|
@@ -3397,8 +3314,8 @@ const themeConfigDefault = {
|
|
|
3397
3314
|
};
|
|
3398
3315
|
|
|
3399
3316
|
var name = "authme/sdk";
|
|
3400
|
-
var version$1 = "2.8.
|
|
3401
|
-
var date = "2025-11-
|
|
3317
|
+
var version$1 = "2.8.32";
|
|
3318
|
+
var date = "2025-11-07T03:04:15+0000";
|
|
3402
3319
|
var packageInfo = {
|
|
3403
3320
|
name: name,
|
|
3404
3321
|
version: version$1,
|
package/index.js
CHANGED
|
@@ -1438,50 +1438,6 @@ const videoConstraintsFactory = (isPC, facingMode) => {
|
|
|
1438
1438
|
}
|
|
1439
1439
|
};
|
|
1440
1440
|
};
|
|
1441
|
-
/**
|
|
1442
|
-
* 等待camera完全就緒
|
|
1443
|
-
* 用於解決外接camera初始化延遲問題
|
|
1444
|
-
* @param videoTrack - MediaStreamTrack 實例
|
|
1445
|
-
* @param maxWaitMs - 最大等待時間(毫秒)
|
|
1446
|
-
* @returns Promise<boolean> - true表示camera已就緒,false表示超時
|
|
1447
|
-
*/
|
|
1448
|
-
function waitForCameraReady(videoTrack, maxWaitMs = 100) {
|
|
1449
|
-
var _a, _b, _c, _d;
|
|
1450
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1451
|
-
const startTime = Date.now();
|
|
1452
|
-
const checkInterval = 50; // 每50ms檢查一次
|
|
1453
|
-
const minStableTime = 50; // 最小穩定時間:即使檢測到就緒,也要等待一小段時間
|
|
1454
|
-
while (Date.now() - startTime < maxWaitMs) {
|
|
1455
|
-
const _settings = videoTrack.getSettings();
|
|
1456
|
-
const capabilities = (_a = videoTrack.getCapabilities) === null || _a === void 0 ? void 0 : _a.call(videoTrack);
|
|
1457
|
-
// 檢查camera是否已提供完整資訊
|
|
1458
|
-
// 1. 必須有基本的寬高設定
|
|
1459
|
-
// 2. 如果支援 getCapabilities,確認有最大解析度資訊
|
|
1460
|
-
const hasBasicSettings = _settings.width && _settings.height;
|
|
1461
|
-
const hasCapabilities = !capabilities || ((_b = capabilities === null || capabilities === void 0 ? void 0 : capabilities.width) === null || _b === void 0 ? void 0 : _b.max) && ((_c = capabilities === null || capabilities === void 0 ? void 0 : capabilities.height) === null || _c === void 0 ? void 0 : _c.max);
|
|
1462
|
-
if (hasBasicSettings && hasCapabilities) {
|
|
1463
|
-
const elapsedTime = Date.now() - startTime;
|
|
1464
|
-
// ⚠️ 關鍵修正:即使檢測到就緒,也要確保經過最小等待時間
|
|
1465
|
-
// 這對外接相機特別重要,它們需要額外的硬體初始化時間
|
|
1466
|
-
if (elapsedTime < minStableTime) {
|
|
1467
|
-
const remainingTime = minStableTime - elapsedTime;
|
|
1468
|
-
console.log(`⏳ Camera基本就緒,額外等待 ${remainingTime}ms 確保穩定 (當前: ${_settings.width}x${_settings.height})`);
|
|
1469
|
-
yield new Promise(resolve => setTimeout(resolve, remainingTime));
|
|
1470
|
-
}
|
|
1471
|
-
console.log(`✅ Camera就緒 (耗時: ${Date.now() - startTime}ms, 解析度: ${_settings.width}x${_settings.height})`);
|
|
1472
|
-
return true;
|
|
1473
|
-
}
|
|
1474
|
-
yield new Promise(resolve => setTimeout(resolve, checkInterval));
|
|
1475
|
-
}
|
|
1476
|
-
const settings = videoTrack.getSettings();
|
|
1477
|
-
console.warn(`⚠️ Camera未在時限內完全就緒 (${maxWaitMs}ms), 當前狀態:`, {
|
|
1478
|
-
width: settings.width,
|
|
1479
|
-
height: settings.height,
|
|
1480
|
-
hasCapabilities: !!((_d = videoTrack.getCapabilities) === null || _d === void 0 ? void 0 : _d.call(videoTrack))
|
|
1481
|
-
});
|
|
1482
|
-
return false;
|
|
1483
|
-
});
|
|
1484
|
-
}
|
|
1485
1441
|
function inferFacingModeFromLabel(label) {
|
|
1486
1442
|
const pattern = /rear|back|rück|arrière|trasera|trás|traseira|posteriore|后|後|背|задней|الخلفية|후|arka|achterzijde|หลัง|baksidan|bagside|sau|bak|tylny|takakamera|belakang|אחורית|πίσω|spate|hátsó|zadní|darrere|zadná|задня|stražnja|belakang|बैक/i;
|
|
1487
1443
|
if (pattern.test(label !== null && label !== void 0 ? label : '')) {
|
|
@@ -1535,8 +1491,53 @@ function arrayFromAsync(asyncIterable) {
|
|
|
1535
1491
|
return result;
|
|
1536
1492
|
});
|
|
1537
1493
|
}
|
|
1494
|
+
function upgradeResolution(videoTrack) {
|
|
1495
|
+
var _a;
|
|
1496
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1497
|
+
const targetConstraints = {
|
|
1498
|
+
width: {
|
|
1499
|
+
ideal: 1920,
|
|
1500
|
+
max: 3840
|
|
1501
|
+
},
|
|
1502
|
+
height: {
|
|
1503
|
+
ideal: 1080,
|
|
1504
|
+
max: 2160
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
const minAcceptableWidth = 1280; // 最低可接受的解析度寬度
|
|
1508
|
+
const maxAttempts = 300; // 最多嘗試10次
|
|
1509
|
+
const retryDelay = 100; // 每次重試間隔1秒
|
|
1510
|
+
console.log('🚀 開始提升解析度...');
|
|
1511
|
+
const startTime = Date.now();
|
|
1512
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1513
|
+
try {
|
|
1514
|
+
yield videoTrack.applyConstraints(targetConstraints);
|
|
1515
|
+
const settings = videoTrack.getSettings();
|
|
1516
|
+
const currentWidth = (_a = settings.width) !== null && _a !== void 0 ? _a : 0;
|
|
1517
|
+
console.log(`嘗試 ${attempt}/${maxAttempts} - 解析度: ${currentWidth}x${settings.height}`);
|
|
1518
|
+
// 檢查是否達到可接受的解析度
|
|
1519
|
+
if (currentWidth >= minAcceptableWidth) {
|
|
1520
|
+
const elapsedTime = Date.now() - startTime;
|
|
1521
|
+
console.log(`✅ 解析度提升成功!最終: ${currentWidth}x${settings.height} (耗時: ${elapsedTime}ms)`);
|
|
1522
|
+
return; // 成功,退出
|
|
1523
|
+
}
|
|
1524
|
+
// 解析度還不夠,繼續重試
|
|
1525
|
+
console.log(`⚠️ 解析度 ${currentWidth} < ${minAcceptableWidth},繼續重試...`);
|
|
1526
|
+
} catch (e) {
|
|
1527
|
+
console.warn(`⚠️ 第 ${attempt} 次嘗試失敗:`, e);
|
|
1528
|
+
}
|
|
1529
|
+
// 如果不是最後一次嘗試,等待後重試
|
|
1530
|
+
if (attempt < maxAttempts) {
|
|
1531
|
+
yield new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
// 所有嘗試都失敗
|
|
1535
|
+
const finalSettings = videoTrack.getSettings();
|
|
1536
|
+
console.warn(`⚠️ 達到最大重試次數,使用當前解析度: ${finalSettings.width}x${finalSettings.height}`);
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1538
1539
|
function switchCamera(deviceId, video) {
|
|
1539
|
-
var _a, _b
|
|
1540
|
+
var _a, _b;
|
|
1540
1541
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1541
1542
|
const startTime = performance.now();
|
|
1542
1543
|
try {
|
|
@@ -1552,104 +1553,20 @@ function switchCamera(deviceId, video) {
|
|
|
1552
1553
|
};
|
|
1553
1554
|
const constraint = localStorage.getItem('camera_constraint');
|
|
1554
1555
|
stream = yield navigator.mediaDevices.getUserMedia(basicConstraints);
|
|
1555
|
-
// 第二階段:等待就緒策略 + 漸進式重試提升解析度
|
|
1556
1556
|
if (!constraint && stream) {
|
|
1557
1557
|
const videoTrack = stream.getVideoTracks()[0];
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
max: 2160
|
|
1571
|
-
}
|
|
1572
|
-
};
|
|
1573
|
-
const maxRetries = 3;
|
|
1574
|
-
const delays = [0, 100, 300]; // 第一次立即嘗試,後續間隔遞增
|
|
1575
|
-
const minAcceptableWidth = 1280; // 最低可接受的解析度寬度
|
|
1576
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
1577
|
-
try {
|
|
1578
|
-
if (delays[attempt] > 0) {
|
|
1579
|
-
yield new Promise(resolve => setTimeout(resolve, delays[attempt]));
|
|
1580
|
-
}
|
|
1581
|
-
const beforeSettings = videoTrack.getSettings();
|
|
1582
|
-
yield videoTrack.applyConstraints(targetConstraints);
|
|
1583
|
-
// ⚠️ 關鍵:驗證解析度是否真的改變
|
|
1584
|
-
const afterSettings = videoTrack.getSettings();
|
|
1585
|
-
const afterWidth = (_a = afterSettings.width) !== null && _a !== void 0 ? _a : 0;
|
|
1586
|
-
const beforeWidth = (_b = beforeSettings.width) !== null && _b !== void 0 ? _b : 0;
|
|
1587
|
-
// 成功條件:
|
|
1588
|
-
// 1. 如果初始解析度 < 最低標準 → 必須提升且達到最低標準
|
|
1589
|
-
// 2. 如果初始解析度 >= 最低標準 → 只要有提升就算成功
|
|
1590
|
-
const needsImprovement = beforeWidth < minAcceptableWidth;
|
|
1591
|
-
const resolutionImproved = needsImprovement ? afterWidth > beforeWidth && afterWidth >= minAcceptableWidth : afterWidth > beforeWidth;
|
|
1592
|
-
if (resolutionImproved) {
|
|
1593
|
-
console.log(`✅ 解析度提升成功 (嘗試 ${attempt + 1}/${maxRetries})`, {
|
|
1594
|
-
before: `${beforeWidth}x${beforeSettings.height}`,
|
|
1595
|
-
after: `${afterWidth}x${afterSettings.height}`,
|
|
1596
|
-
deviceLabel: videoTrack.label
|
|
1597
|
-
});
|
|
1598
|
-
break; // 真正成功才跳出
|
|
1599
|
-
} else {
|
|
1600
|
-
// applyConstraints 沒報錯,但解析度沒變 → 視為失敗,觸發重試
|
|
1601
|
-
console.warn(`⚠️ 解析度未改善 (嘗試 ${attempt + 1}/${maxRetries})`, {
|
|
1602
|
-
before: `${beforeWidth}x${beforeSettings.height}`,
|
|
1603
|
-
after: `${afterWidth}x${afterSettings.height}`,
|
|
1604
|
-
expected: needsImprovement ? `>= ${minAcceptableWidth}` : '任何提升'
|
|
1605
|
-
});
|
|
1606
|
-
if (attempt === maxRetries - 1) {
|
|
1607
|
-
console.warn(`⚠️ 達到最大重試次數,使用當前解析度 (${afterWidth}x${afterSettings.height})`);
|
|
1608
|
-
} else {
|
|
1609
|
-
// 繼續重試
|
|
1610
|
-
continue;
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
} catch (error) {
|
|
1614
|
-
if (attempt === maxRetries - 1) {
|
|
1615
|
-
// 最後一次嘗試失敗,記錄警告但不影響功能
|
|
1616
|
-
const settings = videoTrack.getSettings();
|
|
1617
|
-
console.warn(`⚠️ 無法提升解析度,使用基本設定 (${settings.width}x${settings.height})`, error);
|
|
1618
|
-
} else {
|
|
1619
|
-
console.log(`⏳ 解析度提升嘗試 ${attempt + 1} 失敗,準備重試...`, error);
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
} else {
|
|
1624
|
-
// Camera未完全就緒,但仍嘗試套用約束
|
|
1625
|
-
console.warn('⚠️ Camera未完全就緒,嘗試套用解析度約束...');
|
|
1626
|
-
try {
|
|
1627
|
-
yield videoTrack.applyConstraints({
|
|
1628
|
-
width: {
|
|
1629
|
-
ideal: 1920,
|
|
1630
|
-
max: 3840
|
|
1631
|
-
},
|
|
1632
|
-
height: {
|
|
1633
|
-
ideal: 1080,
|
|
1634
|
-
max: 2160
|
|
1635
|
-
}
|
|
1636
|
-
});
|
|
1637
|
-
} catch (error) {
|
|
1638
|
-
console.warn('⚠️ 解析度提升失敗,使用預設解析度', error);
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
// 🆕 記錄最終解析度資訊
|
|
1642
|
-
const finalSettings = videoTrack.getSettings();
|
|
1643
|
-
const initTime = (performance.now() - startTime).toFixed(2);
|
|
1644
|
-
console.log('📹 Camera初始化完成', {
|
|
1645
|
-
deviceId,
|
|
1646
|
-
deviceLabel: videoTrack.label,
|
|
1647
|
-
resolution: `${finalSettings.width}x${finalSettings.height}`,
|
|
1648
|
-
frameRate: finalSettings.frameRate,
|
|
1649
|
-
facingMode: finalSettings.facingMode,
|
|
1650
|
-
initTime: `${initTime}ms`
|
|
1651
|
-
});
|
|
1652
|
-
}
|
|
1558
|
+
yield upgradeResolution(videoTrack); // ✅ 加上 await 等待解析度提升完成
|
|
1559
|
+
// 🆕 記錄最終解析度資訊
|
|
1560
|
+
const finalSettings = videoTrack.getSettings();
|
|
1561
|
+
const initTime = (performance.now() - startTime).toFixed(2);
|
|
1562
|
+
console.log('📹 Camera初始化完成', {
|
|
1563
|
+
deviceId,
|
|
1564
|
+
deviceLabel: videoTrack.label,
|
|
1565
|
+
resolution: `${finalSettings.width}x${finalSettings.height}`,
|
|
1566
|
+
frameRate: finalSettings.frameRate,
|
|
1567
|
+
facingMode: finalSettings.facingMode,
|
|
1568
|
+
initTime: `${initTime}ms`
|
|
1569
|
+
});
|
|
1653
1570
|
}
|
|
1654
1571
|
// try {
|
|
1655
1572
|
// stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
@@ -1703,7 +1620,7 @@ function switchCamera(deviceId, video) {
|
|
|
1703
1620
|
errorMessage: e === null || e === void 0 ? void 0 : e.message,
|
|
1704
1621
|
initTime: `${initTime}ms`,
|
|
1705
1622
|
streamExists: !!stream,
|
|
1706
|
-
trackCount: (
|
|
1623
|
+
trackCount: (_b = (_a = stream === null || stream === void 0 ? void 0 : stream.getTracks()) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0
|
|
1707
1624
|
});
|
|
1708
1625
|
throw new AuthmeError(ErrorCode.CAMERA_NOT_SUPPORT, e);
|
|
1709
1626
|
}
|
|
@@ -3387,8 +3304,8 @@ const themeConfigDefault = {
|
|
|
3387
3304
|
};
|
|
3388
3305
|
|
|
3389
3306
|
var name = "authme/sdk";
|
|
3390
|
-
var version$1 = "2.8.
|
|
3391
|
-
var date = "2025-11-
|
|
3307
|
+
var version$1 = "2.8.32";
|
|
3308
|
+
var date = "2025-11-07T03:04:15+0000";
|
|
3392
3309
|
var packageInfo = {
|
|
3393
3310
|
name: name,
|
|
3394
3311
|
version: version$1,
|