HTML5 QR スキャナー
動くスキャナーと、自分で作る人向けの API の話。
カメラはボタンを押したときだけ要求します。フレームは端末内で解読し、そのまま破棄します。
HTML5 のスキャナーは、3 つのブラウザ API を重ねたものです。getUserMedia でカメラのストリームを取り、canvas でフレームを標本化し、デコーダに渡します。デコーダは、あればネイティブの BarcodeDetector、なければ同梱の JavaScript デコーダです。プラグインもネイティブコードも登場しません。
このページが道具と解説を兼ねているのは、この検索で来る人の多くがこれから自分で作る人で、どこが要になる部分かを知りたいからです。
使い方
- コードを読むだけなら上のスキャナーを使ってください。
- 自分で実装するなら、下の API の順序を読んでください。
- 本番用のデコーダを選ぶ前に、互換性の注意を確認してください。
実装の順序
getUserMedia({ video: { facingMode: 'environment' } }) でストリームを取り、video 要素に繋ぎ、playsinline を付けます。これが無いと iOS Safari は動画を全画面にします。次に canvas へ 8〜10 fps 程度に間引いて描画し、canvas をデコーダへ渡します。成功したらトラックを止めます。
罠は解像度です。1080p のフレームを渡すと遅く、640 ピクセル幅のものより精度が上がるわけでもありません。先に縮小し、requestAnimationFrame ごとではなく一定間隔で解読してください。
確認日:2026-10-21。このツールはすべてブラウザ内で動作します。サーバーもアカウントもなく、生成した内容は保存されません。
よくある質問
html5-qrcode のようなライブラリは必要ですか?
必須ではありません。ライブラリはブラウザ間の差異と UI を引き受けます。多形式が必要なら価値がありますが、QR だけでよければ BarcodeDetector と jsQR のフォールバックで数十行、サイズもはるかに小さく済みます。
自分のサイトで getUserMedia が例外を投げるのは?
セキュアコンテキスト(HTTPS か localhost)が必要です。平文 HTTP では navigator.mediaDevices が undefined になり、これが最もよくある原因です。
終わった後にカメラを止めるには?
stream.getTracks().forEach(t => t.stop()) を呼びます。途中で離脱する場合に備えて pagehide も購読し、そこで解放してください。
関連ツール
QR コードのその他のツール。