jsios/scan.html

63 lines
2.9 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ru">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Live Scanner</title>
<style>
body{margin:0;background:#0b0b0b;color:#eee;font-family:-apple-system,system-ui,Segoe UI,Roboto,Helvetica,Arial}
header{padding:10px 14px;background:#141414;position:sticky;top:0}
h1{margin:0;font-size:16px}
#wrap{position:relative}
video{width:100vw;height:calc(100vh - 48px);object-fit:cover;background:#000}
.box{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}
.frame{width:min(70vw,70vh);height:min(70vw,70vh);border:2px solid #6cf;border-radius:12px;box-shadow:0 0 8px #6cf inset}
.hint{position:absolute;bottom:10px;left:0;right:0;text-align:center;font-size:12px;color:#bbb}
</style>
<header><h1>Сканирование… наведи на штрихкод</h1></header>
<div id="wrap">
<video id="preview" playsinline autoplay muted></video>
<div class="box"><div class="frame"></div></div>
<div class="hint">Доступ к камере запросится автоматически (только HTTPS)</div>
</div>
<!-- ZXing -->
<script src="https://unpkg.com/@zxing/library@latest"></script>
<script>
(async () => {
// Форматы: 1D (EAN/UPC/Code128/39/ITF/Codabar) + QR
const formats = [
ZXing.BarcodeFormat.EAN_13, ZXing.BarcodeFormat.EAN_8,
ZXing.BarcodeFormat.UPC_A, ZXing.BarcodeFormat.UPC_E,
ZXing.BarcodeFormat.CODE_128, ZXing.BarcodeFormat.CODE_39,
ZXing.BarcodeFormat.ITF, ZXing.BarcodeFormat.CODABAR,
ZXing.BarcodeFormat.QR_CODE
];
const hints = new Map();
hints.set(ZXing.DecodeHintType.POSSIBLE_FORMATS, formats);
hints.set(ZXing.DecodeHintType.TRY_HARDER, true);
const reader = new ZXing.BrowserMultiFormatReader(hints);
const video = document.getElementById('preview');
// Автозапуск потока с тыльной камеры
const constraints = { audio: false, video: { facingMode: { ideal: "environment" } } };
try {
// decodeFromConstraints сам откроет getUserMedia и будет читать кадры
await reader.decodeFromConstraints(constraints, video, (result, err) => {
if (result) {
const text = result.getText ? result.getText() : (result.text || "");
const fmt = result.getBarcodeFormat ? String(result.getBarcodeFormat()) : (result.barcodeFormat || "CODE");
// Отправляем в Scriptable через кастомную схему и останавливаем сканер
try { reader.reset(); } catch(e) {}
location.href = "scriptable://decoded?text=" + encodeURIComponent(text) + "&format=" + encodeURIComponent(fmt);
}
// Ошибки распознавания приходят часто — их игнорируем
});
} catch (e) {
alert("Не удалось открыть камеру: " + e);
}
})();
</script>
</html>