bookManagement/public/index.html
2024-08-24 22:42:37 -04:00

188 lines
6.5 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ISBN Scanner</title>
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2/dist/quagga.js"></script>
<style>
#interactive.viewport {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
}
canvas.drawing, canvas.drawingBuffer {
position: absolute;
top: 0;
left: 0;
}
#book-info {
margin-top: 20px;
}
</style>
</head>
<body>
<h1>Scan a Book ISBN</h1>
<div>
<label for="camera-select">Select Camera:</label>
<select id="camera-select"></select>
<button id="start-scanner">Start Scanner</button>
</div>
<div id="interactive" class="viewport"></div>
<div>
<h2>Or upload a barcode image</h2>
<input type="file" id="barcode-input" accept="image/*">
</div>
<div id="book-info"></div>
<script>
let selectedDeviceId;
async function testCameraAccess() {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
console.log('Camera access granted', stream);
} catch (error) {
console.error('Error accessing camera:', error);
}
}
// Get available video input devices (cameras)
async function getCameras() {
try {
// Ensure the cameraSelect element is defined before accessing it
const cameraSelect = document.getElementById('camera-select');
const stream = await navigator.mediaDevices.getUserMedia({ video: true }); // Prompt for camera access
const devices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = devices.filter(device => device.kind === 'videoinput');
// Update selectedDeviceId when user selects a camera
cameraSelect.addEventListener('change', function() {
selectedDeviceId = this.value;
});
if (videoDevices.length > 0) {
videoDevices.forEach((device, index) => {
const option = document.createElement('option');
option.value = device.deviceId;
option.text = device.label || `Camera ${index + 1}`;
cameraSelect.appendChild(option);
});
} else {
console.log("No video devices found.");
cameraSelect.innerHTML = '<option>No cameras found</option>';
}
} catch (error) {
console.error("Error accessing the camera or enumerating devices:", error);
document.getElementById('camera-select').innerHTML = '<option>'+error+'</option>';
}
}
function startScanner() {
if (!selectedDeviceId) {
alert('No camera selected or available.');
return;
}
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
target: document.querySelector('#interactive'),
constraints: {
deviceId: selectedDeviceId,
facingMode: "environment", // Default to rear camera
},
},
decoder: {
readers: ["ean_reader"] // EAN is the standard format for ISBN-13 barcodes
}
}, function (err) {
if (err) {
console.log(err);
return;
}
console.log("Initialization finished. Ready to start");
Quagga.start();
});
Quagga.onDetected(async function (data) {
const isbn = data.codeResult.code;
console.log("Detected ISBN:", isbn);
Quagga.stop(); // Stop the scanner once an ISBN is detected
// Fetch book details
fetchBookInfo(isbn);
});
}
function fetchBookInfo(isbn) {
fetch(`/book/${isbn}`)
.then(response => response.json())
.then(data => displayBookInfo(data))
.catch(err => console.error('Error fetching book data:', err));
}
function displayBookInfo(data) {
const bookInfoDiv = document.getElementById('book-info');
if (data.title) {
bookInfoDiv.innerHTML = `
<h2>${data.title}</h2>
<p><strong>Authors:</strong> ${data.authors.join(', ')}</p>
<p><strong>Published Date:</strong> ${data.publishedDate}</p>
<p><strong>Description:</strong> ${data.description}</p>
`;
} else {
bookInfoDiv.innerHTML = '<p>No book found for this ISBN.</p>';
}
}
// Handle image file input
document.getElementById('barcode-input').addEventListener('change', function(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
const imageSrc = e.target.result;
decodeBarcodeFromImage(imageSrc);
};
reader.readAsDataURL(file);
}
});
function decodeBarcodeFromImage(imageSrc) {
Quagga.decodeSingle({
src: imageSrc,
numOfWorkers: 0, // Needs to be 0 when used with decodeSingle()
inputStream: {
size: 800 // Limit the size for better performance
},
decoder: {
readers: ["ean_reader"] // EAN is the standard format for ISBN-13 barcodes
}
}, function(result) {
if (result && result.codeResult) {
console.log("Detected ISBN from image:", result.codeResult.code);
fetchBookInfo(result.codeResult.code);
} else {
console.log("Barcode not detected in image.");
document.getElementById('book-info').innerHTML = '<p>Barcode not detected in the image.</p>';
}
});
}
// Start the scanner when the start button is clicked
document.getElementById('start-scanner').addEventListener('click', startScanner);
// Get cameras on page load
window.onload = getCameras;
</script>
</body>
</html>