扫一扫音频提示音

This commit is contained in:
iqudoo
2026-05-25 20:37:49 +08:00
parent 6663fd6ab4
commit f52b9f3518
9 changed files with 94 additions and 34 deletions

View File

@@ -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 => {

View File

@@ -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();