1. 程式人生 > >HTML5 呼叫手機攝像頭掃描二維碼

HTML5 呼叫手機攝像頭掃描二維碼

最近有個專案需要使用H5呼叫手機攝像頭掃描二維碼斌且識別。(很奇葩的需求)

百度了下找到了這個api:

舊版:(目前只有UC瀏覽器支援,其他的手機瀏覽器一律沒有反應)

https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/getUserMedia

新版:(目前只有火狐瀏覽器手機版谷歌瀏覽器桌面版支援支援)

https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia

這兩天折騰總算是把功能實現了,但是!!根本就不能用啊好不好!!

為什麼呢?因為舊版的API的後置攝像頭根本就不能對焦

!!!前置攝象頭可以對焦,但是沒什麼卵用啊,誰會用前置攝像頭去掃描。但是鑑於鼓搗了這麼久還是貼上程式碼吧。希望新版api能被相容QAQ

我的實現思路是這樣的,用喚起攝像頭的api喚起攝像頭,然後把視訊流寫到video標籤,然後利用video的timeupdate事件每一秒擷取一幀影象畫到canvas畫布上,再用js的二維碼解析庫解析二維碼。

js二維碼解析庫的地址:

https://github.com/LazarSoft/jsqrcode

以下是我的程式碼:

<!DOCTYPE html>  
<html>  
<head>  
<meta charset="UTF-8">  
<title>Insert title here</title>

    <script type="text/javascript" src="grid.js"></script>
    <script type="text/javascript" src="version.js"></script>
    <script type="text/javascript" src="detector.js"></script>
    <script type="text/javascript" src="formatinf.js"></script>
    <script type="text/javascript" src="errorlevel.js"></script>
    <script type="text/javascript" src="bitmat.js"></script>
    <script type="text/javascript" src="datablock.js"></script>
    <script type="text/javascript" src="bmparser.js"></script>
    <script type="text/javascript" src="datamask.js"></script>
    <script type="text/javascript" src="rsdecoder.js"></script>
    <script type="text/javascript" src="gf256poly.js"></script>
    <script type="text/javascript" src="gf256.js"></script>
    <script type="text/javascript" src="decoder.js"></script>
    <script type="text/javascript" src="qrcode.js"></script>
    <script type="text/javascript" src="findpat.js"></script>
    <script type="text/javascript" src="alignpat.js"></script>
    <script type="text/javascript" src="databr.js"></script>

</head>  
<body>  
<video id="video" autoplay=""style='width:100%;height:100%'></video>
<canvas id="canvas" style='display:none' width="400" height="400"></canvas>

<div id='pic_box'></div>
<div id='text_box'></div>

<script type="text/javascript">

    function writeObj(obj){
        var description = "";
        for(var i in obj){
            var property=obj[i];
            description+=i+" = "+property+"\n";
        }
        alert(description);
    }

    /*//Uc前置攝像頭掃描成功(因為後置攝像頭不能對焦)
    var exArray = []; //儲存裝置源ID
    MediaStreamTrack.getSources(function (sourceInfos) {
        for (var i = 0; i < sourceInfos.length; i++) {
            var sourceInfo = sourceInfos[i];
            //這裡會遍歷audio,video,所以要加以區分
            if (sourceInfo.kind === 'video') {
                exArray.push(sourceInfo.id);
            }
        }

        var getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
        getUserMedia.call(navigator, {
            'video': {
                'optional': [{
                    'sourceId': exArray[0] //0為前置攝像頭,1為後置
                }]
            },
        }, function(localMediaStream) {
            var video = document.getElementById('video');
            video.src = window.URL.createObjectURL(localMediaStream);
            video.play();
            //每秒用canvas繪製一副圖後用二維碼解析庫解析
            video.addEventListener("timeupdate", checkCode);
        }, function(e) {
            console.log('Reeeejected!', e);
        });

    });
    count = 0;
    function checkCode() {
        canvas.getContext('2d').drawImage(video, 0, 0, 400, 400);
        qrcode.decode(canvas.toDataURL("image/png"));
        qrcode.callback = function (data) {
            if (data == 'error decoding QR Code') {
                document.getElementById('text_box').innerText = '第' + count + '次:' + data;
                count++;
            } else {
                video.removeEventListener('timeupdate', checkCode);
                alert(data);
                //location.href = data;
            }
        }
    }*/


    //谷歌瀏覽器(電腦前置攝像頭)掃描成功
    var count = 0;
    var video = document.getElementById('video');
    var canvas = document.getElementById('canvas');
    navigator.mediaDevices.getUserMedia({
        video: true
    })
    .then(function(stream){
        video.src = window.URL.createObjectURL(stream);
        video.play();
        //每秒用canvas繪製一副圖後用二維碼解析庫解析
        video.addEventListener("timeupdate", checkCode);
    })
    .catch(function(){

    });

    function checkCode(){
        canvas.getContext('2d').drawImage(video, 0, 0, 400, 400);
        qrcode.decode(canvas.toDataURL("image/png"));
        qrcode.callback = function(data){
            if(data == 'error decoding QR Code'){
                document.getElementById('text_box').innerText = '第' + count + '次:' + data;
                count ++;
            }else{
                video.removeEventListener('timeupdate', checkCode);
                alert(data);
                //location.href = data;
            }
        }
    }

</script>  
  
</body>  
</html>  

結語,基本沒什麼實用價值