From b3713f2b384ee43ca9a1b452775339eaec1b6b6d Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 5 Jul 2020 13:38:07 +0200 Subject: [PATCH] Remove canplay logic The manual call of play() just after setting the video stream introduced in the previous commit seems to suffice without the need to wait for the canplay event. Co-authored-by: shrpne --- qr-scanner.min.js | 22 +++++++++++----------- qr-scanner.min.js.map | 2 +- src/qr-scanner.js | 8 -------- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/qr-scanner.min.js b/qr-scanner.min.js index 29474d0..5112e66 100644 --- a/qr-scanner.min.js +++ b/qr-scanner.min.js @@ -1,12 +1,12 @@ -class e{static hasCamera(){return!!navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices().then((a)=>a.some((a)=>"videoinput"===a.kind)).catch(()=>!1)}constructor(a,c,b=e.DEFAULT_CANVAS_SIZE){this.$video=a;this.$canvas=document.createElement("canvas");this._onDecode=c;this._paused=this._active=!1;this.$canvas.width=b;this.$canvas.height=b;this._sourceRect={x:0,y:0,width:b,height:b};this._onCanPlay=this._onCanPlay.bind(this);this._onPlay=this._onPlay.bind(this);this._onVisibilityChange= -this._onVisibilityChange.bind(this);this.$video.addEventListener("canplay",this._onCanPlay);this.$video.addEventListener("play",this._onPlay);document.addEventListener("visibilitychange",this._onVisibilityChange);this._qrWorker=new Worker(e.WORKER_PATH)}destroy(){this.$video.removeEventListener("canplay",this._onCanPlay);this.$video.removeEventListener("play",this._onPlay);document.removeEventListener("visibilitychange",this._onVisibilityChange);this.stop();this._qrWorker.postMessage({type:"close"})}start(){if(this._active&& -!this._paused)return Promise.resolve();"https:"!==window.location.protocol&&console.warn("The camera stream is only accessible if the page is transferred via https.");this._active=!0;this._paused=!1;if(document.hidden)return Promise.resolve();clearTimeout(this._offTimeout);this._offTimeout=null;if(this.$video.srcObject)return this.$video.play(),Promise.resolve();let a="environment";return this._getCameraStream("environment",!0).catch(()=>{a="user";return this._getCameraStream()}).then((c)=>{this.$video.srcObject= -c;this.$video.play();this._setVideoMirror(a)}).catch((a)=>{this._active=!1;throw a;})}stop(){this.pause();this._active=!1}pause(){this._paused=!0;this._active&&(this.$video.pause(),this._offTimeout||(this._offTimeout=setTimeout(()=>{let a=this.$video.srcObject&&this.$video.srcObject.getTracks()[0];a&&(a.stop(),this._offTimeout=this.$video.srcObject=null)},300)))}static scanImage(a,c=null,b=null,d=null,f=!1,g=!1){let h=!1,l=new Promise((l,g)=>{b||(b=new Worker(e.WORKER_PATH),h=!0,b.postMessage({type:"inversionMode", -data:"both"}));let n,m,k;m=(a)=>{"qrResult"===a.data.type&&(b.removeEventListener("message",m),b.removeEventListener("error",k),clearTimeout(n),null!==a.data.data?l(a.data.data):g("QR code not found."))};k=(a)=>{b.removeEventListener("message",m);b.removeEventListener("error",k);clearTimeout(n);g("Scanner error: "+(a?a.message||a:"Unknown Error"))};b.addEventListener("message",m);b.addEventListener("error",k);n=setTimeout(()=>k("timeout"),3E3);e._loadImage(a).then((a)=>{a=e._getImageData(a,c,d,f); -b.postMessage({type:"decode",data:a},[a.data.buffer])}).catch(k)});c&&g&&(l=l.catch(()=>e.scanImage(a,null,b,d,f)));return l=l.finally(()=>{h&&b.postMessage({type:"close"})})}setGrayscaleWeights(a,c,b,d=!0){this._qrWorker.postMessage({type:"grayscaleWeights",data:{red:a,green:c,blue:b,useIntegerApproximation:d}})}setInversionMode(a){this._qrWorker.postMessage({type:"inversionMode",data:a})}_onCanPlay(){this._updateSourceRect();this.$video.play()}_onPlay(){this._updateSourceRect();this._scanFrame()}_onVisibilityChange(){document.hidden? -this.pause():this._active&&this.start()}_updateSourceRect(){let a=Math.round(2/3*Math.min(this.$video.videoWidth,this.$video.videoHeight));this._sourceRect.width=this._sourceRect.height=a;this._sourceRect.x=(this.$video.videoWidth-a)/2;this._sourceRect.y=(this.$video.videoHeight-a)/2}_scanFrame(){if(!this._active||this.$video.paused||this.$video.ended)return!1;requestAnimationFrame(()=>{e.scanImage(this.$video,this._sourceRect,this._qrWorker,this.$canvas,!0).then(this._onDecode,(a)=>{this._active&& -"QR code not found."!==a&&console.error(a)}).then(()=>this._scanFrame())})}_getCameraStream(a,c=!1){let b=[{width:{min:1024}},{width:{min:768}},{}];a&&(c&&(a={exact:a}),b.forEach((b)=>b.facingMode=a));return this._getMatchingCameraStream(b)}_getMatchingCameraStream(a){return navigator.mediaDevices&&0!==a.length?navigator.mediaDevices.getUserMedia({video:a.shift()}).catch(()=>this._getMatchingCameraStream(a)):Promise.reject("Camera not found.")}_setVideoMirror(a){this.$video.style.transform="scaleX("+ -("user"===a?-1:1)+")"}static _getImageData(a,c=null,b=null,d=!1){b=b||document.createElement("canvas");let f=c&&c.x?c.x:0,g=c&&c.y?c.y:0,h=c&&c.width?c.width:a.width||a.videoWidth;c=c&&c.height?c.height:a.height||a.videoHeight;d||b.width===h&&b.height===c||(b.width=h,b.height=c);d=b.getContext("2d",{alpha:!1});d.imageSmoothingEnabled=!1;d.drawImage(a,f,g,h,c,0,0,b.width,b.height);return d.getImageData(0,0,b.width,b.height)}static _loadImage(a){if(a instanceof HTMLCanvasElement||a instanceof HTMLVideoElement|| -window.ImageBitmap&&a instanceof window.ImageBitmap||window.OffscreenCanvas&&a instanceof window.OffscreenCanvas)return Promise.resolve(a);if(a instanceof Image)return e._awaitImageLoad(a).then(()=>a);if(a instanceof File||a instanceof URL||"string"===typeof a){let c=new Image;c.src=a instanceof File?URL.createObjectURL(a):a;return e._awaitImageLoad(c).then(()=>{a instanceof File&&URL.revokeObjectURL(c.src);return c})}return Promise.reject("Unsupported image type.")}static _awaitImageLoad(a){return new Promise((c, -b)=>{if(a.complete&&0!==a.naturalWidth)c();else{let d,f;d=()=>{a.removeEventListener("load",d);a.removeEventListener("error",f);c()};f=()=>{a.removeEventListener("load",d);a.removeEventListener("error",f);b("Image load error")};a.addEventListener("load",d);a.addEventListener("error",f)}})}}e.DEFAULT_CANVAS_SIZE=400;e.WORKER_PATH="qr-scanner-worker.min.js";export default e; +class e{static hasCamera(){return!!navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices().then((a)=>a.some((a)=>"videoinput"===a.kind)).catch(()=>!1)}constructor(a,c,b=e.DEFAULT_CANVAS_SIZE){this.$video=a;this.$canvas=document.createElement("canvas");this._onDecode=c;this._paused=this._active=!1;this.$canvas.width=b;this.$canvas.height=b;this._sourceRect={x:0,y:0,width:b,height:b};this._onPlay=this._onPlay.bind(this);this._onVisibilityChange=this._onVisibilityChange.bind(this); +this.$video.addEventListener("play",this._onPlay);document.addEventListener("visibilitychange",this._onVisibilityChange);this._qrWorker=new Worker(e.WORKER_PATH)}destroy(){this.$video.removeEventListener("play",this._onPlay);document.removeEventListener("visibilitychange",this._onVisibilityChange);this.stop();this._qrWorker.postMessage({type:"close"})}start(){if(this._active&&!this._paused)return Promise.resolve();"https:"!==window.location.protocol&&console.warn("The camera stream is only accessible if the page is transferred via https."); +this._active=!0;this._paused=!1;if(document.hidden)return Promise.resolve();clearTimeout(this._offTimeout);this._offTimeout=null;if(this.$video.srcObject)return this.$video.play(),Promise.resolve();let a="environment";return this._getCameraStream("environment",!0).catch(()=>{a="user";return this._getCameraStream()}).then((c)=>{this.$video.srcObject=c;this.$video.play();this._setVideoMirror(a)}).catch((a)=>{this._active=!1;throw a;})}stop(){this.pause();this._active=!1}pause(){this._paused=!0;this._active&& +(this.$video.pause(),this._offTimeout||(this._offTimeout=setTimeout(()=>{let a=this.$video.srcObject&&this.$video.srcObject.getTracks()[0];a&&(a.stop(),this._offTimeout=this.$video.srcObject=null)},300)))}static scanImage(a,c=null,b=null,d=null,f=!1,g=!1){let h=!1,l=new Promise((l,g)=>{b||(b=new Worker(e.WORKER_PATH),h=!0,b.postMessage({type:"inversionMode",data:"both"}));let n,m,k;m=(a)=>{"qrResult"===a.data.type&&(b.removeEventListener("message",m),b.removeEventListener("error",k),clearTimeout(n), +null!==a.data.data?l(a.data.data):g("QR code not found."))};k=(a)=>{b.removeEventListener("message",m);b.removeEventListener("error",k);clearTimeout(n);g("Scanner error: "+(a?a.message||a:"Unknown Error"))};b.addEventListener("message",m);b.addEventListener("error",k);n=setTimeout(()=>k("timeout"),3E3);e._loadImage(a).then((a)=>{a=e._getImageData(a,c,d,f);b.postMessage({type:"decode",data:a},[a.data.buffer])}).catch(k)});c&&g&&(l=l.catch(()=>e.scanImage(a,null,b,d,f)));return l=l.finally(()=>{h&& +b.postMessage({type:"close"})})}setGrayscaleWeights(a,c,b,d=!0){this._qrWorker.postMessage({type:"grayscaleWeights",data:{red:a,green:c,blue:b,useIntegerApproximation:d}})}setInversionMode(a){this._qrWorker.postMessage({type:"inversionMode",data:a})}_onPlay(){this._updateSourceRect();this._scanFrame()}_onVisibilityChange(){document.hidden?this.pause():this._active&&this.start()}_updateSourceRect(){let a=Math.round(2/3*Math.min(this.$video.videoWidth,this.$video.videoHeight));this._sourceRect.width= +this._sourceRect.height=a;this._sourceRect.x=(this.$video.videoWidth-a)/2;this._sourceRect.y=(this.$video.videoHeight-a)/2}_scanFrame(){if(!this._active||this.$video.paused||this.$video.ended)return!1;requestAnimationFrame(()=>{e.scanImage(this.$video,this._sourceRect,this._qrWorker,this.$canvas,!0).then(this._onDecode,(a)=>{this._active&&"QR code not found."!==a&&console.error(a)}).then(()=>this._scanFrame())})}_getCameraStream(a,c=!1){let b=[{width:{min:1024}},{width:{min:768}},{}];a&&(c&&(a={exact:a}), +b.forEach((b)=>b.facingMode=a));return this._getMatchingCameraStream(b)}_getMatchingCameraStream(a){return navigator.mediaDevices&&0!==a.length?navigator.mediaDevices.getUserMedia({video:a.shift()}).catch(()=>this._getMatchingCameraStream(a)):Promise.reject("Camera not found.")}_setVideoMirror(a){this.$video.style.transform="scaleX("+("user"===a?-1:1)+")"}static _getImageData(a,c=null,b=null,d=!1){b=b||document.createElement("canvas");let f=c&&c.x?c.x:0,g=c&&c.y?c.y:0,h=c&&c.width?c.width:a.width|| +a.videoWidth;c=c&&c.height?c.height:a.height||a.videoHeight;d||b.width===h&&b.height===c||(b.width=h,b.height=c);d=b.getContext("2d",{alpha:!1});d.imageSmoothingEnabled=!1;d.drawImage(a,f,g,h,c,0,0,b.width,b.height);return d.getImageData(0,0,b.width,b.height)}static _loadImage(a){if(a instanceof HTMLCanvasElement||a instanceof HTMLVideoElement||window.ImageBitmap&&a instanceof window.ImageBitmap||window.OffscreenCanvas&&a instanceof window.OffscreenCanvas)return Promise.resolve(a);if(a instanceof +Image)return e._awaitImageLoad(a).then(()=>a);if(a instanceof File||a instanceof URL||"string"===typeof a){let c=new Image;c.src=a instanceof File?URL.createObjectURL(a):a;return e._awaitImageLoad(c).then(()=>{a instanceof File&&URL.revokeObjectURL(c.src);return c})}return Promise.reject("Unsupported image type.")}static _awaitImageLoad(a){return new Promise((c,b)=>{if(a.complete&&0!==a.naturalWidth)c();else{let d,f;d=()=>{a.removeEventListener("load",d);a.removeEventListener("error",f);c()};f=()=> +{a.removeEventListener("load",d);a.removeEventListener("error",f);b("Image load error")};a.addEventListener("load",d);a.addEventListener("error",f)}})}}e.DEFAULT_CANVAS_SIZE=400;e.WORKER_PATH="qr-scanner-worker.min.js";export default e; //# sourceMappingURL=qr-scanner.min.js.map diff --git a/qr-scanner.min.js.map b/qr-scanner.min.js.map index aeae696..2d2ed93 100644 --- a/qr-scanner.min.js.map +++ b/qr-scanner.min.js.map @@ -1 +1 @@ -{"version":3,"file":"qr-scanner.min.js","sources":["src/qr-scanner.js"],"sourcesContent":["export default class QrScanner {\n /* async */\n static hasCamera() {\n // note that enumerateDevices can always be called and does not prompt the user for permission. However, device\n // labels are only readable if served via https and an active media stream exists or permanent permission is\n // given. That doesn't matter for us though as we don't require labels.\n return !!navigator.mediaDevices && navigator.mediaDevices.enumerateDevices()\n .then(devices => devices.some(device => device.kind === 'videoinput'))\n .catch(() => false);\n }\n\n constructor(video, onDecode, canvasSize = QrScanner.DEFAULT_CANVAS_SIZE) {\n this.$video = video;\n this.$canvas = document.createElement('canvas');\n this._onDecode = onDecode;\n this._active = false;\n this._paused = false;\n\n this.$canvas.width = canvasSize;\n this.$canvas.height = canvasSize;\n this._sourceRect = {\n x: 0,\n y: 0,\n width: canvasSize,\n height: canvasSize\n };\n\n this._onCanPlay = this._onCanPlay.bind(this);\n this._onPlay = this._onPlay.bind(this);\n this._onVisibilityChange = this._onVisibilityChange.bind(this);\n\n this.$video.addEventListener('canplay', this._onCanPlay);\n this.$video.addEventListener('play', this._onPlay);\n document.addEventListener('visibilitychange', this._onVisibilityChange);\n\n this._qrWorker = new Worker(QrScanner.WORKER_PATH);\n }\n\n destroy() {\n this.$video.removeEventListener('canplay', this._onCanPlay);\n this.$video.removeEventListener('play', this._onPlay);\n document.removeEventListener('visibilitychange', this._onVisibilityChange);\n\n this.stop();\n this._qrWorker.postMessage({\n type: 'close'\n });\n }\n\n /* async */\n start() {\n if (this._active && !this._paused) {\n return Promise.resolve();\n }\n if (window.location.protocol !== 'https:') {\n // warn but try starting the camera anyways\n console.warn('The camera stream is only accessible if the page is transferred via https.');\n }\n this._active = true;\n this._paused = false;\n if (document.hidden) {\n // camera will be started as soon as tab is in foreground\n return Promise.resolve();\n }\n clearTimeout(this._offTimeout);\n this._offTimeout = null;\n if (this.$video.srcObject) {\n // camera stream already/still set\n this.$video.play();\n return Promise.resolve();\n }\n\n let facingMode = 'environment';\n return this._getCameraStream('environment', true)\n .catch(() => {\n // we (probably) don't have an environment camera\n facingMode = 'user';\n return this._getCameraStream(); // throws if camera is not accessible (e.g. due to not https)\n })\n .then(stream => {\n this.$video.srcObject = stream;\n this.$video.play();\n this._setVideoMirror(facingMode);\n })\n .catch(e => {\n this._active = false;\n throw e;\n });\n }\n\n stop() {\n this.pause();\n this._active = false;\n }\n\n pause() {\n this._paused = true;\n if (!this._active) {\n return;\n }\n this.$video.pause();\n if (this._offTimeout) {\n return;\n }\n this._offTimeout = setTimeout(() => {\n const track = this.$video.srcObject && this.$video.srcObject.getTracks()[0];\n if (!track) return;\n track.stop();\n this.$video.srcObject = null;\n this._offTimeout = null;\n }, 300);\n }\n\n /* async */\n static scanImage(imageOrFileOrUrl, sourceRect=null, worker=null, canvas=null, fixedCanvasSize=false,\n alsoTryWithoutSourceRect=false) {\n let createdNewWorker = false;\n let promise = new Promise((resolve, reject) => {\n if (!worker) {\n worker = new Worker(QrScanner.WORKER_PATH);\n createdNewWorker = true;\n worker.postMessage({ type: 'inversionMode', data: 'both' }); // scan inverted color qr codes too\n }\n let timeout, onMessage, onError;\n onMessage = event => {\n if (event.data.type !== 'qrResult') {\n return;\n }\n worker.removeEventListener('message', onMessage);\n worker.removeEventListener('error', onError);\n clearTimeout(timeout);\n if (event.data.data !== null) {\n resolve(event.data.data);\n } else {\n reject('QR code not found.');\n }\n };\n onError = (e) => {\n worker.removeEventListener('message', onMessage);\n worker.removeEventListener('error', onError);\n clearTimeout(timeout);\n const errorMessage = !e ? 'Unknown Error' : (e.message || e);\n reject('Scanner error: ' + errorMessage);\n };\n worker.addEventListener('message', onMessage);\n worker.addEventListener('error', onError);\n timeout = setTimeout(() => onError('timeout'), 3000);\n QrScanner._loadImage(imageOrFileOrUrl).then(image => {\n const imageData = QrScanner._getImageData(image, sourceRect, canvas, fixedCanvasSize);\n worker.postMessage({\n type: 'decode',\n data: imageData\n }, [imageData.data.buffer]);\n }).catch(onError);\n });\n\n if (sourceRect && alsoTryWithoutSourceRect) {\n promise = promise.catch(() => QrScanner.scanImage(imageOrFileOrUrl, null, worker, canvas, fixedCanvasSize));\n }\n\n promise = promise.finally(() => {\n if (!createdNewWorker) return;\n worker.postMessage({\n type: 'close'\n });\n });\n\n return promise;\n }\n\n setGrayscaleWeights(red, green, blue, useIntegerApproximation = true) {\n this._qrWorker.postMessage({\n type: 'grayscaleWeights',\n data: { red, green, blue, useIntegerApproximation }\n });\n }\n\n setInversionMode(inversionMode) {\n this._qrWorker.postMessage({\n type: 'inversionMode',\n data: inversionMode\n });\n }\n\n _onCanPlay() {\n this._updateSourceRect();\n this.$video.play();\n }\n\n _onPlay() {\n this._updateSourceRect();\n this._scanFrame();\n }\n\n _onVisibilityChange() {\n if (document.hidden) {\n this.pause();\n } else if (this._active) {\n this.start();\n }\n }\n\n _updateSourceRect() {\n const smallestDimension = Math.min(this.$video.videoWidth, this.$video.videoHeight);\n const sourceRectSize = Math.round(2 / 3 * smallestDimension);\n this._sourceRect.width = this._sourceRect.height = sourceRectSize;\n this._sourceRect.x = (this.$video.videoWidth - sourceRectSize) / 2;\n this._sourceRect.y = (this.$video.videoHeight - sourceRectSize) / 2;\n }\n\n _scanFrame() {\n if (!this._active || this.$video.paused || this.$video.ended) return false;\n // using requestAnimationFrame to avoid scanning if tab is in background\n requestAnimationFrame(() => {\n QrScanner.scanImage(this.$video, this._sourceRect, this._qrWorker, this.$canvas, true)\n .then(this._onDecode, error => {\n if (this._active && error !== 'QR code not found.') {\n console.error(error);\n }\n })\n .then(() => this._scanFrame());\n });\n }\n\n _getCameraStream(facingMode, exact = false) {\n const constraintsToTry = [{\n width: { min: 1024 }\n }, {\n width: { min: 768 }\n }, {}];\n\n if (facingMode) {\n if (exact) {\n facingMode = { exact: facingMode };\n }\n constraintsToTry.forEach(constraint => constraint.facingMode = facingMode);\n }\n return this._getMatchingCameraStream(constraintsToTry);\n }\n\n _getMatchingCameraStream(constraintsToTry) {\n if (!navigator.mediaDevices || constraintsToTry.length === 0) {\n return Promise.reject('Camera not found.');\n }\n return navigator.mediaDevices.getUserMedia({\n video: constraintsToTry.shift()\n }).catch(() => this._getMatchingCameraStream(constraintsToTry));\n }\n\n _setVideoMirror(facingMode) {\n // in user facing mode mirror the video to make it easier for the user to position the QR code\n const scaleFactor = facingMode==='user'? -1 : 1;\n this.$video.style.transform = 'scaleX(' + scaleFactor + ')';\n }\n\n static _getImageData(image, sourceRect=null, canvas=null, fixedCanvasSize=false) {\n canvas = canvas || document.createElement('canvas');\n const sourceRectX = sourceRect && sourceRect.x? sourceRect.x : 0;\n const sourceRectY = sourceRect && sourceRect.y? sourceRect.y : 0;\n const sourceRectWidth = sourceRect && sourceRect.width? sourceRect.width : image.width || image.videoWidth;\n const sourceRectHeight = sourceRect && sourceRect.height? sourceRect.height : image.height || image.videoHeight;\n if (!fixedCanvasSize && (canvas.width !== sourceRectWidth || canvas.height !== sourceRectHeight)) {\n canvas.width = sourceRectWidth;\n canvas.height = sourceRectHeight;\n }\n const context = canvas.getContext('2d', { alpha: false });\n context.imageSmoothingEnabled = false; // gives less blurry images\n context.drawImage(image, sourceRectX, sourceRectY, sourceRectWidth, sourceRectHeight, 0, 0, canvas.width, canvas.height);\n return context.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /* async */\n static _loadImage(imageOrFileOrUrl) {\n if (imageOrFileOrUrl instanceof HTMLCanvasElement || imageOrFileOrUrl instanceof HTMLVideoElement\n || window.ImageBitmap && imageOrFileOrUrl instanceof window.ImageBitmap\n || window.OffscreenCanvas && imageOrFileOrUrl instanceof window.OffscreenCanvas) {\n return Promise.resolve(imageOrFileOrUrl);\n } else if (imageOrFileOrUrl instanceof Image) {\n return QrScanner._awaitImageLoad(imageOrFileOrUrl).then(() => imageOrFileOrUrl);\n } else if (imageOrFileOrUrl instanceof File || imageOrFileOrUrl instanceof URL\n || typeof(imageOrFileOrUrl)==='string') {\n const image = new Image();\n if (imageOrFileOrUrl instanceof File) {\n image.src = URL.createObjectURL(imageOrFileOrUrl);\n } else {\n image.src = imageOrFileOrUrl;\n }\n return QrScanner._awaitImageLoad(image).then(() => {\n if (imageOrFileOrUrl instanceof File) {\n URL.revokeObjectURL(image.src);\n }\n return image;\n });\n } else {\n return Promise.reject('Unsupported image type.');\n }\n }\n\n /* async */\n static _awaitImageLoad(image) {\n return new Promise((resolve, reject) => {\n if (image.complete && image.naturalWidth!==0) {\n // already loaded\n resolve();\n } else {\n let onLoad, onError;\n onLoad = () => {\n image.removeEventListener('load', onLoad);\n image.removeEventListener('error', onError);\n resolve();\n };\n onError = () => {\n image.removeEventListener('load', onLoad);\n image.removeEventListener('error', onError);\n reject('Image load error');\n };\n image.addEventListener('load', onLoad);\n image.addEventListener('error', onError);\n }\n });\n }\n}\nQrScanner.DEFAULT_CANVAS_SIZE = 400;\nQrScanner.WORKER_PATH = 'qr-scanner-worker.min.js';\n"],"names":["QrScanner","navigator","mediaDevices","enumerateDevices","then","devices","some","device","kind","catch","video","onDecode","canvasSize","DEFAULT_CANVAS_SIZE","$video","$canvas","document","createElement","_onDecode","_paused","_active","width","height","_sourceRect","x","y","_onCanPlay","bind","_onPlay","_onVisibilityChange","addEventListener","_qrWorker","Worker","WORKER_PATH","removeEventListener","stop","postMessage","type","Promise","resolve","window","location","protocol","console","warn","hidden","clearTimeout","_offTimeout","srcObject","play","facingMode","_getCameraStream","stream","_setVideoMirror","e","pause","setTimeout","track","imageOrFileOrUrl","sourceRect","worker","canvas","fixedCanvasSize","alsoTryWithoutSourceRect","createdNewWorker","promise","reject","data","timeout","onMessage","onError","event","_loadImage","image","imageData","buffer","scanImage","finally","red","green","blue","useIntegerApproximation","inversionMode","_updateSourceRect","_scanFrame","start","videoHeight","sourceRectSize","videoWidth","paused","ended","requestAnimationFrame","error","exact","min","constraintsToTry","forEach","constraint","_getMatchingCameraStream","length","getUserMedia","shift","style","transform","sourceRectWidth","sourceRectHeight","alpha","context","imageSmoothingEnabled","drawImage","sourceRectX","sourceRectY","getImageData","HTMLCanvasElement","HTMLVideoElement","ImageBitmap","OffscreenCanvas","Image","_awaitImageLoad","File","URL","src","createObjectURL","revokeObjectURL","complete","naturalWidth","onLoad"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"qr-scanner.min.js","sources":["src/qr-scanner.js"],"sourcesContent":["export default class QrScanner {\n /* async */\n static hasCamera() {\n // note that enumerateDevices can always be called and does not prompt the user for permission. However, device\n // labels are only readable if served via https and an active media stream exists or permanent permission is\n // given. That doesn't matter for us though as we don't require labels.\n return !!navigator.mediaDevices && navigator.mediaDevices.enumerateDevices()\n .then(devices => devices.some(device => device.kind === 'videoinput'))\n .catch(() => false);\n }\n\n constructor(video, onDecode, canvasSize = QrScanner.DEFAULT_CANVAS_SIZE) {\n this.$video = video;\n this.$canvas = document.createElement('canvas');\n this._onDecode = onDecode;\n this._active = false;\n this._paused = false;\n\n this.$canvas.width = canvasSize;\n this.$canvas.height = canvasSize;\n this._sourceRect = {\n x: 0,\n y: 0,\n width: canvasSize,\n height: canvasSize\n };\n\n this._onPlay = this._onPlay.bind(this);\n this._onVisibilityChange = this._onVisibilityChange.bind(this);\n\n this.$video.addEventListener('play', this._onPlay);\n document.addEventListener('visibilitychange', this._onVisibilityChange);\n\n this._qrWorker = new Worker(QrScanner.WORKER_PATH);\n }\n\n destroy() {\n this.$video.removeEventListener('play', this._onPlay);\n document.removeEventListener('visibilitychange', this._onVisibilityChange);\n\n this.stop();\n this._qrWorker.postMessage({\n type: 'close'\n });\n }\n\n /* async */\n start() {\n if (this._active && !this._paused) {\n return Promise.resolve();\n }\n if (window.location.protocol !== 'https:') {\n // warn but try starting the camera anyways\n console.warn('The camera stream is only accessible if the page is transferred via https.');\n }\n this._active = true;\n this._paused = false;\n if (document.hidden) {\n // camera will be started as soon as tab is in foreground\n return Promise.resolve();\n }\n clearTimeout(this._offTimeout);\n this._offTimeout = null;\n if (this.$video.srcObject) {\n // camera stream already/still set\n this.$video.play();\n return Promise.resolve();\n }\n\n let facingMode = 'environment';\n return this._getCameraStream('environment', true)\n .catch(() => {\n // we (probably) don't have an environment camera\n facingMode = 'user';\n return this._getCameraStream(); // throws if camera is not accessible (e.g. due to not https)\n })\n .then(stream => {\n this.$video.srcObject = stream;\n this.$video.play();\n this._setVideoMirror(facingMode);\n })\n .catch(e => {\n this._active = false;\n throw e;\n });\n }\n\n stop() {\n this.pause();\n this._active = false;\n }\n\n pause() {\n this._paused = true;\n if (!this._active) {\n return;\n }\n this.$video.pause();\n if (this._offTimeout) {\n return;\n }\n this._offTimeout = setTimeout(() => {\n const track = this.$video.srcObject && this.$video.srcObject.getTracks()[0];\n if (!track) return;\n track.stop();\n this.$video.srcObject = null;\n this._offTimeout = null;\n }, 300);\n }\n\n /* async */\n static scanImage(imageOrFileOrUrl, sourceRect=null, worker=null, canvas=null, fixedCanvasSize=false,\n alsoTryWithoutSourceRect=false) {\n let createdNewWorker = false;\n let promise = new Promise((resolve, reject) => {\n if (!worker) {\n worker = new Worker(QrScanner.WORKER_PATH);\n createdNewWorker = true;\n worker.postMessage({ type: 'inversionMode', data: 'both' }); // scan inverted color qr codes too\n }\n let timeout, onMessage, onError;\n onMessage = event => {\n if (event.data.type !== 'qrResult') {\n return;\n }\n worker.removeEventListener('message', onMessage);\n worker.removeEventListener('error', onError);\n clearTimeout(timeout);\n if (event.data.data !== null) {\n resolve(event.data.data);\n } else {\n reject('QR code not found.');\n }\n };\n onError = (e) => {\n worker.removeEventListener('message', onMessage);\n worker.removeEventListener('error', onError);\n clearTimeout(timeout);\n const errorMessage = !e ? 'Unknown Error' : (e.message || e);\n reject('Scanner error: ' + errorMessage);\n };\n worker.addEventListener('message', onMessage);\n worker.addEventListener('error', onError);\n timeout = setTimeout(() => onError('timeout'), 3000);\n QrScanner._loadImage(imageOrFileOrUrl).then(image => {\n const imageData = QrScanner._getImageData(image, sourceRect, canvas, fixedCanvasSize);\n worker.postMessage({\n type: 'decode',\n data: imageData\n }, [imageData.data.buffer]);\n }).catch(onError);\n });\n\n if (sourceRect && alsoTryWithoutSourceRect) {\n promise = promise.catch(() => QrScanner.scanImage(imageOrFileOrUrl, null, worker, canvas, fixedCanvasSize));\n }\n\n promise = promise.finally(() => {\n if (!createdNewWorker) return;\n worker.postMessage({\n type: 'close'\n });\n });\n\n return promise;\n }\n\n setGrayscaleWeights(red, green, blue, useIntegerApproximation = true) {\n this._qrWorker.postMessage({\n type: 'grayscaleWeights',\n data: { red, green, blue, useIntegerApproximation }\n });\n }\n\n setInversionMode(inversionMode) {\n this._qrWorker.postMessage({\n type: 'inversionMode',\n data: inversionMode\n });\n }\n\n _onPlay() {\n this._updateSourceRect();\n this._scanFrame();\n }\n\n _onVisibilityChange() {\n if (document.hidden) {\n this.pause();\n } else if (this._active) {\n this.start();\n }\n }\n\n _updateSourceRect() {\n const smallestDimension = Math.min(this.$video.videoWidth, this.$video.videoHeight);\n const sourceRectSize = Math.round(2 / 3 * smallestDimension);\n this._sourceRect.width = this._sourceRect.height = sourceRectSize;\n this._sourceRect.x = (this.$video.videoWidth - sourceRectSize) / 2;\n this._sourceRect.y = (this.$video.videoHeight - sourceRectSize) / 2;\n }\n\n _scanFrame() {\n if (!this._active || this.$video.paused || this.$video.ended) return false;\n // using requestAnimationFrame to avoid scanning if tab is in background\n requestAnimationFrame(() => {\n QrScanner.scanImage(this.$video, this._sourceRect, this._qrWorker, this.$canvas, true)\n .then(this._onDecode, error => {\n if (this._active && error !== 'QR code not found.') {\n console.error(error);\n }\n })\n .then(() => this._scanFrame());\n });\n }\n\n _getCameraStream(facingMode, exact = false) {\n const constraintsToTry = [{\n width: { min: 1024 }\n }, {\n width: { min: 768 }\n }, {}];\n\n if (facingMode) {\n if (exact) {\n facingMode = { exact: facingMode };\n }\n constraintsToTry.forEach(constraint => constraint.facingMode = facingMode);\n }\n return this._getMatchingCameraStream(constraintsToTry);\n }\n\n _getMatchingCameraStream(constraintsToTry) {\n if (!navigator.mediaDevices || constraintsToTry.length === 0) {\n return Promise.reject('Camera not found.');\n }\n return navigator.mediaDevices.getUserMedia({\n video: constraintsToTry.shift()\n }).catch(() => this._getMatchingCameraStream(constraintsToTry));\n }\n\n _setVideoMirror(facingMode) {\n // in user facing mode mirror the video to make it easier for the user to position the QR code\n const scaleFactor = facingMode==='user'? -1 : 1;\n this.$video.style.transform = 'scaleX(' + scaleFactor + ')';\n }\n\n static _getImageData(image, sourceRect=null, canvas=null, fixedCanvasSize=false) {\n canvas = canvas || document.createElement('canvas');\n const sourceRectX = sourceRect && sourceRect.x? sourceRect.x : 0;\n const sourceRectY = sourceRect && sourceRect.y? sourceRect.y : 0;\n const sourceRectWidth = sourceRect && sourceRect.width? sourceRect.width : image.width || image.videoWidth;\n const sourceRectHeight = sourceRect && sourceRect.height? sourceRect.height : image.height || image.videoHeight;\n if (!fixedCanvasSize && (canvas.width !== sourceRectWidth || canvas.height !== sourceRectHeight)) {\n canvas.width = sourceRectWidth;\n canvas.height = sourceRectHeight;\n }\n const context = canvas.getContext('2d', { alpha: false });\n context.imageSmoothingEnabled = false; // gives less blurry images\n context.drawImage(image, sourceRectX, sourceRectY, sourceRectWidth, sourceRectHeight, 0, 0, canvas.width, canvas.height);\n return context.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /* async */\n static _loadImage(imageOrFileOrUrl) {\n if (imageOrFileOrUrl instanceof HTMLCanvasElement || imageOrFileOrUrl instanceof HTMLVideoElement\n || window.ImageBitmap && imageOrFileOrUrl instanceof window.ImageBitmap\n || window.OffscreenCanvas && imageOrFileOrUrl instanceof window.OffscreenCanvas) {\n return Promise.resolve(imageOrFileOrUrl);\n } else if (imageOrFileOrUrl instanceof Image) {\n return QrScanner._awaitImageLoad(imageOrFileOrUrl).then(() => imageOrFileOrUrl);\n } else if (imageOrFileOrUrl instanceof File || imageOrFileOrUrl instanceof URL\n || typeof(imageOrFileOrUrl)==='string') {\n const image = new Image();\n if (imageOrFileOrUrl instanceof File) {\n image.src = URL.createObjectURL(imageOrFileOrUrl);\n } else {\n image.src = imageOrFileOrUrl;\n }\n return QrScanner._awaitImageLoad(image).then(() => {\n if (imageOrFileOrUrl instanceof File) {\n URL.revokeObjectURL(image.src);\n }\n return image;\n });\n } else {\n return Promise.reject('Unsupported image type.');\n }\n }\n\n /* async */\n static _awaitImageLoad(image) {\n return new Promise((resolve, reject) => {\n if (image.complete && image.naturalWidth!==0) {\n // already loaded\n resolve();\n } else {\n let onLoad, onError;\n onLoad = () => {\n image.removeEventListener('load', onLoad);\n image.removeEventListener('error', onError);\n resolve();\n };\n onError = () => {\n image.removeEventListener('load', onLoad);\n image.removeEventListener('error', onError);\n reject('Image load error');\n };\n image.addEventListener('load', onLoad);\n image.addEventListener('error', onError);\n }\n });\n }\n}\nQrScanner.DEFAULT_CANVAS_SIZE = 400;\nQrScanner.WORKER_PATH = 'qr-scanner-worker.min.js';\n"],"names":["QrScanner","navigator","mediaDevices","enumerateDevices","then","devices","some","device","kind","catch","video","onDecode","canvasSize","DEFAULT_CANVAS_SIZE","$video","$canvas","document","createElement","_onDecode","_paused","_active","width","height","_sourceRect","x","y","_onPlay","bind","_onVisibilityChange","addEventListener","_qrWorker","Worker","WORKER_PATH","removeEventListener","stop","postMessage","type","Promise","resolve","window","location","protocol","console","warn","hidden","clearTimeout","_offTimeout","srcObject","play","facingMode","_getCameraStream","stream","_setVideoMirror","e","pause","setTimeout","track","imageOrFileOrUrl","sourceRect","worker","canvas","fixedCanvasSize","alsoTryWithoutSourceRect","createdNewWorker","promise","reject","data","timeout","onMessage","onError","event","_loadImage","image","imageData","buffer","scanImage","finally","red","green","blue","useIntegerApproximation","inversionMode","_updateSourceRect","_scanFrame","start","videoHeight","sourceRectSize","videoWidth","paused","ended","requestAnimationFrame","error","exact","min","constraintsToTry","forEach","constraint","_getMatchingCameraStream","length","getUserMedia","shift","style","transform","sourceRectWidth","sourceRectHeight","alpha","context","imageSmoothingEnabled","drawImage","sourceRectX","sourceRectY","getImageData","HTMLCanvasElement","HTMLVideoElement","ImageBitmap","OffscreenCanvas","Image","_awaitImageLoad","File","URL","src","createObjectURL","revokeObjectURL","complete","naturalWidth","onLoad"],"mappings":"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"} \ No newline at end of file diff --git a/src/qr-scanner.js b/src/qr-scanner.js index f2c4177..d542722 100644 --- a/src/qr-scanner.js +++ b/src/qr-scanner.js @@ -25,11 +25,9 @@ export default class QrScanner { height: canvasSize }; - this._onCanPlay = this._onCanPlay.bind(this); this._onPlay = this._onPlay.bind(this); this._onVisibilityChange = this._onVisibilityChange.bind(this); - this.$video.addEventListener('canplay', this._onCanPlay); this.$video.addEventListener('play', this._onPlay); document.addEventListener('visibilitychange', this._onVisibilityChange); @@ -37,7 +35,6 @@ export default class QrScanner { } destroy() { - this.$video.removeEventListener('canplay', this._onCanPlay); this.$video.removeEventListener('play', this._onPlay); document.removeEventListener('visibilitychange', this._onVisibilityChange); @@ -182,11 +179,6 @@ export default class QrScanner { }); } - _onCanPlay() { - this._updateSourceRect(); - this.$video.play(); - } - _onPlay() { this._updateSourceRect(); this._scanFrame();