I am working on a face recognition project that sends gen_frame() to video_feed to be rendered in my html file. However, I cannot find the right way to send the localStorage value to the Flask server. Anyone have some suggestions how I can change the webcam with localStorage?
Here is the python attendance_taker.py
which contain the gen_frame
method:
def gen_frame():
cap = cv2.VideoCapture(0) # This is what I want to change using localstorage
face_recognizer = Face_Recognizer()
while True:
success, frame = cap.read()
if not success:
break
face_recognizer.process(frame)
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')`
Here is the javascript code:
window.addEventListener("DOMContentLoaded", function () {
var webcamSelect = document.getElementById("webcamSelect");
webcamSelect.addEventListener("change", function () {
var selectedWebcamIndex = webcamSelect.selectedIndex;
localStorage.setItem("selectedWebcamIndex", selectedWebcamIndex);
});
navigator.mediaDevices
.enumerateDevices()
.then((devices) => {
var videoDevices = devices.filter(
(device) => device.kind === "videoinput",
);
videoDevices.forEach((device, index) => {
var option = document.createElement("option");
option.value = index;
option.text = device.label || `Webcam ${index + 1}`;
webcamSelect.appendChild(option);
});
var selectedWebcamIndex = localStorage.getItem(
"selectedWebcamIndex",
);
if (selectedWebcamIndex) {
webcamSelect.selectedIndex = selectedWebcamIndex;
}
})
.catch((error) => {
console.error("Error enumerating devices:", error);
});
});
app.py
@app.route('/video_feed')
def video_feed():
return Response(gen_frame(), mimetype='multipart/x-mixed-replace; boundary=frame')
I tried using ajax from jquery, but is not working.
Regarding: Sending data back through to flask
"I tried AJAX from jQuery, but it's not working", AJAX is perhaps a bit outdated, and if it's not working with jQuery perhaps use regular javascript
That aside: you can do it off of a POST
request directly in your flask server file like so:
from flask import Flask, render_template, request
import cv2
app = Flask(__name__)
def gen_frame(webcam_val):
cap = cv2.VideoCapture(webcam_val)
# ...
@app.route('/your/route', methods=["GET", "POST"])
def get_webcam_value():
if request.method == 'POST': # method on POST (when form is submitted)
value = request.form['value'] # gets the value of the input field with the attribute `value` (`name="value"`)
gen_frame(value) # call your gen_frame function, and pass the value through
return render_template('yourfile.html')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>your file</title>
</head>
<body>
<form action="your/action" method="POST"> <!-- create form with method `POST` -->
<label>
<input type="number" name="value" placeholder="camera" /> <!-- created an html input with type `number` and name `value` (to be accessed by our flask) -->
</label>
<input type="submit" value="change camera" /> <!-- to submit the form when the user is ready -->
</form>
</body>
</html>
I don't know how your file structure is setup nor your server code, so let me know if you need anything adjusted
(posting this as a new answer not an edited one)