Я перепробовал довольно много вариантов кода из Интернета. Но вроде ничего не работает на 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>