From 624ac2323bf46f0bcda9c1e9660923427d927181 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 9 Jun 2024 15:59:19 +0200 Subject: [PATCH] trying to fix video record, save before bigger changes --- slaeforms/app.py | 8 +- slaeforms/default.json | 7 +- slaeforms/static/styles.css | 9 +- slaeforms/static/videoscript.js | 132 +++++++++++++++++++++ slaeforms/templates/all_links.html | 2 + slaeforms/templates/myvideotemplate.html | 5 +- slaeforms/templates/standard_template.html | 54 ++++++++- slaeforms/templates/test_page0.html | 2 + slaeforms/templates/test_page1.html | 2 + 9 files changed, 210 insertions(+), 11 deletions(-) diff --git a/slaeforms/app.py b/slaeforms/app.py index d52c72b..d58fc57 100644 --- a/slaeforms/app.py +++ b/slaeforms/app.py @@ -229,7 +229,7 @@ def teststartpage(): def jsonform(): #user is not yet registered and should not be here if not "slaeform_user_id" in session: - return redirect(url_for(teststartpage)) #TODO replace this later with actual startpage + return redirect("/teststart") #TODO replace this later with actual startpage current_block = config[session["current_block_name"]] @@ -316,6 +316,12 @@ def sendpage_json(): print("Error occurred: {e}".format(e=str(e))) return "There was a problem while adding the response to the Database" + # handle possible Video that was send + video = request.files['recordedVideo'] + #video_name = './uploads/' + str(date) + "_" + str(session_user_id) + video.save(f'./uploads/{video.filename}') + + # Now move to the next stimulus or block update_session() diff --git a/slaeforms/default.json b/slaeforms/default.json index a2e02de..481cb8a 100644 --- a/slaeforms/default.json +++ b/slaeforms/default.json @@ -48,7 +48,12 @@ "name": "text_feedback", "required": "false", "size": "250" - } + }, + "question3":{ + "type": "videoinput", + "name": "video_feedback", + "required": "false" + } }, "database_table" :{ "table_name": "default_block3_test", diff --git a/slaeforms/static/styles.css b/slaeforms/static/styles.css index 2d6e90b..c4e6999 100644 --- a/slaeforms/static/styles.css +++ b/slaeforms/static/styles.css @@ -1,6 +1,6 @@ body { width: 100%; - height: 100vh; + height: 100%; margin: 0; display: flex; justify-content: center; @@ -52,6 +52,13 @@ body { box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } +video { + max-width: 100%; + max-height: 100%; + width: auto; + height: auto; +} + .videocontrols { width: 100px; /* Set a specific width for the buttons */ height: 70px; /* Set a specific height for the buttons */ diff --git a/slaeforms/static/videoscript.js b/slaeforms/static/videoscript.js index e69de29..a95617b 100644 --- a/slaeforms/static/videoscript.js +++ b/slaeforms/static/videoscript.js @@ -0,0 +1,132 @@ + +const buttonCamera = document.getElementById('buttonCamera'); +const buttonRecord = document.getElementById('buttonRecord'); +const buttonDelete = document.getElementById('buttonDelete'); +const videoDisplay = document.getElementById('videoDisplay'); +const buttonCameraIcon = document.getElementById('buttonCameraIcon'); +const buttonRecordIcon = document.getElementById('buttonRecordIcon'); +//const buttonDeleteIcon = document.getElementById('buttonDeleteIcon'); +var mediaRecorder = null; +var stream = null; +let recordedVideoBlob = null; +let isRecording = false; +let videoAccess = false; + +//handle form submission: +document.getElementById("question_form").addEventListener("submit", function (event) { + event.preventDefault(); // Prevent the default form submission + + // Create a FormData object + const formData = new FormData(event.target); + + // Append the recorded video Blob to the FormData object + formData.append("recordedVideo", recordedVideoBlob, "recordedVideo.webm"); + + // Use fetch to send the form data and video to the backend + console.log("try to send the form and video"); + fetch("/send_json", { + method: "POST", + body: formData + }) + .then(response => response.json()) + .then(data => { + console.log('Success:', data); + // Handle success response + }) + .catch(error => { + console.error('Error:', error); + // Handle error response + }); +}); + +async function cameraButton() { + if (!videoAccess) { //test what happens if user doesnt give the permission + console.log("cameraButton case videoAccess = false"); + // maybe a try catch block? + try { + stream = await navigator.mediaDevices.getUserMedia({ + video: true, + }); + } catch (error) { + //TODO when this occurs the user should get a hint to reload the page or to allow it next to the url + newerror = error + console.log("Error: ", error); + return + } + console.log("stream is active"); + videoAccess = true + + videoDisplay.srcObject = stream + + buttonCameraIcon.src = ICON_PATHS.cameraofficon; //todo, not sure if this works + buttonCameraIcon.alt = "Camera-off Icon"; + buttonRecord.style.display = 'inline-block'; + buttonDelete.style.display = 'inline-block'; + videoDisplay.style.display = 'inline-block'; + + mediaRecorder = new MediaRecorder(stream, { + mimeType: "video/webm", //could use other video format: https://www.iana.org/assignments/media-types/media-types.xhtml#video + // I probably want to change the bitrate: https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder + }); + + } else { + console.log("cameraButton case videoAccess = true"); + + stream = null; + videoAccess = false + + buttonCameraIcon.src = ICON_PATHS.cameraicon; //todo, not sure if this works + buttonCameraIcon.alt = "Camera Icon"; + buttonRecord.style.display = 'none'; + buttonDelete.style.display = 'none'; + videoDisplay.style.display = 'none'; + } + console.log("camera button function ends"); +} + + + +function recordButton() { + console.log("recordButton pressed"); + if (!isRecording) { + console.log("recordButton pressed case isRecording = false"); + deleteButton(); + buttonDelete.setAttribute("disabled", ""); + buttonDeleteIcon.classList.add("buttondisable"); + videoDisplay.srcObject = stream; + videoDisplay.src = null; + mediaRecorder.start(); + + buttonRecordIcon.src = ICON_PATHS.stopicon; + buttonRecordIcon.alt = 'record icon'; + isRecording = true; + console.log('Recording started'); + + } else { + console.log("recordButton pressed case isRecording = true"); + mediaRecorder.stop(); + + console.log("recording stops, now change source"); + videoDisplay.srcObject = null; + videoDisplay.src = URL.createObjectURL(mediaRecorder.data); + recordedVideoBlob = mediaRecorder.data; + + buttonRecordIcon.src = ICON_PATHS.recordicon; + buttonRecordIcon.alt = 'Stop Icon'; + isRecording = false; + console.log('Recording stopped'); + + buttonDelete.removeAttribute("disabled"); + buttonDeleteIcon.classList.remove("buttondisable"); + } +} +function deleteButton() { + //todo delete data + videoDisplay.srcObject = stream; + videoDisplay.src = null; + buttonDelete.setAttribute("disabled", ""); + buttonDeleteIcon.classList.add("buttondisable"); +} + + + \ No newline at end of file diff --git a/slaeforms/templates/all_links.html b/slaeforms/templates/all_links.html index 9476363..683be47 100644 --- a/slaeforms/templates/all_links.html +++ b/slaeforms/templates/all_links.html @@ -10,6 +10,7 @@ +

