I would like to ask how to turn on a phone flashlight on a web app using JavaScript and HTML. I had created a web app that is able to scan QR codes using a phone camera. I had managed to turn on a phone camera, but I faced some difficulties regarding to turning on the phone flashlight on a different platform which is Android and iOS.
For Android OS, I had managed to turn on the phone camera on my web app, and was also able to turn on the phone flashlight right after the camera has been turned on. However, after I turned on the flashlight, closed the web app, and reopened it again, the flashlight wasn't working anymore.
For iOS, the camera seems to be turned on, but I can't view anything through the web app. Besides, the phone flashlight doesn't work as well.
My code:
HTML part
<!DOCTYPE html>
<html>
<head>
<title>HOME PAGE</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" >
<script src="https://rawgit.com/sitepoint-editors/jsqrcode/master/src/qr_packed.js"></script>
</head>
<body>
<button class="switch"><i class="fa fa-lightbulb-o" id="flashlight-icon"></i>Flashlight</button>
<canvas id="qr-canvas"></canvas>
<div id="qr-result" hidden="">
<b>Data:</b> <span id="outputData"></span>
</div>
<script src="src/torch.js"></script>
<script src="src/qrCodeScanner.js"></script>
</body>
</html>
torch.js:
//Test browser support
const SUPPORTS_MEDIA_DEVICES = 'mediaDevices' in navigator;
if (SUPPORTS_MEDIA_DEVICES) {
//Get the environment camera (usually the second one)
navigator.mediaDevices.enumerateDevices().then(devices => {
const cameras = devices.filter((device) => device.kind === 'videoinput');
if (cameras.length === 0) {
throw 'No camera found on this device.';
}
const camera = cameras[cameras.length - 1];
// Create stream and get video track
navigator.mediaDevices.getUserMedia({
video: {
deviceId: camera.deviceId,
facingMode: ['user', 'environment'],
height: {ideal: 1080},
width: {ideal: 1920}
}
}).then(stream => {
const track = stream.getVideoTracks()[0];
//Create image capture object and get camera capabilities
const imageCapture = new ImageCapture(track)
const photoCapabilities = imageCapture.getPhotoCapabilities().then(() => {
//todo: check if camera has a torch
//let there be light!
const btn = document.querySelector('.switch');
btn.addEventListener('click', function(){
track.applyConstraints({
advanced: [{torch: true}]
});
});
});
});
});
//The light will be on as long the track exists
}
qrCodeScanner.js:
const qrcode1 = window.qrcode;
const video = document.createElement("video");
const canvasElement = document.getElementById("qr-canvas");
const canvas = canvasElement.getContext("2d");
const qrResult = document.getElementById("qr-result");
const outputData = document.getElementById("outputData");
const btnScanQR = document.getElementById("btn-scan-qr");
let scanning = false;
qrcode1.callback = res => {
if (res) {
outputData.innerText = res;
if (res.match("^[0-9A-Z]{4}$")) {
window.location="worker.php?ennm="+res;
scanning = false;
video.srcObject.getTracks().forEach(track => {
track.stop();
});
qrResult.hidden = false;
canvasElement.hidden = true;
btnScanQR.hidden = false;
} else {
alert("Wrong scanning!");
window.location="qr.php";
}
}
};
navigator.mediaDevices
.getUserMedia({ video: { facingMode: "environment" } })
.then(function(stream) {
scanning = true;
canvasElement.hidden = false;
video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
video.srcObject = stream;
video.play();
tick();
scan();
});
function tick() {
canvasElement.height = video.videoHeight;
canvasElement.width = video.videoWidth;
canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
scanning && requestAnimationFrame(tick);
}
function scan() {
try {
qrcode1.decode();
} catch (e) {
setTimeout(scan, 300);
}
}
Is there anything wrong with my code? Please, can anyone point out which part is wrong? I am a newbie to JavaScript and I would really appreciate it if someone can help me, thanks in advance!