์๋
ํ์ธ์,
Instascan์ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ios safari์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
instascan์์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ง๋ง ๋ฐฑ ์นด๋ฉ๋ผ๋ฅผ ์ด์ง ์์ต๋๋ค. ์ ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ด ๋๋ง๋ค.
Android(Chrome, Firefox)์์๋ ๋์ผํ ์ฝ๋๊ฐ ์ ์๋ํฉ๋๋ค.
์๊ธฐ ์์ ; isQRScannerInitialised = ๊ฑฐ์ง; ํจ์ testQrCode(textBoxId,DivWidth){ ์๊ธฐ = ์ด๊ธฐํQRScanner(DivWidth); self.scanner.addListener('์ค์บ', ํจ์(๋ด์ฉ, ์ด๋ฏธ์ง) { if(textBoxId == $("#hiddenTextBox").val()){ ์ค๋์ค.์ฌ์(); var ์ฝ๋ = ๋ด์ฉ; $("#"+textBoxId).val(์ฝ๋); isQRScannerInitialised = ๊ฑฐ์ง; } }, ๊ฑฐ์ง); } ํจ์ ์ด๊ธฐํQRScanner(DivWidth){ ์๊ธฐ = ์ด๊ฒ; if(isQRScannerInitialised == ๊ฑฐ์ง){ var ์์ ๋น๋์ค = document.getElementsByTagName("๋น๋์ค")[0]; tempVideo.width=DivWidth; ์์ ๋น๋์ค.๋์ด=480; self.scanner = new Instascan.Scanner({ ๋น๋์ค: document.getElementsByTagName("๋น๋์ค")[0],mirror:false, scanPeriod: 1}); Instascan.Camera.getCameras().then(ํจ์(์นด๋ฉ๋ผ) { self.cameras = ์นด๋ฉ๋ผ; if (self.cameras.length > 0) { if(์นด๋ฉ๋ผ[0].name.match(/back/) || ์นด๋ฉ๋ผ[0].name.match(/Back/)){ self.activeCameraId = ์นด๋ฉ๋ผ[0].id; self.scanner.start(์นด๋ฉ๋ผ[0]); } else if(์นด๋ฉ๋ผ[1].name.match(/back/) || ์นด๋ฉ๋ผ[1].name.match(/Back/)){ self.activeCameraId = ์นด๋ฉ๋ผ[1].id; self.scanner.start(์นด๋ฉ๋ผ[1]); } isQRScannerInitialised = true; } ๋ ๋ค๋ฅธ { alert('์นด๋ฉ๋ผ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.'); isQRScannerInitialised = ๊ฑฐ์ง; ๋ฐํ; } }).catch(ํจ์(e) { isQRScannerInitialised = ๊ฑฐ์ง; alert("QR ์ค๋ฅ ์ด๋ฆ:-"+e.name + " & QR ์ค๋ฅ ๋ฉ์์ง:-"+e.message); console.error(e); }); } ์๊ธฐ ๋ฐํ; }
Apple ์ฅ์น์ ์ก์ธ์คํ ์ ์์ต๋๊น? ๋ฐ๋ชจ๊ฐ ์๋ํ๋์ง ์๊ณ ์์ต๋๊น?
์ด๊ฒ์ iOS ์ฌํ๋ฆฌ์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ฌ๋๋ค์ด ๋ฉํ ํ๊ทธ๋ฅผ ์ถ๊ฐํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ๊ทน๋ณตํ ์ ์๋ค๋ ๊ฒ์ ์ฝ์์ต๋๋ค. ์ด ํฌ๋ผ์ ๋๋ฌ๋ณด๋ฉด ์ ์ ์์ต๋๋ค. ๋น์ทํ ์ผ์ ํ๊ณ ์์ด์ ๊ด์ฌ์ด ์์ต๋๋ค. ์ ๋ฅผ ๋ง์ค์ด๊ฒ ํ๋ ๊ฒ์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ ์ฅ์น๊ฐ ์๋ค๋ ๊ฒ์ ๋๋ค.
iPhone์์ ๋ฐ๋ชจ๋ฅผ ์๋ํ์ง๋ง ์๋ํ์ง ์์์ต๋๋ค.
๋ค, ์ด ์ผ์ ํ๊ณ ์๋๋ฐ ์๋์ด ์ ๋ผ์. ๋์๊ฐ์ ์ค๋ ๋๋ฅผ ๋ค์ ์ฝ์ผ๋ ค๊ณ ํฉ๋๋ค. ์ต์ ์น RTC ์ด๋ํฐ๋ฅผ ์ถ๊ฐํ๊ณ ๋น๋์ค ํ๊ทธ์ _playsinline_ ์์ฑ์ ์ถ๊ฐํ์ฌ ์ ๋ฉด ์นด๋ฉ๋ผ๊ฐ ์๋ํ๋๋ก ํ์ต๋๋ค. ์นด๋ฉ๋ผ๋ฅผ ์ฝ์ ์ ์์ง๋ง ํ๋ฉด ์นด๋ฉ๋ผ๋ก ๊ต์ฒดํ ๋ ์๋ฌด ์์ ๋ ์ํํ์ง ์์ต๋๋ค.
๋๋ ๋น๋์ค ํ๊ทธ ์์ ์์ฑ์ ์ถ๊ฐํ๊ณ ๋ฉํ ํ๊ทธ๋ ์ธ๊ธํ์ต๋๋ค.
๋๋ ๋น๋์ค ํ๊ทธ ์์playsinline ์์ฑ์ ์ถ๊ฐํ๊ณ ๋ฉํ ํ๊ทธ๋ ์ธ๊ธํ์ต๋๋ค.
๋๊ตฐ๊ฐ ์ค์ ๋ก ์ค๋ ๋ ์ค ํ๋์์ ์ด๊ฒ์ ์์ ํ์ต๋๋ค. ์ง๊ธ ์๋ํ๊ณ ์์ง๋ง iPhone์ ์ฌ์ฉํ๋ ์ฌ๋์ด ์๋ํ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค.
์ด๋ด, ๋๋ ์ด๊ฒ์ ์๋ ์์ผฐ์ง๋ง ์ฌ์ ํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋๋ผ๋ ๊ธฐ๋ณธ๊ฐ์ ํญ์ ํ๋ฉด ํ๋ฉด ์นด๋ฉ๋ผ์ ๋๋ค. ๋ฐ๋ผ์ ์ ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ฌ๊ธฐ ๋ด๊ฐ ํ ์ผ์ด ์์ต๋๋ค!
๋ฉํ ํ๊ทธ๋ฅผ ์ถ๊ฐํ์ต๋๋ค.
<meta name="apple-mobile-web-app-capable" content="yes">
์ด ์์ฑ์ ์ถ๊ฐํ์ต๋๋ค.
<video id="scanner" class="video-back" playsinline></video>
์ด JS ํ์ผ์ ์ถ๊ฐํ์ต๋๋ค.
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
๊ทธ๋ฐ ๋ค์ ์ด๊ฒ์ ํจํค์งํ์ฌ ๋ฆด๋ฆฌ์คํฉ๋๋ค: https://github.com/JoseCDB/instascan/tree/ios-rear-camera. node.js์ ํจ๊ป Gulp๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๋์ง ํ์คํ์ง ์์ง๋ง ์ฝ์ต๋๋ค. 15๋ถ๋ง์ ๋ฒ์์ด์! ๋๋ Instascan์ ์ด ์ฌ๋ ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ๊ทธ๋ ๋ฌธ์ ๋ฅผ ์๊ณ ์์๊ณ ๊ณ ์น ์ ์์์ต๋๋ค. ๋์์ด ๋์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ํ์ด์ ๋น๋๋ค.
๋ฉํ ํ๊ทธ, ๋น๋์ค ํ๊ทธ ๋ฐ adapter-latest.js๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋๋ instscan.min.js๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ".js - scanner.js - camara.js"๋ฅผ ๋ณ๋๋ก ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
๋ฉํ ํ๊ทธ, ๋น๋์ค ํ๊ทธ ๋ฐ adapter-latest.js๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋๋ instscan.min.js๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ".js - scanner.js - camara.js"๋ฅผ ๋ณ๋๋ก ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
node.js๊ฐ ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค. ์ด๋ฌํ ๋ชจ๋ ํ์ผ์ ํจ๊ป ํจํค์งํ๋ ๋ช ๋ น ํ๋กฌํํธ๊ฐ ์์ผ๋ฉฐ ์ต์ข ์ถ๋ ฅ์ instascanner์ ์ถ์๋ JS ํ์ผ์ด ๋ฉ๋๋ค.
์ด๊ฒ์ ํ๋ฅญํ ์ ํ์ด๊ณ ์ ๋ง ์ ์ฉํ์ต๋๋ค. ๊ทธ๋์ ๋ฉ์ง๊ฒ ๋ง๋ค์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋ด ์ฐ๊ตฌ์์์ด instascan์ ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
_scanner.start(camera)_๋ฅผ ํธ์ถํ๋ฉด ์นด๋ฉ๋ผ ์์ _camera.start()_ ๋ฉ์๋๋ฅผ ํธ์ถํ๋
**This Part Is the Disconnect and what is messing it all up!**
์ ๋ฌ๋ Camera ๊ฐ์ฒด๋ ์ ์ฝ ์กฐ๊ฑด์์ ํด๋น ID ๋ฅผ ์ฅ์น ๊ฒ์์ _"ํ์"_๋ก ์ฌ์ฉํฉ๋๋ค. ์ฐพ์ ์ ์์ผ๋ฉด ๋น๋์ค๊ฐ ํ์๋์ง ์์ต๋๋ค. ๋ํ ๋ค๋ฅธ "ํ์" ์ ์ฝ ์กฐ๊ฑด์ด ์ค์ ๋ฉ๋๋ค.
๋ค๋ฅธ ์ฅ์น๋ ์ฌ์ฉ๋ ์ ์ฝ ์กฐ๊ฑด์ ์ง์ํ์ง ์์ต๋๋ค!
์ฌ์ฉํ๋ ค๋ ์ฅ์น์์ ์ด ๋งํฌ๋ฅผ ์คํํ๋ฉด ์ง์ํ๋ ์ ์ฝ ์กฐ๊ฑด์ด ๋ฌด์์ธ์ง ์๋ ค์ค๋๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints
์ฌ์ฉํ๋ ค๋ ์ฅ์น์์ ์ด ๋งํฌ๋ฅผ ์คํํ๊ณ ์ ์ฝ ์กฐ๊ฑด์ ์
๋ ฅํ์ญ์์ค. ์ง์ ์ฌ๋ถ๋ฅผ ์๋ ค์ค๋๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSupportedConstraints/deviceId
aspectRatio, facesMode, _deviceId * _ , ๋์ด, ๋๋น, aspectRatio ๋ฑ.
_๋ด๊ฐ ์ด๊ฒ์ ํ ์คํธํ ๋ _deviceId๋ ์ ์ฝ ์กฐ๊ฑด์ผ๋ก ๋ฌด์๋ฉ๋๋ค._ ์ ์ฝ ์กฐ๊ฑด ์ ๋ํด ์์ ๋งํฌ์์ ์ด๊ฒ์ ์๋ํ๋ฉด deviceId = ""๋ก ์ค์ ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์๋ฐ ์คํฌ๋ฆฝํธ์์ ์ก์์ ํ์ํ์ ๋ iphone์ ํญ์ ๋น deviceId๋ฅผ ๋ฐํํ์ต๋๋ค.
๋ฐ๋ผ์ Iphone์์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก์ผ๋ ค๋ฉด deviceId๋ฅผ ์ฌ์ฉํ์ง ์๊ณ faceMode๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
deviceId, _facingMode * _, aspectRatio, ๋์ด, ๋๋น ๋ฑ.
๋๋ ์ด๊ฒ์ ์ผ์ฑ ํ๋ธ๋ฆฟ๊ณผ ์๋๋ก์ด๋ ํฐ์์ ํ ์คํธํ๋ค. faceMode์ ๊ธฐ๋ณธ๊ฐ์ "์ฌ์ฉ์" ์ ๋ฉด ์นด๋ฉ๋ผ์ ๋๋ค. ์ด ์ฝ๋๋ฅผ ์คํํ ๊ฒฐ๊ณผ ์์ง๊น์ง ๋ฐ๊ฒฌํ ์ด๋ค ์ด์ ๋ก Android์ฉ facesMode๊ฐ ์๋ํ์ง ์๋๋ค๋ ์ฌ์ค์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์์ ๋งํฌ์์ ์๋ํฉ๋๋ค. ๋๋ ๊ทธ ๋ถ๋ถ์ ๊ณ์ ์กฐ์ฌํ ๊ฒ์ด๊ณ ์๋ง๋ ์ด ์ฝ๋๊ฐ facesMode ๋ฐ android์์ ์ ๋๋ก ์๋ํ๋๋ก ์์ ํ ๊ฒ์ ๋๋ค.
* * Android ๋ฌธ์ ์ ๋ํ ๋ต๋ณ * * *
์ด ํ๋ก์ ํธ์ Gulp ๋น๋์๋ Android Chrome์์ facesMode๋ฅผ ์๋ง์ผ๋ก ๋ง๋๋ webrtc-adapter ๋ฒ์ ^1.4.0์ด ํฌํจ๋์ด ์์ต๋๋ค. ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ์ค์ ๋ก ์ง๋ฉด ๋ชจ๋๋ฅผ ์ญ์ ํ์ต๋๋ค.
require('webrtc-adapter');
์ ๊ฑฐํ ๋ค์ ์๋ ๋น๋ ์ ์ฐจ๋ฅผ ๋ฐ๋ฅด์ธ์. Chrome์์ ํ๋ธ๋ฆฟ๊ณผ 4๊ฐ์ ๋ค๋ฅธ Android ํด๋์ ํ์์ ํ
์คํธํ์ ๋ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก๊ธฐ ์ํด ๋ชจ๋ ๋ค์ ์๋ํ์ต๋๋ค.์ด instascan ์ฝ๋๋ก Android์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก์ผ๋ ค๋ฉด deviceId๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
deviceId๊ฐ ๋ค์๊ณผ ๊ฐ์ _video_ ์ ์ฝ ์กฐ๊ฑด์ธ์ง ํ์ธํ์ญ์์ค.
video: {
devideId: this.id
}
๋ค์์ ์ ์ฝ ์กฐ๊ฑด์ ์ค์ ํ๊ณ MediaStream ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ํ๋ก์ ํธ์ ์ฝ๋์
๋๋ค.
์ด ์ฝ๋๊ฐ ์ ๋๋ก ์๋ํ์ง ์๋ ์ด์ ๋ _video ์ ์ฝ ์กฐ๊ฑด _ ์ sourceId๊ฐ _Android_ ๋๋ _Iphone_์์ ์ง์๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๊ฒ์ deviceId ๋ก ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค . ๋ํ ๋ชจ๋ ํ์ ํญ๋ชฉ์ ์ฅ์น๊ฐ ์ฒ๋ฆฌํ์ง ์๋ ๊ฒฝ์ฐ ์ด๋ํด์ผ ํฉ๋๋ค.
async start() {
let constraints;
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
if (iOS) {
constraints = {
audio: false,
video: {
facingMode: 'environment',
mandatory: {
sourceId: this.id,
minWidth: 600,
maxWidth: 800,
minAspectRatio: 1.6
},
optional: []
}
};
} else {
constraints = {
audio: false,
video: {
mandatory: {
sourceId: this.id,
minWidth: 600,
maxWidth: 800,
minAspectRatio: 1.6
},
optional: []
}
};
}
this._stream = await Camera._wrapErrors(async () => {
return await navigator.mediaDevices.getUserMedia(constraints);
});
์ด๊ฒ์ ์ป๊ณ ๋ณ๊ฒฝํ๊ธฐ ์ํด VSCode๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
1) Node.js์ vsCode๋ฅผ ์ค์นํฉ๋๋ค.
2) ๋ค์ด๋ก๋ํ๋ ค๋ ๋๋ ํ ๋ฆฌ์ ํฐ๋ฏธ๋์์ ๋ค์์ ์คํํฉ๋๋ค.
git clone https://github.com/JoseCDB/instascan.git
3) ํฐ๋ฏธ๋ cd์์ instascan ๋๋ ํ ๋ฆฌ๋ก:
cd instascan
4) ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ณ๊ฒฝํ๊ณ gulp๋ฅผ ์คํํ์ฌ ์ฝ๋๋ฅผ ํด์ ํฉ๋๋ค.
gulp release
5) ์ด๊ฒ์ _dist_ ํด๋์ ์๋ก์ด ์ถ์๋ instascan.min.js ํญ๋ชฉ์ ์ค ๊ฒ์ ๋๋ค.
์ด๋ฒ ์ฃผ๋ง์ ์ด Android ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ๋ฉ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ํฅํ ํ๋ก์ ํธ์ ๋ํ ์ถฉ๋ถํ ํต์ฐฐ๋ ฅ์ ์ป์ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์๋
ํ์ธ์, ์ด๊ฒ์ ์ ์๋ํด์ผํฉ๋๋ค.
๋จผ์ https://github.com/webrtc/adapter ์์ adapter.js ๋ฅผ ์ถ๊ฐ ํฉ๋๋ค.
๊ทธ ํ์ ์ด๊ฒ์ ๋ณต์ ํ์ญ์์ค.
git clone https://github.com/quocthai95/instascan.git
์ด์:
npm i
ํ์ํ์ ์ค์นํ๊ธฐ ์ํด
gulp๋ฅผ ์ฌ์ฉํ์ฌ ์ต์ข
์ฝ๋๋ฅผ ๋ฆด๋ฆฌ์คํฉ๋๋ค.
gulp release
Iphone 6 plus(iOS 11.4) ๋ฐ Iphone 8 plus(iOS 11.3)์์ ํ์ธํ๋๋ฐ ์ ์๋ํ์ต๋๋ค. ์นด๋ฉ๋ผ๋ฅผ ์ ์์ ์ผ๋ก ๊ต์ฒดํ ์ ์์ต๋๋ค.
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์๋ ํ์ธ์, ์ด๊ฒ์ ์ ์๋ํด์ผํฉ๋๋ค.
๋จผ์ https://github.com/webrtc/adapter ์์ adapter.js ๋ฅผ ์ถ๊ฐ ํฉ๋๋ค.๊ทธ ํ์ ์ด๊ฒ์ ๋ณต์ ํ์ญ์์ค.
git clone https://github.com/quocthai95/instascan.git
์ด์:
npm i
ํ์ํ์ ์ค์นํ๊ธฐ ์ํดgulp๋ฅผ ์ฌ์ฉํ์ฌ ์ต์ข ์ฝ๋๋ฅผ ๋ฆด๋ฆฌ์คํฉ๋๋ค.
gulp release
Iphone 6 plus(iOS 11.4) ๋ฐ Iphone 8 plus(iOS 11.3)์์ ํ์ธํ๋๋ฐ ์ ์๋ํ์ต๋๋ค. ์นด๋ฉ๋ผ๋ฅผ ์ ์์ ์ผ๋ก ๊ต์ฒดํ ์ ์์ต๋๋ค.
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
ํ์ํ์ ์ค์นํ ๋ "์ทจ์ฝ์ 12๊ฐ(๋ฎ์ 1๊ฐ, ๋ณดํต 5๊ฐ, ๋์ 6๊ฐ)"๊ฐ ๋ํ๋ฉ๋๋ค.
์ผ๋ถ "$ npm install --save-dev [package-name]" ๋ช
๋ น์ ์ด๋ฌํ ์ทจ์ฝ์ ์ ํด๊ฒฐํ๋ ๊ฒ์ผ๋ก ๋ณด์ด์ง๋ง ๋ค์ ์์ธ๋ก ์ธํด ๋น๋ํ ์ ์์ต๋๋ค.
$ gulp release assert.js:351 throw err; ^ AssertionError [ERR_ASSERTION]: ์์ ๊ธฐ๋ฅ์ Gulp.set [as _setTask]์ ์ง์ ๋์ด์ผ ํฉ๋๋ค(C:\Users\John\Downloads\instascan-ios-rear-camera\instascan-ios-rear-camera\node_modules\undertaker\lib \set-task.js:10:3)
์ฌ๊ธฐ์์ ์ด๋ป๊ฒ ์์ํฉ๋๊น? ์ด ๋น๋๋ฅผ ์ค์ ๋ก ์ฌ์ฉํด๋ณด๊ณ ์ถ์ต๋๋ค. ๋ด ์๋๋ก์ด๋ ํฐ๊ณผ ์ ์ด์ธ๋ฆฌ๋์?
/๋จ์
์๋
ํ์ธ์ @johnatitide ,
gulp ์ต์ ๋ฒ์ (4.0.0)์ ์ค์นํ์
จ์ต๋๊น? ๊ทธ๋ ๋ค๋ฉด 3.9.1๋ก ์ ํํ์ญ์์ค. ์ฐธ๊ณ ๋ก:
https://github.com/ampproject/docs/issues/793#issuecomment -354836162
๋๋ ๋น๋ํ๊ธฐ ์ํด ์ํํ ๋ช
๋ น์ ์ ๊ณตํ ์ ์์ต๋๋ค.
์๋ ํ์ธ์ @quocthai95
๋น๋๋ ๋ค์ ๋ช
๋ น์ผ๋ก ์๋ํฉ๋๋ค.
์์ ํด๋ก https://github.com/quocthai95/instascan.git
npm ์ค์น [email protected]
npm ๋๋
๊ฟ๊บฝ๊ฟ๊บฝ
์ด์ iPad ๋ฐ iPhone์ Safari์์ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ ์ ์์ต๋๋ค. ๋ฉ์ง.
์ ์ฝ ์กฐ๊ฑด ์์ ์ด schmich์ ์ ์ฅ์์ ๋ค์ ๋ณํฉ๋ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๊น?
์ ์ฝ ์กฐ๊ฑด ์์ ์ด schmich์ ์ ์ฅ์์ ๋ค์ ๋ณํฉ๋ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๊น?
์๋ก์ด pull ์์ฒญ์ ๋ง๋ค์์ต๋๋ค. ์ ์๋ฅผ ๊ธฐ๋ค๋ฆฌ์ธ์^^
@quocthai95 ์๋ ํ์ธ์, ive๋ https://github.com/schmich/instascan/issues/182#issuecomment -447198290์์ ๊ทํ์ ๋จ๊ณ๋ฅผ ๋ฐ๋์ต๋๋ค.
๋ด ์๋๋ก์ด๋ ํฌ๋กฌ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ป๊ณ ์๋์ง ๊ถ๊ธํฉ๋๋ค. ํ๋ฐฉ์นด๋ฉ๋ผ๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ํ๋ ๋ฐฉ๋ฒ์ด ๊ถ๊ธํฉ๋๋ค. ์์ ์ฝ๋๊ฐ ์์ต๋๊น?
@fariskas ,
regexp๋ฅผ ์ฌ์ฉํ์ฌ /back/๊ณผ ์ผ์นํ๋์ง ํ
์คํธํ ๋ค์ ์์ํ๋ฉด ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
`Instascan.Camera.getCameras().then(ํจ์(์นด๋ฉ๋ผ) {
if(์นด๋ฉ๋ผ[0].name.match(/back/i)){
Scanner.start(์นด๋ฉ๋ผ[0]);
} else if(์นด๋ฉ๋ผ[1].name.match(/back/i)){
Scanner.start(์นด๋ฉ๋ผ[1]);
}
}
์ด๊ฒ์ ์ ์ฉํ ์ ์์ต๋๋ค: cameras[i].name
์์ "๋ค๋ก"๋ฅผ ์ฐพ๊ธฐ ์ํด for ๋ฃจํ๋ฅผ ์ฌ์ฉํ๊ณ ์์ง๋ง cameras[i].name
๋ฅผ console.log
์ธ ๋๊น์ง iPad์์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ ์ ์์๊ณ ์คํจํ์ต๋๋ค.
๋ฐ๋ผ์ iOS์์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋ ๋ฐ ์คํจํ๋ฉด "back"์ ๋ฒ์ญํ๊ฑฐ๋ cameras[i].name
๋ฅผ console.log
๋ก ์์ฑํ์ฌ ํ๋ฉด ์นด๋ฉ๋ผ์ ์ด๋ฆ์ด ๋ฌด์์ธ์ง ์์๋ณด์ธ์.
๋ฐ๋ชจ๊ฐ ์ ๋ฉด ์นด๋ฉ๋ผ์์๋ง ์๋ํ๋์ง ํ์ธํ ์ ์์ต๋๋ค. ์ด๊ฒ์ iOS 12.2์ Safari์ ๊ด๋ จ์ด ์์ต๋๋ค.
iOS 12+์์ Safari์ ํจ๊ป ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ธ ์ฌ๋์ด ์์ต๋๊น?
iOS 12+์์ Safari์ ํจ๊ป ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ธ ์ฌ๋์ด ์์ต๋๊น?
์ ๋ ์ฝ 7๊ฐ์ ๋์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ ๋ ๋ฒ์ ์ 30๊ฐ ์ด์์ ์ ํ์ ios ๋ฐ Android ํด๋ํฐ ๋ฐ ํ๋ธ๋ฆฟ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์์ ์ค์ธ OS์์ ์นด๋ฉ๋ผ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์์ ๋ ๋ฒ์ ์ ๋ํด ์์ ๋จ๊ธด ๋๊ธ์ ํ์ธํ์ธ์. ๋๊ธ์ ์ดํ์ webrtc๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ๊ณ์ ์ด์ผ๊ธฐํ๋๋ฐ, ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฒด ๋ฌธ์ ์ธ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
ํ๋ก์ ํธ์์ webrtc๋ฅผ ์์ ํ ์ ๊ฑฐํ๊ณ ๋ค์ ์ปดํ์ผํ์ต๋๋ค. webrtc๋ es5 ์ด์์ผ๋ก ํธ๋์คํ์ผ๋ ๋ ์ด ์ฝ๋์ ํจ๊ป ๋ ์ด์ ํ์ํ์ง ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ webrtc๋ฅผ ์ฌ์ฉํ๊ณ ์ฝ๋ฉ ๋ฐฉ์์ผ๋ก ์ธํด ์ฌ๋ฐ๋ฅธ ์นด๋ฉ๋ผ๋ฅผ ๊ฒ์ํ ์ ์์์ต๋๋ค.
ํ๋์ ์ฌ์ฉํ๊ณ ์๋ ๊ณ ์ ๋ฐ ํธ๋์คํ์ผ๋ ์ผ๋ฐ ๋ฐ ์ถ์๋ js ํ์ผ์ ํฌํจํ์ต๋๋ค. ์ ๋ ํ์๊ณผ ๊ต์ฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์ ํ๊ธฐ์์ QrCode๋ก ํ๊ต ์ถ์์ ์ฌ์ฉํฉ๋๋ค. ์ด ์ ํ๊ธฐ๋ ํ์ฌ ์ฝ 30๊ฐ ์ด์์ ๋ชจ๋ธ์ ๋๋ค. ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
์ด๊ฒ ๋์์ด ๋๊ธธ ๋ฐ๋๋ค.
ํ๋ฉด ์นด๋ฉ๋ผ ์ฝ๋
```
์ค์บ๋ = ์๋ก์ด Instascan.Scanner({ ๋น๋์ค: ๋น๋์ค, scanPeriod: 4, ๋ฏธ๋ฌ: false })
.then(handleSuccess)
.catch(ํธ๋ค์ค๋ฅ);
//์ค์บ ์์
Scanner.addListener('scan', foundCode);
Instascan.Camera.getCameras().then(function (cameras) {
if (cameras.length > 0) {
scanner.start(cameras[0]);
}
else {
...
}
}).catch (function (e) {
...
});
https://github.com/schmich/instascan/issues/182#issuecomment -443388022
์ด๊ฒ์ ํ๋ฅญํ ์ ํ์ด๊ณ ์ ๋ง ์ ์ฉํ์ต๋๋ค. ๊ทธ๋์ ๋ฉ์ง๊ฒ ๋ง๋ค์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋ด ์ฐ๊ตฌ์์์ด instascan์ ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- getCameras๋ฅผ ํธ์ถํ ๋ Camera ํด๋์ค๋ navigator.mediaDevices.enumerateDevices() ํธ์ถ์ ํตํด ์์ง๋ MediaDeviceInfo ๊ฐ์ฒด์์ ์์ฑ๋ Camera ๊ฐ์ฒด ์ปฌ๋ ์ ์ ๋ฐํํฉ๋๋ค. ์ค์บ๋๋ฅผ ์์ํ ๋ ์ฌ์ฉ๋ ์นด๋ฉ๋ผ์ ์ค์ ์คํธ๋ฆผ์ ํฌํจํ๋ MediaStream ๊ฐ์ฒด๊ฐ id _ ๋ฐ _ name _ ์์ฑ๋ง ํฌํจ๋์ด ์์ต๋๋ค. Camera ๊ฐ์ฒด์ ๋ฐฐ์ด์ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
_scanner.start(camera)_๋ฅผ ํธ์ถํ๋ฉด ์นด๋ฉ๋ผ ์์ _camera.start()_ ๋ฉ์๋๋ฅผ ํธ์ถํ๋
- ์ MediaStream์ Arrary๋ฅผ ๋ฐํ _camera.start () _ ๋ฐฉ๋ฒ์ ๋ค์ _navigator.mediaDevices.getUserMedia (์ ์ฝ ์กฐ๊ฑด)๋ฅผ ํธ์ถ _๋ ๋ฐฉ๋ฒ์ ๋์ด๋ ์ฃผ์ด์ง ์ ์ฝ ์กฐ๊ฑด์ ๋ฐ๋ผ ๊ฐ์ฒด.
- _scanner.start()_๋ _scanner._enableScan(camera)_์ ํธ์ถํ์ฌ ์นด๋ฉ๋ผ์์ ์์ ํธ์ถ์์ ๋ฐํ๋ ์ฒซ ๋ฒ์งธ MediaStream ๊ฐ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค. src ์์๋ฅผ ์ด ๋ฏธ๋์ด ์คํธ๋ฆผ ๊ฐ์ฒด๋ก ์ค์ ํฉ๋๋ค.
**This Part Is the Disconnect and what is messing it all up!**
์ ์ฝ ๋ฌธ์ :
์ ๋ฌ๋ Camera ๊ฐ์ฒด๋ ์ ์ฝ ์กฐ๊ฑด์์ ํด๋น ID ๋ฅผ ์ฅ์น ๊ฒ์์ _"ํ์"_๋ก ์ฌ์ฉํฉ๋๋ค. ์ฐพ์ ์ ์์ผ๋ฉด ๋น๋์ค๊ฐ ํ์๋์ง ์์ต๋๋ค. ๋ํ ๋ค๋ฅธ "ํ์" ์ ์ฝ ์กฐ๊ฑด์ด ์ค์ ๋ฉ๋๋ค.
๋ค๋ฅธ ์ฅ์น๋ ์ฌ์ฉ๋ ์ ์ฝ ์กฐ๊ฑด์ ์ง์ํ์ง ์์ต๋๋ค!
์ฌ์ฉํ๋ ค๋ ์ฅ์น์์ ์ด ๋งํฌ๋ฅผ ์คํํ๋ฉด ์ง์ํ๋ ์ ์ฝ ์กฐ๊ฑด์ด ๋ฌด์์ธ์ง ์๋ ค์ค๋๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints์ฌ์ฉํ๋ ค๋ ์ฅ์น์์ ์ด ๋งํฌ๋ฅผ ์คํํ๊ณ ์ ์ฝ ์กฐ๊ฑด์ ์ ๋ ฅํ์ญ์์ค. ์ง์ ์ฌ๋ถ๋ฅผ ์๋ ค์ค๋๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSupportedConstraints/deviceIdIpad/Iphone/IOS ์ง์ ์ ์ฝ:
aspectRatio, facesMode, _deviceId * _ , ๋์ด, ๋๋น, aspectRatio ๋ฑ.
_๋ด๊ฐ ์ด๊ฒ์ ํ ์คํธํ ๋ _deviceId๋ ์ ์ฝ ์กฐ๊ฑด์ผ๋ก ๋ฌด์๋ฉ๋๋ค._ ์ ์ฝ ์กฐ๊ฑด ์ ๋ํด ์์ ๋งํฌ์์ ์ด๊ฒ์ ์๋ํ๋ฉด deviceId = ""๋ก ์ค์ ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์๋ฐ ์คํฌ๋ฆฝํธ์์ ์ก์์ ํ์ํ์ ๋ iphone์ ํญ์ ๋น deviceId๋ฅผ ๋ฐํํ์ต๋๋ค.
๋ฐ๋ผ์ Iphone์์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก์ผ๋ ค๋ฉด deviceId๋ฅผ ์ฌ์ฉํ์ง ์๊ณ faceMode๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Android ์ง์ ์ ์ฝ:
deviceId, _facingMode * _, aspectRatio, ๋์ด, ๋๋น ๋ฑ.
๋๋ ์ด๊ฒ์ ์ผ์ฑ ํ๋ธ๋ฆฟ๊ณผ ์๋๋ก์ด๋ ํฐ์์ ํ ์คํธํ๋ค. faceMode์ ๊ธฐ๋ณธ๊ฐ์ "์ฌ์ฉ์" ์ ๋ฉด ์นด๋ฉ๋ผ์ ๋๋ค. ์ด ์ฝ๋๋ฅผ ์คํํ ๊ฒฐ๊ณผ ์์ง๊น์ง ๋ฐ๊ฒฌํ ์ด๋ค ์ด์ ๋ก Android์ฉ facesMode๊ฐ ์๋ํ์ง ์๋๋ค๋ ์ฌ์ค์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์์ ๋งํฌ์์ ์๋ํฉ๋๋ค. ๋๋ ๊ทธ ๋ถ๋ถ์ ๊ณ์ ์กฐ์ฌํ ๊ฒ์ด๊ณ ์๋ง๋ ์ด ์ฝ๋๊ฐ facesMode ๋ฐ android์์ ์ ๋๋ก ์๋ํ๋๋ก ์์ ํ ๊ฒ์ ๋๋ค.
* _ * Android ๋ฌธ์ ์ ๋ํ ๋ต๋ณ * _ **
์ด ํ๋ก์ ํธ์ Gulp ๋น๋์๋ Android Chrome์์ facesMode๋ฅผ ์๋ง์ผ๋ก ๋ง๋๋ webrtc-adapter ๋ฒ์ ^1.4.0์ด ํฌํจ๋์ด ์์ต๋๋ค. ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ์ค์ ๋ก ์ง๋ฉด ๋ชจ๋๋ฅผ ์ญ์ ํ์ต๋๋ค.
- ์ด ํ๋ก์ ํธ์์ ์์ ํ๋ ค๋ฉด - _index.js_์์ 2ํ
require('webrtc-adapter');
์ ๊ฑฐํ ๋ค์ ์๋ ๋น๋ ์ ์ฐจ๋ฅผ ๋ฐ๋ฅด์ธ์. Chrome์์ ํ๋ธ๋ฆฟ๊ณผ 4๊ฐ์ ๋ค๋ฅธ Android ํด๋์ ํ์์ ํ ์คํธํ์ ๋ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก๊ธฐ ์ํด ๋ชจ๋ ๋ค์ ์๋ํ์ต๋๋ค.์ด instascan ์ฝ๋๋ก Android์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก์ผ๋ ค๋ฉด deviceId๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
deviceId๊ฐ ๋ค์๊ณผ ๊ฐ์ _video_ ์ ์ฝ ์กฐ๊ฑด์ธ์ง ํ์ธํ์ญ์์ค.video: { devideId: this.id }
์นด๋ฉ๋ผ ์ ์ฝ ์ฝ๋:
๋ค์์ ์ ์ฝ ์กฐ๊ฑด์ ์ค์ ํ๊ณ MediaStream ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ํ๋ก์ ํธ์ ์ฝ๋์ ๋๋ค.
์ด ์ฝ๋๊ฐ ์ ๋๋ก ์๋ํ์ง ์๋ ์ด์ ๋ _video ์ ์ฝ ์กฐ๊ฑด _ ์ sourceId๊ฐ _Android_ ๋๋ _Iphone_์์ ์ง์๋์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๊ฒ์ deviceId ๋ก ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค . ๋ํ ๋ชจ๋ ํ์ ํญ๋ชฉ์ ์ฅ์น๊ฐ ์ฒ๋ฆฌํ์ง ์๋ ๊ฒฝ์ฐ ์ด๋ํด์ผ ํฉ๋๋ค.async start() { let constraints; var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; if (iOS) { constraints = { audio: false, video: { facingMode: 'environment', mandatory: { sourceId: this.id, minWidth: 600, maxWidth: 800, minAspectRatio: 1.6 }, optional: [] } }; } else { constraints = { audio: false, video: { mandatory: { sourceId: this.id, minWidth: 600, maxWidth: 800, minAspectRatio: 1.6 }, optional: [] } }; } this._stream = await Camera._wrapErrors(async () => { return await navigator.mediaDevices.getUserMedia(constraints); });
InstaScan์ ์์ ํ๊ณ ์ถ์ํ๋ ๋ฐฉ๋ฒ:
์ด๊ฒ์ ์ป๊ณ ๋ณ๊ฒฝํ๊ธฐ ์ํด VSCode๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
- Node.js ๋ฐ vsCode๋ฅผ ์ค์นํฉ๋๋ค.
- ๋ค์ด๋ก๋ํ๋ ค๋ ๋๋ ํ ๋ฆฌ์ ํฐ๋ฏธ๋์์ ๋ค์์ ์คํํ์ญ์์ค.
git clone https://github.com/JoseCDB/instascan.git
- ํฐ๋ฏธ๋ cd์์ instascan ๋๋ ํ ๋ฆฌ๋ก:
cd instascan
- ์๋ฐ ์คํฌ๋ฆฝํธ๋ฅผ ๋ณ๊ฒฝํ๊ณ gulp๋ฅผ ์คํํ์ฌ ์ฝ๋๋ฅผ ํด์ ํ์ญ์์ค.
gulp release
- ์ด๋ ๊ฒ ํ๋ฉด _dist_ ํด๋์ ์ถ์๋ ์ instascan.min.js ํญ๋ชฉ์ด ์ ๊ณต๋ฉ๋๋ค.
์ด๋ฒ ์ฃผ๋ง์ ์ด Android ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ๋ฉ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ํฅํ ํ๋ก์ ํธ์ ๋ํ ์ถฉ๋ถํ ํต์ฐฐ๋ ฅ์ ์ป์ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์์ ๋จ๊ณ๋ฅผ ์ํํ ๋ค์ ํ์ผ camera.js (29ํ)๋ฅผ ์๋์ ๊ฐ์ด ํธ์งํฉ๋๋ค.
facingMode: { exact: "environment" },
๊ทธ๊ฒ์ ๋๋ฅผ ์ํด ์๋ํฉ๋๋ค. @apchandler ๊ฐ์ฌํฉ๋๋ค
๋น์ ์ ์ํด ์ผํ ์ผ์ด ์๊ฒจ์ ๊ธฐ์ฉ๋๋ค! ์ด ์์ ์ฌํญ์ ๊ฒ์ํด ์ฃผ์ @glorynguyen์๊ฒ๋ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
๋ถํํ๋ ์ด๋ฌํ ์๋ฃจ์
์ iOS 13์์ ์๋ํ์ง ์์ต๋๋ค. ๋จ์ํ ๋น์ด ์์ต๋๋ค(๊ฒ์์๋ ์๋).
Safari๋ฅผ ์๊ฒฉ ๋๋ฒ๊น
ํ ๋๋ ์ฝ์์ ์ค๋ฅ๊ฐ ํ์๋์ง ์์ต๋๋ค.
iOS 12+์์ Safari์ ํจ๊ป ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ธ ์ฌ๋์ด ์์ต๋๊น?
์ ๋ ์ฝ 7๊ฐ์ ๋์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ ๋ ๋ฒ์ ์ 30๊ฐ ์ด์์ ์ ํ์ ios ๋ฐ Android ํด๋ํฐ ๋ฐ ํ๋ธ๋ฆฟ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์์ ์ค์ธ OS์์ ์นด๋ฉ๋ผ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์์ ๋ ๋ฒ์ ์ ๋ํด ์์ ๋จ๊ธด ๋๊ธ์ ํ์ธํ์ธ์. ๋๊ธ์ ์ดํ์ webrtc๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ๊ณ์ ์ด์ผ๊ธฐํ๋๋ฐ, ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฒด ๋ฌธ์ ์ธ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
ํ๋ก์ ํธ์์ webrtc๋ฅผ ์์ ํ ์ ๊ฑฐํ๊ณ ๋ค์ ์ปดํ์ผํ์ต๋๋ค. webrtc๋ es5 ์ด์์ผ๋ก ํธ๋์คํ์ผ๋ ๋ ์ด ์ฝ๋์ ํจ๊ป ๋ ์ด์ ํ์ํ์ง ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ webrtc๋ฅผ ์ฌ์ฉํ๊ณ ์ฝ๋ฉ ๋ฐฉ์์ผ๋ก ์ธํด ์ฌ๋ฐ๋ฅธ ์นด๋ฉ๋ผ๋ฅผ ๊ฒ์ํ ์ ์์์ต๋๋ค.
ํ๋์ ์ฌ์ฉํ๊ณ ์๋ ๊ณ ์ ๋ฐ ํธ๋์คํ์ผ๋ ์ผ๋ฐ ๋ฐ ์ถ์๋ js ํ์ผ์ ํฌํจํ์ต๋๋ค. ์ ๋ ํ์๊ณผ ๊ต์ฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์ ํ๊ธฐ์์ QrCode๋ก ํ๊ต ์ถ์์ ์ฌ์ฉํฉ๋๋ค. ์ด ์ ํ๊ธฐ๋ ํ์ฌ ์ฝ 30๊ฐ ์ด์์ ๋ชจ๋ธ์ ๋๋ค. ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
์ด๊ฒ ๋์์ด ๋๊ธธ ๋ฐ๋๋ค.
ํ๋ฉด ์นด๋ฉ๋ผ ์ฝ๋
scanner = new Instascan.Scanner({ video: video, scanPeriod: 4, mirror:false }) .then(handleSuccess) .catch(handleError); //Start scanning scanner.addListener('scan', foundCode); Instascan.Camera.getCameras().then(function (cameras) { if (cameras.length > 0) { scanner.start(cameras[0]); } else { ... } }).catch (function (e) { ... });
์ด๊ฒ์ ๋ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ๋๋จํ ๊ฐ์ฌํฉ๋๋ค.
์ด์ ๋ํ ์ต์ ์์ ์ฌํญ์ ๋ฌด์์
๋๊น? ์ค๋ ๋์์ ๋ช ๊ฐ์ง๋ฅผ ์๋ํ์ง๋ง ์ ๋ฉด ์นด๋ฉ๋ผ๋ง ์ป๋ ๊ฒ ๊ฐ์ต๋๋ค.
Gulp๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ค์ ๋ก .js .git ํ๋ก์ ํธ๋ฅผ ์ปดํ์ผํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ
๋๋ค. ์ ๋ ์ฃผ๋ก C#/Asp.net Mvc๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ฏ๋ก ์ด๊ฒ์ ์ ์๊ฒ ์ฝ๊ฐ ์๋กญ์ต๋๋ค.
apchandler์ ์๋ฃจ์
์ ๋์๊ฒ ์ค๋ฅ๋ฅผ ์ ๊ณตํฉ๋๋ค. (๋์์์ด ์ ์๋์ง ์์)
ํ์ฌ Android ๊ธฐ๊ธฐ์ฉ "๊ณ ์ " instascan.min.js์ IOS์ฉ ๋ฒ์ ์ ๋ก๋ํ๊ณ ์์ง๋ง ์ ๋๋ก ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด์ ๋ํ ์ต์ ์์ ์ฌํญ์ ๋ฌด์์ ๋๊น? ์ค๋ ๋์์ ๋ช ๊ฐ์ง๋ฅผ ์๋ํ์ง๋ง ์ ๋ฉด ์นด๋ฉ๋ผ๋ง ์ป๋ ๊ฒ ๊ฐ์ต๋๋ค.
Gulp๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ค์ ๋ก .js .git ํ๋ก์ ํธ๋ฅผ ์ปดํ์ผํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ ๋๋ค. ์ ๋ ์ฃผ๋ก C#/Asp.net Mvc๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ฏ๋ก ์ด๊ฒ์ ์ ์๊ฒ ์ฝ๊ฐ ์๋กญ์ต๋๋ค.
apchandler์ ์๋ฃจ์ ์ ๋์๊ฒ ์ค๋ฅ๋ฅผ ์ ๊ณตํฉ๋๋ค. (๋์์์ด ์ ์๋์ง ์์)
ํ์ฌ Android ๊ธฐ๊ธฐ์ฉ "๊ณ ์ " instascan.min.js์ IOS์ฉ ๋ฒ์ ์ ๋ก๋ํ๊ณ ์์ง๋ง ์ ๋๋ก ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
html ๋น๋์ค ์์๊ฐ ์์ต๋๊น?
```
When you run instascan you need to speficy a video element like:
var ์๊ธฐ = ์ด๊ฒ;
self.scanner = new Instascan.Scanner({ ๋น๋์ค: document.getElementById('๋ฏธ๋ฆฌ๋ณด๊ธฐ'), scanPeriod: 5 });
self.scanner.addListener('์ค์บ', ํจ์(๋ด์ฉ, ์ด๋ฏธ์ง) {
self.scans.unshift({ ๋ ์ง: +(๋ ์ง.now()), ๋ด์ฉ: ๋ด์ฉ });
});
Instascan.Camera.getCameras().then(ํจ์(์นด๋ฉ๋ผ) {
self.cameras = ์นด๋ฉ๋ผ;
if (์นด๋ฉ๋ผ ๊ธธ์ด > 0) {
self.activeCameraId = ์นด๋ฉ๋ผ[0].id;
self.scanner.start(์นด๋ฉ๋ผ[0]);
} ๋ ๋ค๋ฅธ {
console.error('์นด๋ฉ๋ผ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.');
}
}).catch(ํจ์(e) {
console.error(e);
});
```
์, ๋ค์๊ณผ ๊ฐ์ด ์๋ํฉ๋๋ค.
<video class="player" style="max-width:100%" id="preview" playsinline></video>
<script>
.....
Instascan.Camera.getCameras().then(function (cameras) {
if (cameras.length > 0) {
scanner.start(cameras[0]);
} else {
console.error('No cameras found.');
}
}).catch(function (e) {
console.error(e);
});
</script>
Iphone/Ios ๊ธฐ๊ธฐ์ฉ ์นด๋ฉ๋ผ[0] ์์ ์ค. ์๋๋ก์ด๋์ฉ:
<script>
.....
Instascan.Camera.getCameras().then(function (cameras) {
if (cameras.length > 0) {
var selectedCam = cameras[0];
$.each(cameras, (i, c) => {
if (c.name.indexOf('back') != -1) {
selectedCam = c;
return false;
}
});
scanner.start(selectedCam);
}
else {
console.error('No cameras found.');
}
});
</script>
๋ฌธ์ ๋ "iphone"์ด ์๋ Request.UserAgent.Contains("ios")๋ง ํ์ธํ๊ธฐ ๋๋ฌธ์ Iphone์ฉ Android ์คํฌ๋ฆฝํธ๋ ์คํํ ๊ฒ ๊ฐ์ต๋๋ค.
์์๋์๋ฉด ์ข์ต๋๋ค. ์ ๋ณด์ ๋ํด์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
@apchandler ์๋ ํ์ธ์, '๋ฉ์ธ' ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์ด ์๋์ง ์์ญ๋๊น?
๋ด ์ฌ์ฉ์๊ฐ instascan์ ์ฌ์ฉํ์ฌ QR ์ฝ๋๋ฅผ ์ค์บํ๋ ์น์ฌ์ดํธ๊ฐ ์์ต๋๋ค. ์ ๋ ์น์ฌ์ดํธ๋ฅผ ๊ฐ๋ฐ ์ค์ด๋ฉฐ 4๊ฐ์ ํ๋ฉด ์นด๋ฉ๋ผ(HUAWEI P30 PRO)๊ฐ ์๋ ๋ชจ๋ฐ์ผ ์ ํ๋ฅผ ์ฌ์ฉํ์ฌ ์น์ฌ์ดํธ์ ์ก์ธ์คํ๋ ๋ช ๊ฐ์ง ํ ์คํธ๋ฅผ ์ํํ๊ณ ์์ต๋๋ค.
๋๋ $.each๋ฅผ ์๋ํ๊ณ ์ฒซ ๋ฒ์งธ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ ์ํ์์ ์์ผ๊ฐ ๋๋ฌด ํ๋ฆฟํ๊ณ ๋ง์ ์ค์ผ๋ก ์ธํด ์๋ฌด๊ฒ๋ ์ค์บํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์นด๋ฉ๋ผ[2]๋ฅผ ์ ํํ๋ฉด ๋ชจ๋ ๊ฒ์ ์ค์บํ ์ ์์ต๋๋ค.
'๋ฉ์ธ' ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
๋ด ์น ์ฑ์ ๋ค๋ฅธ ํด๋ ์ ํ, ๋ค๋ฅธ ์์ ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์ฌ์ฉํ ๊ฒ์ด๋ฉฐ ์นด๋ฉ๋ผ์ ์์๋ ๋ค๋ฅผ ๊ฒ์ ๋๋ค.
์๋๋ฉด ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๊ณ ์ฌ์ฉ์๊ฐ ์์ ์๊ฒ ์๋ฒฝํ๊ฒ ์๋ํ๋ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋๋ก ํ์๊ฒ ์ต๋๊น?
๊ฐ์ฌ ํด์
@apchandler ์๋ ํ์ธ์, '๋ฉ์ธ' ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์ด ์๋์ง ์์ญ๋๊น?
๋ด ์ฌ์ฉ์๊ฐ instascan์ ์ฌ์ฉํ์ฌ QR ์ฝ๋๋ฅผ ์ค์บํ๋ ์น์ฌ์ดํธ๊ฐ ์์ต๋๋ค. ์ ๋ ์น์ฌ์ดํธ๋ฅผ ๊ฐ๋ฐ ์ค์ด๋ฉฐ 4๊ฐ์ ํ๋ฉด ์นด๋ฉ๋ผ(HUAWEI P30 PRO)๊ฐ ์๋ ๋ชจ๋ฐ์ผ ์ ํ๋ฅผ ์ฌ์ฉํ์ฌ ์น์ฌ์ดํธ์ ์ก์ธ์คํ๋ ๋ช ๊ฐ์ง ํ ์คํธ๋ฅผ ์ํํ๊ณ ์์ต๋๋ค.
๋๋ $.each๋ฅผ ์๋ํ๊ณ ์ฒซ ๋ฒ์งธ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ ์ํ์์ ์์ผ๊ฐ ๋๋ฌด ํ๋ฆฟํ๊ณ ๋ง์ ์ค์ผ๋ก ์ธํด ์๋ฌด๊ฒ๋ ์ค์บํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์นด๋ฉ๋ผ[2]๋ฅผ ์ ํํ๋ฉด ๋ชจ๋ ๊ฒ์ ์ค์บํ ์ ์์ต๋๋ค.
'๋ฉ์ธ' ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
๋ด ์น ์ฑ์ ๋ค๋ฅธ ํด๋ ์ ํ, ๋ค๋ฅธ ์์ ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์ฌ์ฉํ ๊ฒ์ด๋ฉฐ ์นด๋ฉ๋ผ์ ์์๋ ๋ค๋ฅผ ๊ฒ์ ๋๋ค.
์๋๋ฉด ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๊ณ ์ฌ์ฉ์๊ฐ ์์ ์๊ฒ ์๋ฒฝํ๊ฒ ์๋ํ๋ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋๋ก ํ์๊ฒ ์ต๋๊น?
๊ฐ์ฌ ํด์
๋ฏธ์ ํด์. ์ฌ๋ฌ ๋๊ฐ ์์ ๋ '๋ฉ์ธ' ์นด๋ฉ๋ผ๋ก ์ง์ ํ๋ ๊ฐ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์นด๋ฉ๋ผ ์ ํ ๊ธฐ๋ฅ์ ์ต์ํ ํน์ ํด์๋ ๋ฐ ๊ธฐํ ์ฌ์์ด ์์ด์ผ ํจ์ ์ง์ ํ๋ ๊ธฐ์ค ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ต์ํ์ ๋ฅ๋ ฅ์ ๊ฐ์ถ ์นด๋ฉ๋ผ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ฃจ์ ์ด ์ ๊ทผํ๋ ค๋ ๋ฐฉ์์ ์ ํฉํฉ๋๋ค.
@apchandler ์๋ ํ์ธ์, '๋ฉ์ธ' ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์ด ์๋์ง ์์ญ๋๊น?
๋ด ์ฌ์ฉ์๊ฐ instascan์ ์ฌ์ฉํ์ฌ QR ์ฝ๋๋ฅผ ์ค์บํ๋ ์น์ฌ์ดํธ๊ฐ ์์ต๋๋ค. ์ ๋ ์น์ฌ์ดํธ๋ฅผ ๊ฐ๋ฐ ์ค์ด๋ฉฐ 4๊ฐ์ ํ๋ฉด ์นด๋ฉ๋ผ(HUAWEI P30 PRO)๊ฐ ์๋ ๋ชจ๋ฐ์ผ ์ ํ๋ฅผ ์ฌ์ฉํ์ฌ ์น์ฌ์ดํธ์ ์ก์ธ์คํ๋ ๋ช ๊ฐ์ง ํ ์คํธ๋ฅผ ์ํํ๊ณ ์์ต๋๋ค.
๋๋ $.each๋ฅผ ์๋ํ๊ณ ์ฒซ ๋ฒ์งธ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ ์ํ์์ ์์ผ๊ฐ ๋๋ฌด ํ๋ฆฟํ๊ณ ๋ง์ ์ค์ผ๋ก ์ธํด ์๋ฌด๊ฒ๋ ์ค์บํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์นด๋ฉ๋ผ[2]๋ฅผ ์ ํํ๋ฉด ๋ชจ๋ ๊ฒ์ ์ค์บํ ์ ์์ต๋๋ค.
'๋ฉ์ธ' ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
๋ด ์น ์ฑ์ ๋ค๋ฅธ ํด๋ ์ ํ, ๋ค๋ฅธ ์์ ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์ฌ์ฉํ ๊ฒ์ด๋ฉฐ ์นด๋ฉ๋ผ์ ์์๋ ๋ค๋ฅผ ๊ฒ์ ๋๋ค.
์๋๋ฉด ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๊ณ ์ฌ์ฉ์๊ฐ ์์ ์๊ฒ ์๋ฒฝํ๊ฒ ์๋ํ๋ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๋๋ก ํ์๊ฒ ์ต๋๊น?
๊ฐ์ฌ ํด์๋ฏธ์ ํด์. ์ฌ๋ฌ ๋๊ฐ ์์ ๋ '๋ฉ์ธ' ์นด๋ฉ๋ผ๋ก ์ง์ ํ๋ ๊ฐ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์นด๋ฉ๋ผ ์ ํ ๊ธฐ๋ฅ์ ์ต์ํ ํน์ ํด์๋ ๋ฐ ๊ธฐํ ์ฌ์์ด ์์ด์ผ ํจ์ ์ง์ ํ๋ ๊ธฐ์ค ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ต์ํ์ ๋ฅ๋ ฅ์ ๊ฐ์ถ ์นด๋ฉ๋ผ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ฃจ์ ์ด ์ ๊ทผํ๋ ค๋ ๋ฐฉ์์ ์ ํฉํฉ๋๋ค.
๋ต๋ณํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค! ํด์๋๋ก ๋ ธ๋ ฅํ๊ฒ ์ต๋๋ค. Instascan์ ์นด๋ฉ๋ผ A์ ํด์๋๋ฅผ ๋ฐํํ ์ ์์ต๋๊น?
@glorynguyen ๋ฐ @apchandler๊ฐ ์ ๊ณตํ ๋ฐฉ๋ฒ์ ๋ฐ๋ฅด๋ฉด.
์ด์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ผค ์ ์์ต๋๋ค.
instascan.min ์์
์ ์
case 0:return i={audio:!1,video:{mandatory:{sourceId:this.id,minWidth:600,maxWidth:800,minAspectRatio:1.6},optional:[]}}
ํ์
case 0:return i=(/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream)?{audio:!1,video:{facingMode:{exact:"environment"},mandatory:{sourceId:this.id,minWidth:600,maxWidth:800,minAspectRatio:1.6},optional:[]}}:{audio:!1,video:{mandatory:{sourceId:this.id,minWidth:600,maxWidth:800,minAspectRatio:1.6},optional:[]}}
iOS 12+์์ Safari์ ํจ๊ป ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ธ ์ฌ๋์ด ์์ต๋๊น?
์ ๋ ์ฝ 7๊ฐ์ ๋์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ ๋ ๋ฒ์ ์ 30๊ฐ ์ด์์ ์ ํ์ ios ๋ฐ Android ํด๋ํฐ ๋ฐ ํ๋ธ๋ฆฟ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์์ ์ค์ธ OS์์ ์นด๋ฉ๋ผ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์์ ๋ ๋ฒ์ ์ ๋ํด ์์ ๋จ๊ธด ๋๊ธ์ ํ์ธํ์ธ์. ๋๊ธ์ ์ดํ์ webrtc๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ๊ณ์ ์ด์ผ๊ธฐํ๋๋ฐ, ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฒด ๋ฌธ์ ์ธ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
ํ๋ก์ ํธ์์ webrtc๋ฅผ ์์ ํ ์ ๊ฑฐํ๊ณ ๋ค์ ์ปดํ์ผํ์ต๋๋ค. webrtc๋ es5 ์ด์์ผ๋ก ํธ๋์คํ์ผ๋ ๋ ์ด ์ฝ๋์ ํจ๊ป ๋ ์ด์ ํ์ํ์ง ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ webrtc๋ฅผ ์ฌ์ฉํ๊ณ ์ฝ๋ฉ ๋ฐฉ์์ผ๋ก ์ธํด ์ฌ๋ฐ๋ฅธ ์นด๋ฉ๋ผ๋ฅผ ๊ฒ์ํ ์ ์์์ต๋๋ค.
ํ๋์ ์ฌ์ฉํ๊ณ ์๋ ๊ณ ์ ๋ฐ ํธ๋์คํ์ผ๋ ์ผ๋ฐ ๋ฐ ์ถ์๋ js ํ์ผ์ ํฌํจํ์ต๋๋ค. ์ ๋ ํ์๊ณผ ๊ต์ฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์ ํ๊ธฐ์์ QrCode๋ก ํ๊ต ์ถ์์ ์ฌ์ฉํฉ๋๋ค. ์ด ์ ํ๊ธฐ๋ ํ์ฌ ์ฝ 30๊ฐ ์ด์์ ๋ชจ๋ธ์ ๋๋ค. ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
์ด๊ฒ ๋์์ด ๋๊ธธ ๋ฐ๋๋ค.
ํ๋ฉด ์นด๋ฉ๋ผ ์ฝ๋
scanner = new Instascan.Scanner({ video: video, scanPeriod: 4, mirror:false }) .then(handleSuccess) .catch(handleError); //Start scanning scanner.addListener('scan', foundCode); Instascan.Camera.getCameras().then(function (cameras) { if (cameras.length > 0) { scanner.start(cameras[0]); } else { ... } }).catch (function (e) { ... });
๋น์ ์ ๋ฐฉ๊ธ ์ฃผ๋์ด ๊ฐ๋ฐ์์ ์ง์ ์ ๊ตฌํ๊ณ ํ์ ํฌ์ด๋์์ต๋๋ค.
๊ฐ์ฌ ํด์. ์ด ์ฝ๋๋ฅผ ๋ดค์ ๋ ๋น์ ์ด ์๋ ๋ฐ๋ก ๊ทธ ์๋ฆฌ์ ์์์ต๋๋ค. ๊ธฐํ์ด ์์๊ณ 30๊ฐ์ง ์ ํ์ ์นด๋ฉ๋ผ๊ฐ ํ์ํ์ต๋๋ค. ๋๋ ๊ทธ๋ค์ด ์ด๊ฒ์ ์ผ๊ธฐ ๋๋ฌธ์ ๊ธฐ์ฉ๋๋ค.
ํ์ฌ 15๊ฐ์ ๋์ 45๊ฐ์ง ๋ค๋ฅธ ๋ชจ๋ธ์ ํด๋ํฐ์ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ์ผ์ฑ์ด ํจ์นํ์ ๋ ์์ ๋ ์ผ์ฑ ํด๋ํฐ์์ ๋จ ํ ๋ฒ์ ๋ธ๊พน์ง์ด ๋ฐ์ํ์ต๋๋ค. ๊ทธ๋์ ์ผ์ฑ WebKit ์ค๋ฅ์์ต๋๋ค.
์๋
ํ์ธ์,
๋๋ ๋ํ ๋ค๋ฅธ ์ฌ๋๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก IOS์์ ํ๋ฉด ์นด๋ฉ๋ผ ๋ฌธ์ ์ ์ง๋ฉดํ๊ณ ์์ต๋๋ค. iPhone์์ ํ๋ฉด ์นด๋ฉ๋ผ๊ฐ ์ด๋ฆฌ์ง ์๊ณ ๊ธฐ๋ณธ ์ ๋ฉด ์นด๋ฉ๋ผ๊ฐ ์คํ ์ค์
๋๋ค. ์ฌํ๋ฆฌ ์
๋ฐ์ดํธ ๋ฒ์ (13.xx.xx)์ผ๋ก ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ ๋ถ์ด ๊ณ์๋ฉด ๋์์ฃผ์ธ์.
iOS 12+์์ Safari์ ํจ๊ป ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ธ ์ฌ๋์ด ์์ต๋๊น?
์ ๋ ์ฝ 7๊ฐ์ ๋์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ ๋ ๋ฒ์ ์ 30๊ฐ ์ด์์ ์ ํ์ ios ๋ฐ Android ํด๋ํฐ ๋ฐ ํ๋ธ๋ฆฟ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์์ ์ค์ธ OS์์ ์นด๋ฉ๋ผ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์์ ๋ ๋ฒ์ ์ ๋ํด ์์ ๋จ๊ธด ๋๊ธ์ ํ์ธํ์ธ์. ๋๊ธ์ ์ดํ์ webrtc๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ๊ณ์ ์ด์ผ๊ธฐํ๋๋ฐ, ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฒด ๋ฌธ์ ์ธ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
ํ๋ก์ ํธ์์ webrtc๋ฅผ ์์ ํ ์ ๊ฑฐํ๊ณ ๋ค์ ์ปดํ์ผํ์ต๋๋ค. webrtc๋ es5 ์ด์์ผ๋ก ํธ๋์คํ์ผ๋ ๋ ์ด ์ฝ๋์ ํจ๊ป ๋ ์ด์ ํ์ํ์ง ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ webrtc๋ฅผ ์ฌ์ฉํ๊ณ ์ฝ๋ฉ ๋ฐฉ์์ผ๋ก ์ธํด ์ฌ๋ฐ๋ฅธ ์นด๋ฉ๋ผ๋ฅผ ๊ฒ์ํ ์ ์์์ต๋๋ค.
ํ๋์ ์ฌ์ฉํ๊ณ ์๋ ๊ณ ์ ๋ฐ ํธ๋์คํ์ผ๋ ์ผ๋ฐ ๋ฐ ์ถ์๋ js ํ์ผ์ ํฌํจํ์ต๋๋ค. ์ ๋ ํ์๊ณผ ๊ต์ฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์ ํ๊ธฐ์์ QrCode๋ก ํ๊ต ์ถ์์ ์ฌ์ฉํฉ๋๋ค. ์ด ์ ํ๊ธฐ๋ ํ์ฌ ์ฝ 30๊ฐ ์ด์์ ๋ชจ๋ธ์ ๋๋ค. ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
์ด๊ฒ ๋์์ด ๋๊ธธ ๋ฐ๋๋ค.
ํ๋ฉด ์นด๋ฉ๋ผ ์ฝ๋
scanner = new Instascan.Scanner({ video: video, scanPeriod: 4, mirror:false }) .then(handleSuccess) .catch(handleError); //Start scanning scanner.addListener('scan', foundCode); Instascan.Camera.getCameras().then(function (cameras) { if (cameras.length > 0) { scanner.start(cameras[0]); } else { ... } }).catch (function (e) { ... });
Android์ iOS ๋ชจ๋์์ ๋งค๋ ฅ์ฒ๋ผ ์๋ํ์ต๋๋ค! ๋ฐฉ๊ธ ์๋ณธ instascan ๋ง์คํฐ ๋ธ๋์น๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ํ์ผ์ "dist" ํด๋์ ๋ฃ์ผ๋ฉด ๋์ ๋๋ค! ๋๋จํ ๊ฐ์ฌํฉ๋๋ค !
Android์ iOS ๋ชจ๋์์ ๋งค๋ ฅ์ฒ๋ผ ์๋ํ์ต๋๋ค! ๋ฐฉ๊ธ ์๋ณธ instascan ๋ง์คํฐ ๋ธ๋์น๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ํ์ผ์ "dist" ํด๋์ ๋ฃ์ผ๋ฉด ๋์ ๋๋ค! ๋๋จํ ๊ฐ์ฌํฉ๋๋ค !
@antworks-hub ๋ธ๋์น์ ์ ์ฒด ์ฝ๋๋ฅผ ์ฌ์ฉํ์
จ๋์ ์๋๋ฉด ์ถ์๋ js๋ฅผ ์ฌ์ฉํ์
จ๋์?
"dist" ํด๋๋ ์ด๋์ ๊ตฌํ์
จ๋์?
Android์ iOS ๋ชจ๋์์ ๋งค๋ ฅ์ฒ๋ผ ์๋ํ์ต๋๋ค! ๋ฐฉ๊ธ ์๋ณธ instascan ๋ง์คํฐ ๋ธ๋์น๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ํ์ผ์ "dist" ํด๋์ ๋ฃ์ผ๋ฉด ๋์ ๋๋ค! ๋๋จํ ๊ฐ์ฌํฉ๋๋ค !
@antworks-hub ๋ธ๋์น์ ์ ์ฒด ์ฝ๋๋ฅผ ์ฌ์ฉํ์ จ๋์ ์๋๋ฉด ์ถ์๋ js๋ฅผ ์ฌ์ฉํ์ จ๋์?
"dist" ํด๋๋ ์ด๋์ ๊ตฌํ์ จ๋์?
@Sandi2211 ์๋ instascan ๋ง์คํฐ ๋ธ๋์น์ ๋ฃจํธ์ "dist" ํด๋๋ฅผ ๋ง๋ค๊ณ ๊ทธ ํด๋์ instasca,min.zip ํ์ผ์ ๋ด์ฉ์ ๋ฃ์ ๊ฒ ๊ฐ์ต๋๋ค.
iOS 12+์์ Safari์ ํจ๊ป ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ธ ์ฌ๋์ด ์์ต๋๊น?
์ ๋ ์ฝ 7๊ฐ์ ๋์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ ๋ ๋ฒ์ ์ 30๊ฐ ์ด์์ ์ ํ์ ios ๋ฐ Android ํด๋ํฐ ๋ฐ ํ๋ธ๋ฆฟ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์์ ์ค์ธ OS์์ ์นด๋ฉ๋ผ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์์ ๋ ๋ฒ์ ์ ๋ํด ์์ ๋จ๊ธด ๋๊ธ์ ํ์ธํ์ธ์. ๋๊ธ์ ์ดํ์ webrtc๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ๊ณ์ ์ด์ผ๊ธฐํ๋๋ฐ, ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฒด ๋ฌธ์ ์ธ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
ํ๋ก์ ํธ์์ webrtc๋ฅผ ์์ ํ ์ ๊ฑฐํ๊ณ ๋ค์ ์ปดํ์ผํ์ต๋๋ค. webrtc๋ es5 ์ด์์ผ๋ก ํธ๋์คํ์ผ๋ ๋ ์ด ์ฝ๋์ ํจ๊ป ๋ ์ด์ ํ์ํ์ง ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ webrtc๋ฅผ ์ฌ์ฉํ๊ณ ์ฝ๋ฉ ๋ฐฉ์์ผ๋ก ์ธํด ์ฌ๋ฐ๋ฅธ ์นด๋ฉ๋ผ๋ฅผ ๊ฒ์ํ ์ ์์์ต๋๋ค.
ํ๋์ ์ฌ์ฉํ๊ณ ์๋ ๊ณ ์ ๋ฐ ํธ๋์คํ์ผ๋ ์ผ๋ฐ ๋ฐ ์ถ์๋ js ํ์ผ์ ํฌํจํ์ต๋๋ค. ์ ๋ ํ์๊ณผ ๊ต์ฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์ ํ๊ธฐ์์ QrCode๋ก ํ๊ต ์ถ์์ ์ฌ์ฉํฉ๋๋ค. ์ด ์ ํ๊ธฐ๋ ํ์ฌ ์ฝ 30๊ฐ ์ด์์ ๋ชจ๋ธ์ ๋๋ค. ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
์ด๊ฒ ๋์์ด ๋๊ธธ ๋ฐ๋๋ค.
ํ๋ฉด ์นด๋ฉ๋ผ ์ฝ๋scanner = new Instascan.Scanner({ video: video, scanPeriod: 4, mirror:false }) .then(handleSuccess) .catch(handleError); //Start scanning scanner.addListener('scan', foundCode); Instascan.Camera.getCameras().then(function (cameras) { if (cameras.length > 0) { scanner.start(cameras[0]); } else { ... } }).catch (function (e) { ... });
์ด๊ฒ์ ๋ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ๋๋จํ ๊ฐ์ฌํฉ๋๋ค.
๊ฐ์ฌํฉ๋๋ค. ์ ์์ ์ด ์ ๋ฉ๋๋ค. ์ js๋ฅผ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
๊ด์ฐฎ์์. ์ด ๋ชจ๋ ๊ฒ์ด ์ฌ์ ํ ์ฌ๊ธฐ์์ ์๋ํ๊ณ ์์ด ๊ธฐ์ฉ๋๋ค.
iOS 12+์์ Safari์ ํจ๊ป ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ธ ์ฌ๋์ด ์์ต๋๊น?
์ ๋ ์ฝ 7๊ฐ์ ๋์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ ๋ ๋ฒ์ ์ 30๊ฐ ์ด์์ ์ ํ์ ios ๋ฐ Android ํด๋ํฐ ๋ฐ ํ๋ธ๋ฆฟ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์์ ์ค์ธ OS์์ ์นด๋ฉ๋ผ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์์ ๋ ๋ฒ์ ์ ๋ํด ์์ ๋จ๊ธด ๋๊ธ์ ํ์ธํ์ธ์. ๋๊ธ์ ์ดํ์ webrtc๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ๊ณ์ ์ด์ผ๊ธฐํ๋๋ฐ, ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฒด ๋ฌธ์ ์ธ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
ํ๋ก์ ํธ์์ webrtc๋ฅผ ์์ ํ ์ ๊ฑฐํ๊ณ ๋ค์ ์ปดํ์ผํ์ต๋๋ค. webrtc๋ es5 ์ด์์ผ๋ก ํธ๋์คํ์ผ๋ ๋ ์ด ์ฝ๋์ ํจ๊ป ๋ ์ด์ ํ์ํ์ง ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ webrtc๋ฅผ ์ฌ์ฉํ๊ณ ์ฝ๋ฉ ๋ฐฉ์์ผ๋ก ์ธํด ์ฌ๋ฐ๋ฅธ ์นด๋ฉ๋ผ๋ฅผ ๊ฒ์ํ ์ ์์์ต๋๋ค.
ํ๋์ ์ฌ์ฉํ๊ณ ์๋ ๊ณ ์ ๋ฐ ํธ๋์คํ์ผ๋ ์ผ๋ฐ ๋ฐ ์ถ์๋ js ํ์ผ์ ํฌํจํ์ต๋๋ค. ์ ๋ ํ์๊ณผ ๊ต์ฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์ ํ๊ธฐ์์ QrCode๋ก ํ๊ต ์ถ์์ ์ฌ์ฉํฉ๋๋ค. ์ด ์ ํ๊ธฐ๋ ํ์ฌ ์ฝ 30๊ฐ ์ด์์ ๋ชจ๋ธ์ ๋๋ค. ๋ชจ๋ ์นด๋ฉ๋ผ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
์ด๊ฒ ๋์์ด ๋๊ธธ ๋ฐ๋๋ค.
ํ๋ฉด ์นด๋ฉ๋ผ ์ฝ๋
scanner = new Instascan.Scanner({ video: video, scanPeriod: 4, mirror:false }) .then(handleSuccess) .catch(handleError); //Start scanning scanner.addListener('scan', foundCode); Instascan.Camera.getCameras().then(function (cameras) { if (cameras.length > 0) { scanner.start(cameras[0]); } else { ... } }).catch (function (e) { ... });
๊ณ ๋ง์, @apchandler11! ๋น์ ์ ๋ด ์์ ์ ์ ์ฅํ์ต๋๋ค. ๋ง์์ฌ!
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด๊ฒ์ ํ๋ฅญํ ์ ํ์ด๊ณ ์ ๋ง ์ ์ฉํ์ต๋๋ค. ๊ทธ๋์ ๋ฉ์ง๊ฒ ๋ง๋ค์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋ด ์ฐ๊ตฌ์์์ด instascan์ ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
_scanner.start(camera)_๋ฅผ ํธ์ถํ๋ฉด ์นด๋ฉ๋ผ ์์ _camera.start()_ ๋ฉ์๋๋ฅผ ํธ์ถํ๋
์ ์ฝ ๋ฌธ์ :
์ ๋ฌ๋ Camera ๊ฐ์ฒด๋ ์ ์ฝ ์กฐ๊ฑด์์ ํด๋น ID ๋ฅผ ์ฅ์น ๊ฒ์์ _"ํ์"_๋ก ์ฌ์ฉํฉ๋๋ค. ์ฐพ์ ์ ์์ผ๋ฉด ๋น๋์ค๊ฐ ํ์๋์ง ์์ต๋๋ค. ๋ํ ๋ค๋ฅธ "ํ์" ์ ์ฝ ์กฐ๊ฑด์ด ์ค์ ๋ฉ๋๋ค.
๋ค๋ฅธ ์ฅ์น๋ ์ฌ์ฉ๋ ์ ์ฝ ์กฐ๊ฑด์ ์ง์ํ์ง ์์ต๋๋ค!
์ฌ์ฉํ๋ ค๋ ์ฅ์น์์ ์ด ๋งํฌ๋ฅผ ์คํํ๋ฉด ์ง์ํ๋ ์ ์ฝ ์กฐ๊ฑด์ด ๋ฌด์์ธ์ง ์๋ ค์ค๋๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints
์ฌ์ฉํ๋ ค๋ ์ฅ์น์์ ์ด ๋งํฌ๋ฅผ ์คํํ๊ณ ์ ์ฝ ์กฐ๊ฑด์ ์ ๋ ฅํ์ญ์์ค. ์ง์ ์ฌ๋ถ๋ฅผ ์๋ ค์ค๋๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSupportedConstraints/deviceId
Ipad/Iphone/IOS ์ง์ ์ ์ฝ:
aspectRatio, facesMode, _deviceId * _ , ๋์ด, ๋๋น, aspectRatio ๋ฑ.
_๋ด๊ฐ ์ด๊ฒ์ ํ ์คํธํ ๋ _deviceId๋ ์ ์ฝ ์กฐ๊ฑด์ผ๋ก ๋ฌด์๋ฉ๋๋ค._ ์ ์ฝ ์กฐ๊ฑด ์ ๋ํด ์์ ๋งํฌ์์ ์ด๊ฒ์ ์๋ํ๋ฉด deviceId = ""๋ก ์ค์ ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์๋ฐ ์คํฌ๋ฆฝํธ์์ ์ก์์ ํ์ํ์ ๋ iphone์ ํญ์ ๋น deviceId๋ฅผ ๋ฐํํ์ต๋๋ค.
๋ฐ๋ผ์ Iphone์์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก์ผ๋ ค๋ฉด deviceId๋ฅผ ์ฌ์ฉํ์ง ์๊ณ faceMode๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Android ์ง์ ์ ์ฝ:
deviceId, _facingMode * _, aspectRatio, ๋์ด, ๋๋น ๋ฑ.
๋๋ ์ด๊ฒ์ ์ผ์ฑ ํ๋ธ๋ฆฟ๊ณผ ์๋๋ก์ด๋ ํฐ์์ ํ ์คํธํ๋ค. faceMode์ ๊ธฐ๋ณธ๊ฐ์ "์ฌ์ฉ์" ์ ๋ฉด ์นด๋ฉ๋ผ์ ๋๋ค. ์ด ์ฝ๋๋ฅผ ์คํํ ๊ฒฐ๊ณผ ์์ง๊น์ง ๋ฐ๊ฒฌํ ์ด๋ค ์ด์ ๋ก Android์ฉ facesMode๊ฐ ์๋ํ์ง ์๋๋ค๋ ์ฌ์ค์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์์ ๋งํฌ์์ ์๋ํฉ๋๋ค. ๋๋ ๊ทธ ๋ถ๋ถ์ ๊ณ์ ์กฐ์ฌํ ๊ฒ์ด๊ณ ์๋ง๋ ์ด ์ฝ๋๊ฐ facesMode ๋ฐ android์์ ์ ๋๋ก ์๋ํ๋๋ก ์์ ํ ๊ฒ์ ๋๋ค.
* * Android ๋ฌธ์ ์ ๋ํ ๋ต๋ณ * * *
์ด ํ๋ก์ ํธ์ Gulp ๋น๋์๋ Android Chrome์์ facesMode๋ฅผ ์๋ง์ผ๋ก ๋ง๋๋ webrtc-adapter ๋ฒ์ ^1.4.0์ด ํฌํจ๋์ด ์์ต๋๋ค. ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ์ค์ ๋ก ์ง๋ฉด ๋ชจ๋๋ฅผ ์ญ์ ํ์ต๋๋ค.
require('webrtc-adapter');
์ ๊ฑฐํ ๋ค์ ์๋ ๋น๋ ์ ์ฐจ๋ฅผ ๋ฐ๋ฅด์ธ์. Chrome์์ ํ๋ธ๋ฆฟ๊ณผ 4๊ฐ์ ๋ค๋ฅธ Android ํด๋์ ํ์์ ํ ์คํธํ์ ๋ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก๊ธฐ ์ํด ๋ชจ๋ ๋ค์ ์๋ํ์ต๋๋ค.์ด instascan ์ฝ๋๋ก Android์ ํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ก์ผ๋ ค๋ฉด deviceId๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
deviceId๊ฐ ๋ค์๊ณผ ๊ฐ์ _video_ ์ ์ฝ ์กฐ๊ฑด์ธ์ง ํ์ธํ์ญ์์ค.
์นด๋ฉ๋ผ ์ ์ฝ ์ฝ๋:
๋ค์์ ์ ์ฝ ์กฐ๊ฑด์ ์ค์ ํ๊ณ MediaStream ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ํ๋ก์ ํธ์ ์ฝ๋์ ๋๋ค.
์ด ์ฝ๋๊ฐ ์ ๋๋ก ์๋ํ์ง ์๋ ์ด์ ๋ _video ์ ์ฝ ์กฐ๊ฑด _ ์ sourceId๊ฐ _Android_ ๋๋ _Iphone_์์ ์ง์๋์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๊ฒ์ deviceId ๋ก ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค . ๋ํ ๋ชจ๋ ํ์ ํญ๋ชฉ์ ์ฅ์น๊ฐ ์ฒ๋ฆฌํ์ง ์๋ ๊ฒฝ์ฐ ์ด๋ํด์ผ ํฉ๋๋ค.
InstaScan์ ์์ ํ๊ณ ์ถ์ํ๋ ๋ฐฉ๋ฒ:
์ด๊ฒ์ ์ป๊ณ ๋ณ๊ฒฝํ๊ธฐ ์ํด VSCode๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
1) Node.js์ vsCode๋ฅผ ์ค์นํฉ๋๋ค.
2) ๋ค์ด๋ก๋ํ๋ ค๋ ๋๋ ํ ๋ฆฌ์ ํฐ๋ฏธ๋์์ ๋ค์์ ์คํํฉ๋๋ค.
git clone https://github.com/JoseCDB/instascan.git
3) ํฐ๋ฏธ๋ cd์์ instascan ๋๋ ํ ๋ฆฌ๋ก:
cd instascan
4) ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ณ๊ฒฝํ๊ณ gulp๋ฅผ ์คํํ์ฌ ์ฝ๋๋ฅผ ํด์ ํฉ๋๋ค.
gulp release
5) ์ด๊ฒ์ _dist_ ํด๋์ ์๋ก์ด ์ถ์๋ instascan.min.js ํญ๋ชฉ์ ์ค ๊ฒ์ ๋๋ค.
์ด๋ฒ ์ฃผ๋ง์ ์ด Android ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ๋ฉ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ํฅํ ํ๋ก์ ํธ์ ๋ํ ์ถฉ๋ถํ ํต์ฐฐ๋ ฅ์ ์ป์ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.