{"id":13398019,"url":"https://github.com/schmich/instascan","last_synced_at":"2025-05-14T04:03:09.888Z","repository":{"id":39618272,"uuid":"61934962","full_name":"schmich/instascan","owner":"schmich","description":"HTML5 QR code scanner using your webcam","archived":false,"fork":false,"pushed_at":"2021-12-15T13:21:36.000Z","size":2114,"stargazers_count":3000,"open_issues_count":193,"forks_count":868,"subscribers_count":97,"default_branch":"master","last_synced_at":"2025-05-11T15:37:36.838Z","etag":null,"topics":["browser","camera","emscripten","html5","javascript","qr-code","qrcode","quick-response","video","webcam","zxing"],"latest_commit_sha":null,"homepage":"https://schmich.github.io/instascan/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/schmich.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-25T08:52:12.000Z","updated_at":"2025-05-04T18:21:45.000Z","dependencies_parsed_at":"2022-08-09T15:06:56.667Z","dependency_job_id":null,"html_url":"https://github.com/schmich/instascan","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schmich","download_url":"https://codeload.github.com/schmich/instascan/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254067124,"owners_count":22009085,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","camera","emscripten","html5","javascript","qr-code","qrcode","quick-response","video","webcam","zxing"],"created_at":"2024-07-30T18:02:02.093Z","updated_at":"2025-05-14T04:03:09.780Z","avatar_url":"https://github.com/schmich.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Libraries"],"sub_categories":["QR code","JavaScript"],"readme":"# ![Instascan](https://raw.githubusercontent.com/schmich/instascan/master/assets/qr.png) Instascan\nReal-time webcam-driven HTML5 QR code scanner. [Try the live demo](https://schmich.github.io/instascan/).\n\n## Installing\n\n*Note:* Chrome requires HTTPS when using the WebRTC API. Any pages using this library should be served over HTTPS.\n\n### NPM\n\n`npm install --save instascan`\n\n```javascript\nconst Instascan = require('instascan');\n```\n\n### Bower\n\nPending. [Drop a note](https://github.com/schmich/instascan/issues/31) if you need Bower support.\n\n### Minified\n\nCopy `instascan.min.js` from the [releases](https://github.com/schmich/instascan/releases) page and load with:\n\n```html\n\u003cscript type=\"text/javascript\" src=\"instascan.min.js\"\u003e\u003c/script\u003e\n```\n\n## Example\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eInstascan\u003c/title\u003e\n    \u003cscript type=\"text/javascript\" src=\"instascan.min.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cvideo id=\"preview\"\u003e\u003c/video\u003e\n    \u003cscript type=\"text/javascript\"\u003e\n      let scanner = new Instascan.Scanner({ video: document.getElementById('preview') });\n      scanner.addListener('scan', function (content) {\n        console.log(content);\n      });\n      Instascan.Camera.getCameras().then(function (cameras) {\n        if (cameras.length \u003e 0) {\n          scanner.start(cameras[0]);\n        } else {\n          console.error('No cameras found.');\n        }\n      }).catch(function (e) {\n        console.error(e);\n      });\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## API\n\n### let scanner = new Instascan.Scanner(opts)\n\nCreate a new scanner with options:\n\n```javascript\nlet opts = {\n  // Whether to scan continuously for QR codes. If false, use scanner.scan() to manually scan.\n  // If true, the scanner emits the \"scan\" event when a QR code is scanned. Default true.\n  continuous: true,\n  \n  // The HTML element to use for the camera's video preview. Must be a \u003cvideo\u003e element.\n  // When the camera is active, this element will have the \"active\" CSS class, otherwise,\n  // it will have the \"inactive\" class. By default, an invisible element will be created to\n  // host the video.\n  video: document.getElementById('preview'),\n  \n  // Whether to horizontally mirror the video preview. This is helpful when trying to\n  // scan a QR code with a user-facing camera. Default true.\n  mirror: true,\n  \n  // Whether to include the scanned image data as part of the scan result. See the \"scan\" event\n  // for image format details. Default false.\n  captureImage: false,\n  \n  // Only applies to continuous mode. Whether to actively scan when the tab is not active.\n  // When false, this reduces CPU usage when the tab is not active. Default true.\n  backgroundScan: true,\n  \n  // Only applies to continuous mode. The period, in milliseconds, before the same QR code\n  // will be recognized in succession. Default 5000 (5 seconds).\n  refractoryPeriod: 5000,\n  \n  // Only applies to continuous mode. The period, in rendered frames, between scans. A lower scan period\n  // increases CPU usage but makes scan response faster. Default 1 (i.e. analyze every frame).\n  scanPeriod: 1\n};\n```\n\n### scanner.start(camera)\n\n- Activate `camera` and start scanning using it as the source. Returns promise.\n- This must be called in order to use [`scanner.scan`](#let-result--scannerscan) or receive [`scan`](#scanneraddlistenerscan-callback) events.\n- `camera`: Instance of `Instascan.Camera` from [`Instascan.Camera.getCameras`](#instascancameragetcameras).\n- `.then(function () { ... })`: called when camera is active and scanning has started.\n- `.catch(function (err) { ... })`\n  - Called when an error occurs trying to initialize the camera for scanning.\n  - `err`: An `Instascan.MediaError` in the case of a known `getUserMedia` failure ([see error types](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Errors)).\n  \n### scanner.stop()\n\n- Stop scanning and deactivate the camera. Returns promise.\n- `.then(function () { ... })`: called when camera and scanning have stopped.\n\n### let result = scanner.scan()\n\n- Scan video immediately for a QR code.\n- QR codes recognized with this method are not emitted via the `scan` event.\n- If no QR code is detected, `result` is `null`.\n- `result.content`: Scanned content decoded from the QR code.\n- `result.image`: Undefined if [`scanner.captureImage`](#let-scanner--new-instascanscanneropts) is `false`, otherwise, see the [`scan`](#scanneraddlistenerscan-callback) event for format.\n\n### scanner.addListener('scan', callback)\n\n- Emitted when a QR code is scanned using the camera in continuous mode (see [`scanner.continuous`](#let-scanner--new-instascanscanneropts)).\n- `callback`: `function (content, image)`\n  - `content`: Scanned content decoded from the QR code.\n  - `image`: `null` if [`scanner.captureImage`](#let-scanner--new-instascanscanneropts) is `false`, otherwise, a base64-encoded [WebP](https://en.wikipedia.org/wiki/WebP)-compressed data URI of the camera frame used to decode the QR code.\n\n### scanner.addListener('active', callback)\n\n- Emitted when the scanner becomes active as the result of [`scanner.start`](#scannerstartcamera) or the tab gaining focus.\n- If `opts.video` element was specified, it will have the `active` CSS class.\n- `callback`: `function ()`\n\n### scanner.addListener('inactive', callback)\n\n- Emitted when the scanner becomes inactive as the result of [`scanner.stop`](#scannerstop) or the tab losing focus.\n- If `opts.video` element was specified, it will have the `inactive` CSS class.\n- `callback`: `function ()`\n\n### Instascan.Camera.getCameras()\n\n- Enumerate available video devices. Returns promise.\n- `.then(function (cameras) { ... })`\n  - Called when cameras are available.\n  - `cameras`: Array of `Instascan.Camera` instances available for use.\n- `.catch(function (err) { ... })`\n  - Called when an error occurs while getting cameras.\n  - `err`: An `Instascan.MediaError` in the case of a known `getUserMedia` failure ([see error types](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Errors)).\n\n### camera.id\n\n- Unique camera ID provided by the browser.\n- These IDs are stable and can be persisted across instances of your application (e.g. in localStorage).\n\n### camera.name\n\n- Camera name, including manufacturer and model\n- e.g. \"Microsoft LifeCam HD-3000\".\n\n## Compatibility\n\nInstascan works on non-iOS platforms in [any browser that supports the WebRTC/getUserMedia API](http://caniuse.com/#feat=stream), which currently includes Chome, Firefox, Opera, and Edge. IE and Safari are not supported.\n\nInstascan does not work on iOS since Apple does not yet support WebRTC in WebKit *and* forces other browser vendors (Chrome, Firefox, Opera) to use their implementation of WebKit. [Apple is actively working on WebRTC support in WebKit](https://bugs.webkit.org/show_bug.cgi?id=124288).\n\n## Performance\n\nMany factors affect how quickly and reliably Instascan can detect QR codes.\n\nIf you control creation of the QR code, consider the following:\n\n- A larger physical code is better. A 2\" square code is better than a 1\" square code.\n- Flat, smooth, matte surfaces are better than curved, rough, glossy surfaces.\n- Include a sufficient quiet zone, the white border surrounding QR code. The quiet zone should be at least four times the width of an individual element in your QR code.\n- A simpler code is better. You can use [this QR code generator](https://www.the-qrcode-generator.com/) to see how your input affects complexity.\n- For the same length, numeric content is simpler than ASCII content, which is simpler than Unicode content.\n- Shorter content is simpler. If you're encoding a URL, consider using a shortener such as [goo.gl](https://goo.gl/) or [bit.ly](https://bitly.com/).\n\nWhen scanning, consider the following:\n\n- QR code orientation doesn't matter.\n- Higher resolution video is better, but is more CPU intensive.\n- Direct, orthogonal scanning is better than scanning at an angle.\n- Blurry video greatly reduces scanner performance.\n- Auto-focus can cause lags in detection as the camera adjusts focus. Consider disabling it or using a fixed-focus camera with the subject positioned at the focal point.\n- Exposure adjustment on cameras can cause lags in detection. Consider disabling it or having a fixed white backdrop.\n\n## Example Setup\n\n- Purpose: To scan QR code stickers on paper cards and plastic bags.\n- Camera: [Microsoft LifeCam HD-3000](http://www.newegg.com/Product/Product.aspx?Item=9SIA4RE40S4991), 720p, fixed focus, around $30 USD.\n- Small support to ensure camera is focused on subject.\n- White paper backdrop to mitigate exposure adjustment.\n\n![Setup](https://raw.githubusercontent.com/schmich/instascan/master/assets/setup.jpg)\n\n## Credits\n\nPowered by the [Emscripten JavaScript build](https://github.com/kig/zxing-cpp-emscripten) of the [C++ port](https://github.com/glassechidna/zxing-cpp) of the [ZXing Java library](https://github.com/zxing/zxing).\n\n## License\n\nCopyright \u0026copy; 2016 Chris Schmich  \nMIT License. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschmich%2Finstascan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschmich%2Finstascan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschmich%2Finstascan/lists"}