Scan QR Code/Barcode Dengan Webcam di website dengan zxing js

kali ini kita akan membuat sebuah fitur web dimana kita bisa mescan barcode dan menampilkannya di webnya memanfaatkan camera/webcam yang ada jadi tidak perlu alat khusus

kita akan menggunakan library js bernama zxing-js : https://github.com/zxing-js/library

ok yang pertama kita buat struktur html dasar

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scan QrCode</title>
</head>
<body>
     <video id="previewKamera" style="width: 300px;height: 300px;"></video>
     <br>
     <select id="pilihKamera" style="max-width:400px">
     </select>
     <br>
     <input type="text" id="hasilscan">


</body>
</html>

untuk bisa menampilkan preview webcam ke browser kita menggunakan tag video

lalu kita tambahkan linbrarynya

<script type="text/javascript" src="https://unpkg.com/@zxing/library@latest"></script>

kita juga menambahkan library jquery agar lebih mudah nantinya

<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

yang pertama kita deklarasikan beberapa vairable yang akan nanti kita gunakan

let selectedDeviceId = null;
const codeReader = new ZXing.BrowserMultiFormatReader();
const sourceSelect = $("#pilihKamera");

kemudian kita buat fungsi untuk inisiasi camera dan scannya

function initScanner() {

//kode didalam fungsi

}

yang pertama kita akan mengambil id camera yang ada di perangkat kita bisa jadi nanti saat web di buka di hp kita bisa memilih kamera depan atau belakang

function initScanner() {
    codeReader
    .listVideoInputDevices()
    .then(videoInputDevices => {
        videoInputDevices.forEach(device =>
                    //list kamera yang tersedia (bisa di hapus)
            console.log(`${device.label}, ${device.deviceId}`)
        );

        if(videoInputDevices.length > 0){
            //cek jika kamera id tidak null
            if(selectedDeviceId == null){
                            
                //memebrikan nilai kamera yang dipilih secara default
                if(videoInputDevices.length > 1){
                    selectedDeviceId = videoInputDevices[1].deviceId
                } else {
                    selectedDeviceId = videoInputDevices[0].deviceId
                }
            }

                    
            //menampilkan list kamera yang ada ke list select option jadi nanti kita bisa memilih kameranya nanti
            if (videoInputDevices.length >= 1) {
                sourceSelect.html('');
                videoInputDevices.forEach((element) => {
                    const sourceOption = document.createElement('option')
                    sourceOption.text = element.label
                    sourceOption.value = element.deviceId
                    if(element.deviceId == selectedDeviceId){
                        sourceOption.selected = 'selected';
                    }
                    sourceSelect.append(sourceOption)
                })

            }
            



        } else {
            alert("Camera not found!")
        }
    })
    .catch(err => console.error(err));
}

lalu kita coba panggil fungsinya,tapi sebelumnya kita check apakah browser kita memiliki akses kamera atau tidak

if (navigator.mediaDevices) {
    
    initScanner()
  

} else {
    alert('kamera tidak bisa di akses.');
}

NOTE : akses kamera kadang tidak di ijinkan di localhost keculai jika sudah menggunakan https

jika kita akses maka akan muncul list device kamera yang tersedia

kemudian kita akan menampilkan preview kamera dan proses scannya

codeReader
    .decodeOnceFromVideoDevice(selectedDeviceId, 'previewKamera')
    .then(result => {

            //hasil scan
            console.log(result.text)
            $("#hasilscan").val(result.text);
        
            if(codeReader){
//menghentikan kamera dan proses scan
                codeReader.reset()
            }
    })
    .catch(err => console.error(err));

sehingga keseluruhan kode javascriptnya menjadi seperti ini

let selectedDeviceId = null;
const codeReader = new ZXing.BrowserMultiFormatReader();
const sourceSelect = $("#pilihKamera");

$(document).on('change','#pilihKamera',function(){
    selectedDeviceId = $(this).val();
    if(codeReader){
        codeReader.reset()
        initScanner()
    }
})

