扫一扫音频提示音
This commit is contained in:
@@ -89,8 +89,8 @@ interface ScanConfigOptions {
|
||||
webScanType?: ("qrCode" | "barCode")[];
|
||||
webScanVideoMirror?: boolean;
|
||||
webScanVideoMirrorVertical?: boolean;
|
||||
webScanBeepAudio?: string;
|
||||
webScanBeepEnabled?: boolean;
|
||||
scanBeepAudio?: string;
|
||||
scanBeepEnabled?: boolean;
|
||||
initWechatJssdk?: {
|
||||
apiUrl?: string;
|
||||
sdkConfig?: {
|
||||
@@ -120,8 +120,8 @@ interface ScanConfigOptions {
|
||||
| `webScanType` | WebScan 扫码类型 | `["qrCode", "barCode"]` |
|
||||
| `webScanVideoMirror` | WebScan 视频是否水平镜像;不配置时自动判断:前置/PC 镜像,后置不镜像 | 自动 |
|
||||
| `webScanVideoMirrorVertical` | WebScan 视频是否垂直镜像 | `false` |
|
||||
| `webScanBeepAudio` | WebScan 扫码成功提示音地址 | 内置提示音 |
|
||||
| `webScanBeepEnabled` | WebScan 扫码成功是否播放提示音 | `true` |
|
||||
| `scanBeepAudio` | 扫码成功提示音地址(任意模式匹配成功时播放) | 内置提示音 |
|
||||
| `scanBeepEnabled` | 扫码成功是否播放提示音 | `true` |
|
||||
| `initWechatJssdk` | 微信 JSSDK 初始化配置,仅微信环境生效 | 无 |
|
||||
|
||||
`initWechatJssdk` 子配置:
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
webScanEnabled: true,
|
||||
webScanCanvasEnabled: true,
|
||||
webScanCloseButtonStyle: "background: rgba(27, 99, 244, 0.88);",
|
||||
webScanBeepEnabled: true,
|
||||
scanBeepEnabled: true,
|
||||
initWechatJssdk: {
|
||||
apiUrl: "https://your-domain.com/wechat/jssdk-config"
|
||||
}
|
||||
@@ -321,7 +321,7 @@ IScan.stopScan();</pre>
|
||||
initSDK({
|
||||
webScanCanvasEnabled: true,
|
||||
webScanCloseButtonStyle: "background: rgba(27, 99, 244, 0.88);",
|
||||
webScanBeepEnabled: true,
|
||||
scanBeepEnabled: true,
|
||||
initWechatJssdk: { apiUrl: url }
|
||||
}, function () {
|
||||
setStatus(IScan.getStatus());
|
||||
|
||||
8
dist/index.d.ts
vendored
8
dist/index.d.ts
vendored
@@ -90,13 +90,13 @@ interface ScanConfigOptions {
|
||||
*/
|
||||
webScanVideoMirrorVertical?: boolean,
|
||||
/**
|
||||
* 网页扫码成功提示音地址,默认使用内置提示音
|
||||
* 扫码成功提示音地址,默认使用内置提示音;任意识别模式匹配成功时播放
|
||||
*/
|
||||
webScanBeepAudio?: string,
|
||||
scanBeepAudio?: string,
|
||||
/**
|
||||
* 网页扫码成功提示音是否启用,默认启用
|
||||
* 扫码成功是否播放提示音,默认启用;任意识别模式匹配成功时生效
|
||||
*/
|
||||
webScanBeepEnabled?: boolean,
|
||||
scanBeepEnabled?: boolean,
|
||||
/**
|
||||
* 微信JSSDK配置,微信环境才会生效,配置后会自动初始化微信JSSDK
|
||||
*/
|
||||
|
||||
4
dist/index.html
vendored
4
dist/index.html
vendored
@@ -165,7 +165,7 @@
|
||||
webScanEnabled: true,
|
||||
webScanCanvasEnabled: true,
|
||||
webScanCloseButtonStyle: "background: rgba(27, 99, 244, 0.88);",
|
||||
webScanBeepEnabled: true,
|
||||
scanBeepEnabled: true,
|
||||
initWechatJssdk: {
|
||||
apiUrl: "https://your-domain.com/wechat/jssdk-config"
|
||||
}
|
||||
@@ -251,7 +251,7 @@ IScan.stopScan();</pre></section></main><script>(function () {
|
||||
initSDK({
|
||||
webScanCanvasEnabled: true,
|
||||
webScanCloseButtonStyle: "background: rgba(27, 99, 244, 0.88);",
|
||||
webScanBeepEnabled: true,
|
||||
scanBeepEnabled: true,
|
||||
initWechatJssdk: { apiUrl: url }
|
||||
}, function () {
|
||||
setStatus(IScan.getStatus());
|
||||
|
||||
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
8
dist/index.md
vendored
8
dist/index.md
vendored
@@ -89,8 +89,8 @@ interface ScanConfigOptions {
|
||||
webScanType?: ("qrCode" | "barCode")[];
|
||||
webScanVideoMirror?: boolean;
|
||||
webScanVideoMirrorVertical?: boolean;
|
||||
webScanBeepAudio?: string;
|
||||
webScanBeepEnabled?: boolean;
|
||||
scanBeepAudio?: string;
|
||||
scanBeepEnabled?: boolean;
|
||||
initWechatJssdk?: {
|
||||
apiUrl?: string;
|
||||
sdkConfig?: {
|
||||
@@ -120,8 +120,8 @@ interface ScanConfigOptions {
|
||||
| `webScanType` | WebScan 扫码类型 | `["qrCode", "barCode"]` |
|
||||
| `webScanVideoMirror` | WebScan 视频是否水平镜像;不配置时自动判断:前置/PC 镜像,后置不镜像 | 自动 |
|
||||
| `webScanVideoMirrorVertical` | WebScan 视频是否垂直镜像 | `false` |
|
||||
| `webScanBeepAudio` | WebScan 扫码成功提示音地址 | 内置提示音 |
|
||||
| `webScanBeepEnabled` | WebScan 扫码成功是否播放提示音 | `true` |
|
||||
| `scanBeepAudio` | 扫码成功提示音地址(任意模式匹配成功时播放) | 内置提示音 |
|
||||
| `scanBeepEnabled` | 扫码成功是否播放提示音 | `true` |
|
||||
| `initWechatJssdk` | 微信 JSSDK 初始化配置,仅微信环境生效 | 无 |
|
||||
|
||||
`initWechatJssdk` 子配置:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { inRuntime, bridgeAsync } from "../bridge";
|
||||
import { isSupportWebScan, startScanForWeb, stopScanForWeb, isSupportImageScan, startScanForImage, unlockScanBeep } from "../web";
|
||||
import { isSupportWebScan, startScanForWeb, stopScanForWeb, isSupportImageScan, startScanForImage, unlockScanBeep, playScanBeep } from "../web";
|
||||
import { isSupportWxScan, startScanForWx } from "../wx";
|
||||
import { startScanner, stopScanner } from "../scanner";
|
||||
import { getConfig } from "../config";
|
||||
@@ -105,6 +105,7 @@ function __result(result) {
|
||||
}
|
||||
}
|
||||
if (matched) {
|
||||
playScanBeep();
|
||||
_scan_next_start_time = Date.now() + getScanRestartDelay();
|
||||
}
|
||||
return matched;
|
||||
@@ -401,6 +402,7 @@ export function startScan() {
|
||||
if (isScanning() || _scan_closing || Date.now() < _scan_next_start_time) {
|
||||
return;
|
||||
}
|
||||
unlockScanBeep();
|
||||
Promise.resolve().then(() => {
|
||||
__scanning();
|
||||
let scannerPromise = new Promise(resolve => {
|
||||
@@ -412,7 +414,6 @@ export function startScan() {
|
||||
} else if (isSupportWxScan()) {
|
||||
scanPromise = __startWxScan();
|
||||
} else if (isSupportWebScan()) {
|
||||
unlockScanBeep();
|
||||
scanPromise = startScanForWeb(__result);
|
||||
} else if (isSupportImageScan()) {
|
||||
scanPromise = __startImageScan();
|
||||
@@ -456,6 +457,7 @@ export function scanImage() {
|
||||
if (isScanning() || _scan_closing || Date.now() < _scan_next_start_time) {
|
||||
return;
|
||||
}
|
||||
unlockScanBeep();
|
||||
Promise.resolve().then(() => {
|
||||
__scanning();
|
||||
return startScanForImage().then(resp => {
|
||||
|
||||
@@ -31,6 +31,7 @@ let barcodeDetectorPreparePromise = null;
|
||||
let scanBeepAudioEl = null;
|
||||
let scanBeepAudioSrc = null;
|
||||
let scanBeepUnlocked = false;
|
||||
let scanBeepGestureUnlockInstalled = false;
|
||||
|
||||
function removeEl(id, uuid) {
|
||||
try {
|
||||
@@ -305,8 +306,37 @@ function drawBarcode(context, width, height, barcode, mirrorHorizontal, mirrorVe
|
||||
}
|
||||
}
|
||||
|
||||
function playScanBeep() {
|
||||
if (getConfig("webScanBeepEnabled") === false) {
|
||||
function isScanBeepEnabled() {
|
||||
return getConfig("scanBeepEnabled") !== false;
|
||||
}
|
||||
|
||||
function getScanBeepAudioSrc() {
|
||||
return getConfig("scanBeepAudio") || DEFAULT_SCAN_BEEP_AUDIO;
|
||||
}
|
||||
|
||||
function resetScanBeepPlayback(audio) {
|
||||
try {
|
||||
audio.pause();
|
||||
audio.currentTime = 0;
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
function installScanBeepGestureUnlock() {
|
||||
if (scanBeepGestureUnlockInstalled || typeof document === "undefined" || !isScanBeepEnabled()) {
|
||||
return;
|
||||
}
|
||||
scanBeepGestureUnlockInstalled = true;
|
||||
const onGesture = () => {
|
||||
unlockScanBeep();
|
||||
};
|
||||
document.addEventListener("click", onGesture, true);
|
||||
document.addEventListener("touchstart", onGesture, true);
|
||||
document.addEventListener("keydown", onGesture, true);
|
||||
}
|
||||
|
||||
export function playScanBeep() {
|
||||
if (!isScanBeepEnabled()) {
|
||||
return;
|
||||
}
|
||||
const audio = getScanBeepAudio();
|
||||
@@ -318,15 +348,17 @@ function playScanBeep() {
|
||||
audio.volume = 1;
|
||||
audio.currentTime = 0;
|
||||
const playPromise = audio.play();
|
||||
playPromise && playPromise.catch && playPromise.catch(() => {
|
||||
// no thing
|
||||
playPromise && playPromise.catch && playPromise.catch(err => {
|
||||
if (err && err.name === "NotAllowedError") {
|
||||
scanBeepUnlocked = false;
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
function getScanBeepAudio() {
|
||||
const audioSrc = getConfig("webScanBeepAudio") || DEFAULT_SCAN_BEEP_AUDIO;
|
||||
const audioSrc = getScanBeepAudioSrc();
|
||||
if (!audioSrc || typeof Audio === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
@@ -340,22 +372,48 @@ function getScanBeepAudio() {
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
installScanBeepGestureUnlock();
|
||||
return scanBeepAudioEl;
|
||||
}
|
||||
|
||||
export function unlockScanBeep() {
|
||||
if (getConfig("webScanBeepEnabled") === false || scanBeepUnlocked) {
|
||||
if (!isScanBeepEnabled() || scanBeepUnlocked) {
|
||||
return;
|
||||
}
|
||||
const audio = getScanBeepAudio();
|
||||
if (!audio) {
|
||||
return;
|
||||
}
|
||||
const prevMuted = audio.muted;
|
||||
const prevVolume = audio.volume;
|
||||
try {
|
||||
// 这里只做预加载,不主动 play,避免部分浏览器露出提示音。
|
||||
audio.load && audio.load();
|
||||
scanBeepUnlocked = true;
|
||||
audio.muted = true;
|
||||
audio.volume = 0;
|
||||
audio.currentTime = 0;
|
||||
const playPromise = audio.play();
|
||||
if (!playPromise || !playPromise.then) {
|
||||
resetScanBeepPlayback(audio);
|
||||
audio.muted = prevMuted;
|
||||
audio.volume = prevVolume;
|
||||
scanBeepUnlocked = true;
|
||||
return;
|
||||
}
|
||||
playPromise.then(() => {
|
||||
resetScanBeepPlayback(audio);
|
||||
audio.muted = prevMuted;
|
||||
audio.volume = prevVolume;
|
||||
scanBeepUnlocked = true;
|
||||
}).catch(() => {
|
||||
resetScanBeepPlayback(audio);
|
||||
audio.muted = prevMuted;
|
||||
audio.volume = prevVolume;
|
||||
});
|
||||
} catch (e) {
|
||||
try {
|
||||
audio.muted = prevMuted;
|
||||
audio.volume = prevVolume;
|
||||
} catch (_e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,6 +454,7 @@ function chooseImageFile() {
|
||||
};
|
||||
input.id = "__webscan_image_input__";
|
||||
input.onchange = () => {
|
||||
unlockScanBeep();
|
||||
finish(input.files && input.files[0]);
|
||||
};
|
||||
input.oncancel = () => {
|
||||
@@ -579,6 +638,7 @@ export function startScanForWeb(onResult) {
|
||||
if (scanWeb.uuid !== currentUuid || closed) {
|
||||
return;
|
||||
}
|
||||
unlockScanBeep();
|
||||
chooseImageFile().then(file => {
|
||||
if (!file || scanWeb.uuid !== currentUuid || closed) {
|
||||
return;
|
||||
@@ -590,7 +650,6 @@ export function startScanForWeb(onResult) {
|
||||
if (!onResult || !onResult(code.rawValue)) {
|
||||
return;
|
||||
}
|
||||
playScanBeep();
|
||||
scanWeb.uuid = null;
|
||||
scanWeb.finish = true;
|
||||
close();
|
||||
@@ -637,7 +696,6 @@ export function startScanForWeb(onResult) {
|
||||
return;
|
||||
}
|
||||
drawBarcode(context, canvasEl.width, canvasEl.height, code, mirrorVideo, mirrorVideoVertical, cover);
|
||||
playScanBeep();
|
||||
scanWeb.uuid = null;
|
||||
scanWeb.finish = true;
|
||||
close();
|
||||
|
||||
8
types/index.d.ts
vendored
8
types/index.d.ts
vendored
@@ -90,13 +90,13 @@ interface ScanConfigOptions {
|
||||
*/
|
||||
webScanVideoMirrorVertical?: boolean,
|
||||
/**
|
||||
* 网页扫码成功提示音地址,默认使用内置提示音
|
||||
* 扫码成功提示音地址,默认使用内置提示音;任意识别模式匹配成功时播放
|
||||
*/
|
||||
webScanBeepAudio?: string,
|
||||
scanBeepAudio?: string,
|
||||
/**
|
||||
* 网页扫码成功提示音是否启用,默认启用
|
||||
* 扫码成功是否播放提示音,默认启用;任意识别模式匹配成功时生效
|
||||
*/
|
||||
webScanBeepEnabled?: boolean,
|
||||
scanBeepEnabled?: boolean,
|
||||
/**
|
||||
* 微信JSSDK配置,微信环境才会生效,配置后会自动初始化微信JSSDK
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user