QR コードが好きな気がする zaru です。今回は暇だったので QR コードを連続で読み取れたら良いな〜と思ったので、QR コードを連続で読み取れる Web アプリを作りました。たぶん QR コードを読み取る仕事をしている人や、趣味の人には役に立つと思います。

カメラ機能のついているブラウザでアクセスしてみてください。

1

ブラウザでカメラにつなげる

1

MediaDevices.getUserMedia() API を使うとブラウザからカメラに接続することができます。

_getStream(): Promise<MediaStream> {
  const config = {
    video: {
      audio: false,
      facingMode: { exact: 'environment' }
    }
  }
  return navigator.mediaDevices.getUserMedia(config)
}

facingMode オプションでカメラの前面・背面を決められます。 facingMode: "user" で前面に facingMode: { exact: "environment" } } で背面になります。

2

ここで取得したカメラを <video> タグに出力することで画面上にカメラの映像を映すことができます。

// this.video = this.document.getElementById('video') as HTMLVideoElement

async showStream(): Promise<void> {
  this.video.srcObject = await this._getStream()
  this.video.addEventListener('loadedmetadata', () => {
    this.video.play()
  })
}

カメラの映像を画像にして QR コードを解析する

3

QR コードの解析は jsQR にお任せします。そのために <video> の映像を画像として渡してあげる必要がありますので、<canvas> に渡して画像に変換してあげます。

_syncCanvas(): void {
  this.ctx.drawImage(this.video, 0, 0, this.video.videoWidth, this.video.videoHeight)
  const data = this.ctx.getImageData(0, 0, this.video.videoWidth, this.video.videoHeight).data
  const code = jsQR(data, this.video.videoWidth, this.video.videoHeight)
}

画像を常に抽出するのに requestAnimationFrame を使うといい感じのパフォーマンスでブラウザがやってくれます。全体のコードはこちらを参照してください。

this.window.requestAnimationFrame(() => this._syncCanvas())
4

これでもうほぼ完成です。getUserMedia 楽しくて良いですね。