function initScanner() {
    codeReader
    .listVideoInputDevices()
    .then(videoInputDevices => {
        videoInputDevices.forEach(device =>
            console.log(`${device.label}, ${device.deviceId}`)
        );

        if(videoInputDevices.length > 0){
            
            if(selectedDeviceId == null){
                if(videoInputDevices.length > 1){
                    selectedDeviceId = videoInputDevices[1].deviceId
                } else {
                    selectedDeviceId = videoInputDevices[0].deviceId
                }
            }
            
            
            if (videoInputDevices.length >= 1) {
                sourceSelect.html('');
                videoInputDevices.forEach((element) => {
                    const sourceOption = document.createElement('option')
                    sourceOption.text = element.label
                    sourceOption.value = element.deviceId
                    if(element.deviceId == selectedDeviceId){
                        sourceOption.selected = 'selected';
                    }
                    sourceSelect.append(sourceOption)
                })
        
            }

            codeReader
                .decodeOnceFromVideoDevice(selectedDeviceId, 'previewKamera')
                .then(result => {

                        //hasil scan
                        console.log(result.text)
                        $("#hasilscan").val(result.text);
                    
                        if(codeReader){
                            codeReader.reset()
                        }
                })
                .catch(err => console.error(err));
            
        } else {
            alert("Camera not found!")
        }
    })
    .catch(err => console.error(err));
}


if (navigator.mediaDevices) {
    

    initScanner()
    

} else {
    alert('Cannot access camera.');
}

jika sudah coba jalankan lagi,dan juga siapkan qrcode yang akan di scan

jika berhasil maka otomatis kamera akan tertutup dan menampilkan hasil scannya di inputan

jika kalian memilki banyak device kamera kalian bisa memilih kamera mana yang akan di gunakan di bagian select optionnya lalu kamera akan terbuka lagi/terreset

kode lengkapnya

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scan QrCode</title>
</head>
<body>
     <video id="previewKamera" style="width: 300px;height: 300px;"></video>
     <br>
     <select id="pilihKamera" style="max-width:400px">
     </select>
     <br>
     <input type="text" id="hasilscan">
     
     <script type="text/javascript" src="https://unpkg.com/@zxing/library@latest"></script>
     <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

     <script>
        let selectedDeviceId = null;
        const codeReader = new ZXing.BrowserMultiFormatReader();
        const sourceSelect = $("#pilihKamera");

        $(document).on('change','#pilihKamera',function(){
            selectedDeviceId = $(this).val();
            if(codeReader){
                codeReader.reset()
                initScanner()
            }
        })

        function initScanner() {
            codeReader
            .listVideoInputDevices()
            .then(videoInputDevices => {
                videoInputDevices.forEach(device =>
                    console.log(`${device.label}, ${device.deviceId}`)
                );

                if(videoInputDevices.length > 0){
                    
                    if(selectedDeviceId == null){
                        if(videoInputDevices.length > 1){
                            selectedDeviceId = videoInputDevices[1].deviceId
                        } else {
                            selectedDeviceId = videoInputDevices[0].deviceId
                        }
                    }
                    
                    
                    if (videoInputDevices.length >= 1) {
                        sourceSelect.html('');
                        videoInputDevices.forEach((element) => {
                            const sourceOption = document.createElement('option')
                            sourceOption.text = element.label
                            sourceOption.value = element.deviceId
                            if(element.deviceId == selectedDeviceId){
                                sourceOption.selected = 'selected';
                            }
                            sourceSelect.append(sourceOption)
                        })
                
                    }

                    codeReader
                        .decodeOnceFromVideoDevice(selectedDeviceId, 'previewKamera')
                        .then(result => {

                                //hasil scan
                                console.log(result.text)
                                $("#hasilscan").val(result.text);
                            
                                if(codeReader){
                                    codeReader.reset()
                                }
                        })
                        .catch(err => console.error(err));
                    
                } else {
                    alert("Camera not found!")
                }
            })
            .catch(err => console.error(err));
        }


        if (navigator.mediaDevices) {
            

            initScanner()
            

        } else {
            alert('Cannot access camera.');
        }
      
     </script>
</body>
</html>

One thought on “Scan QR Code/Barcode Dengan Webcam di website dengan zxing js

  1. Hai Gan, terima kasih untuk script yang sangat menarik. Saya ingin menanyakan bagaimana caranya agar scanner dapat bekerja terus menerus dan agar data yang terbaca langsung tertulis pada kursor yang sedang aktif sekaligus mengkonfirmasi data tersebut (input ENTER). Rencananya akan saya gunakan pada penghitung pengunjung perpustakaan saya (menggunakan SLiMS). Semoga berkenan menjawab pertanyaan saya.

    Like

Leave a comment