Vue js Сканер QR-кода - Как отключить стрим камеры - PullRequest
0 голосов
/ 06 мая 2020

Я перепробовал довольно много вариантов кода из Интернета. Но вроде ничего не работает на 100%. Я все еще вижу, что на моем компьютере горит свет камеры. В методе закрытия ниже вы можете увидеть мои попытки. Может ли кто-нибудь пролить свет на то, как закрыть этот видеопоток?

  <style lang="scss" scoped>

    #loadingMessage 
    {
        text-align: center;
        padding: 40px;
    }

    #canvas 
    {
        position: fixed;
        width: 100%;
        height: 100%;
        left: 0px;
        top: 0px;
    }

    #output div 
    {
        padding-bottom: 10px;
        word-wrap: break-word;
    }

    #noQRFound 
    {
        text-align: center;
    }

</style>

<template>

    <div id="qrScannner" style="z-index: 1000;">

        <div class="row">

            <div class="col-12 d-flex justify-content-center align-items-center">

                <div id="loadingMessage">? Unable to access video stream (please make sure you have a webcam enabled)</div>

                <canvas id="canvas" hidden></canvas>

            </div>

            <div class="col-12 d-flex justify-content-center">

                <div style="position: absolute; left: 0; top: 0; background-color: blue; width: 40px; height: 40px;" @click="close">

                    X

                </div>

                <div id="output" hidden>

                    <div hidden><b>Data:</b> <span id="outputData"></span></div>

                </div>

            </div>

        </div>

    </div>

</template>

<script>

import jsQR from "jsqr";

export default {

    data() 
    {
        return {
            isLoaded: false,
            scanning: false,
            lastScannedDate: '',
            tmr: null,
            video: document.createElement("video")
        };
    },

    methods: 
    {
        init: function()
        {
            this.scanning = true;

            if(!this.isLoaded)
            {
                let _this = this;
                let canvasElement  = document.getElementById('canvas');
                let canvas         = canvasElement.getContext('2d');
                let loadingMessage = document.getElementById('loadingMessage');

                // Use facingMode: environment to attemt to get the front camera on phones
                if(navigator.mediaDevices) 
                {
                    navigator.mediaDevices.getUserMedia(
                        {
                            video:
                            {
                                facingMode: 'environment',
                                width: { exact: 300 },
                                height: { exact: 500 },
                                focusDistance: 1,
                            }
                        }
                    )
                    .then(function(stream) {
                        _this.video.srcObject = stream;
                        _this.video.setAttribute('playsinline', true); // required to tell iOS safari we don't want fullscreen
                        _this.video.play();
                        requestAnimationFrame(_this.tick);
                    });
                }

                canvasElement.addEventListener('mousedown',function(evt){

                    // here it would be good to add a focus function

                },false);
            }
            else
            {
                requestAnimationFrame(_this.tick);
            }
        },

        tick: function ()
        {
            if (!this.scanning) return;

            let canvasElement  = document.getElementById("canvas");
            let canvas         = canvasElement.getContext("2d");
            let loadingMessage = document.getElementById("loadingMessage");

            loadingMessage.innerText = `⌛ ${tr('loading-video')}...`;

            if (this.video.readyState === this.video.HAVE_ENOUGH_DATA)
            {
                loadingMessage.hidden = true;
                canvasElement.hidden  = false;

                canvasElement.height = this.video.videoHeight;
                canvasElement.width  = this.video.videoWidth;

                canvas.drawImage(this.video, 0, 0, canvasElement.width, canvasElement.height);

                let imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);

                let code = jsQR(imageData.data, imageData.width, imageData.height, 
                {
                    inversionAttempts: "dontInvert",
                });

                if (code)
                {
                    this.drawLine(code.location.topLeftCorner, code.location.topRightCorner, "#FF3B58");
                    this.drawLine(code.location.topRightCorner, code.location.bottomRightCorner, "#FF3B58");
                    this.drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, "#FF3B58");
                    this.drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, "#FF3B58");
                    this.scanning = false;

                    this.sleep(500).then(() => 
                    {
                        this.$emit('code-scanned', code.data);

                        this.init();
                    });
                }
            }

            if ($("#qrScannner").is(":visible"))
            {
                requestAnimationFrame(this.tick);
            }
        },

        drawLine: function (begin, end, color)
        {
            var canvasElement = document.getElementById('canvas');
            var canvas       = canvasElement.getContext('2d');

            canvas.beginPath();
            canvas.moveTo(begin.x, begin.y);
            canvas.lineTo(end.x, end.y);

            canvas.lineWidth   = 4;
            canvas.strokeStyle = color;

            canvas.stroke();
        },


        sleep: function (time) 
        {
            return new Promise((resolve) => setTimeout(resolve, time));
        },

        close: function ()
        {
            // MediaStream.getTracks().forEach(
            //  function(track)
            //  {
            //      track.stop();
            //  }
            // );

            $(this.video)[0].pause();
            $(this.video)[0].src = null;

            this.video = null;
        }
    }
}
</script>
...