All available pages

+
\ No newline at end of file diff --git a/slaeforms/templates/myvideotemplate.html b/slaeforms/templates/myvideotemplate.html index 3c32365..6e3cbf4 100644 --- a/slaeforms/templates/myvideotemplate.html +++ b/slaeforms/templates/myvideotemplate.html @@ -10,6 +10,7 @@ +

Gib Feedback als Video

@@ -34,7 +35,7 @@
- +
- +
\ No newline at end of file diff --git a/slaeforms/templates/standard_template.html b/slaeforms/templates/standard_template.html index 072c4e5..8cc8c83 100644 --- a/slaeforms/templates/standard_template.html +++ b/slaeforms/templates/standard_template.html @@ -8,10 +8,10 @@

{{title}}

{% endif %}
- +
{% else %} @@ -32,9 +32,16 @@ required - + + Testform + @@ -51,7 +58,7 @@ required

Questions

-
+ {% for question in questions %} {% if (questions[question]["type"] == "likert") %}
@@ -72,12 +79,47 @@ required cols="60" maxlength="{{ questions[question]['size'] }}" {{required(questions[question])}}>
+ {% elif (questions[question]["type"] == "videoinput") %} +

Gib Feedback als Video

+
+ + + +
+ +
+ + + + + +
+ +
+ +
+ + {% else %}

Error: Block {{config["question 1"]["blocks"][block]["type"]}} could not be loaded!

{% endif %} {% endfor %}

+
diff --git a/slaeforms/templates/test_page0.html b/slaeforms/templates/test_page0.html index dbabed6..8f8214c 100644 --- a/slaeforms/templates/test_page0.html +++ b/slaeforms/templates/test_page0.html @@ -9,10 +9,12 @@ +

This is just a test page for the single page option of the json configuration, but without something to submit

+
\ No newline at end of file diff --git a/slaeforms/templates/test_page1.html b/slaeforms/templates/test_page1.html index 3dc2f94..f3d4611 100644 --- a/slaeforms/templates/test_page1.html +++ b/slaeforms/templates/test_page1.html @@ -9,6 +9,7 @@ +

This is just a test page for the single page option of the json configuration

Akzeptieren sie die Datenschutzerklaerung

+
\ No newline at end of file