Skip to content

Commit

Permalink
added recording functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
anistuhin committed Dec 20, 2024
1 parent bda72d6 commit f9d1d3c
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 137 deletions.
231 changes: 105 additions & 126 deletions assets/articles.js
Original file line number Diff line number Diff line change
@@ -1,80 +1,7 @@
if (localStorage.getItem("auth") == null) {
localStorage.setItem("auth", "true");
}
var articleList = [];
var groups = [{
'name': 'Group 1',
'id': 'group-1',
'password': 'test1',
'articles': [{
'title': 'Cold Nose Article',
'filename': 'cold_nose_article'
},
{
'title': 'Exoplanet Article',
'filename': 'exoplanet_article'
},
{
'title': 'Osmosis Article',
'filename': 'osmosis_article'
}
]
},
{
'name': 'Group 2',
'id': 'group-2',
'password': 'test2',
'articles': [{
'title': 'Frogs Evaluation Article',
'filename': 'frogs_evolution_article'
},
{
'title': 'Soils & Nutrient Cycle',
'filename': 'table_readings_1'
},
{
'title': 'Earthworms Article',
'filename': 'table_readings_2'
}
]
}, {
'name': 'Group 3',
'id': 'group-3',
'password': 'test3',
'articles': [{
'title': 'Consume vs Consumed',
'filename': 'table_readings_3'
},
{
'title': 'An Alive Bug?',
'filename': 'table_readings_4'
},
{
'title': 'Nitrogen Cycle',
'filename': 'table_readings_5'
}
]
}, {
'name': 'Group 4',
'id': 'group-4',
'password': 'test4',
'articles': [{
'title': 'Carbon Cycle',
'filename': 'table_readings_6'
},
{
'title': 'Recycling the Dead',
'filename': 'table_readings_7'
},
{
'title': 'Gut Bacteria',
'filename': 'table_readings_8'
}
]
}
];

var articles = [{
var articleLibrary = [{
'title': 'Doctor with an eye for eyes',
'filename': 'doctor-with-an-eye-for-eyes'
},
Expand Down Expand Up @@ -113,59 +40,112 @@ var articles = [{
{
'title': 'The Camping Trip',
'filename': 'the-camping-trip'
},
{
'title': 'Cold Nose Article',
'filename': 'cold_nose_article',
'from': new Date('2024-12-20T10:00:00'),
'to': new Date('2024-12-20T16:30:00')
},
{
'title': 'Exoplanet Article',
'filename': 'exoplanet_article',
'from': new Date('2024-12-20T16:31:00'),
'to': new Date('2024-12-21T16:30:00')
},
{
'title': 'Osmosis Article',
'filename': 'osmosis_article',
'from': new Date('2024-12-22T16:31:00'),
'to': new Date('2024-12-23T16:30:00')
},
{
'title': 'Frogs Evaluation Article',
'filename': 'frogs_evolution_article'
},
{
'title': 'Soils & Nutrient Cycle',
'filename': 'table_readings_1'
},
{
'title': 'Earthworms Article',
'filename': 'table_readings_2'
},
{
'title': 'Consume vs Consumed',
'filename': 'table_readings_3'
},
{
'title': 'An Alive Bug?',
'filename': 'table_readings_4'
},
{
'title': 'Nitrogen Cycle',
'filename': 'table_readings_5'
},
{
'title': 'Carbon Cycle',
'filename': 'table_readings_6'
},
{
'title': 'Recycling the Dead',
'filename': 'table_readings_7'
},
{
'title': 'Gut Bacteria',
'filename': 'table_readings_8'
}
];

// var articles = [{
// 'title': 'Cold Nose Article',
// 'filename': 'cold_nose_article'
// },
// {
// 'title': 'Exoplanet Article',
// 'filename': 'exoplanet_article'
// },
// {
// 'title': 'Osmosis Article',
// 'filename': 'osmosis_article'
// },
// {
// 'title': 'Frogs Evaluation Article',
// 'filename': 'frogs_evolution_article'
// },
// {
// 'title': 'Soils & Nutrient Cycle',
// 'filename': 'table_readings_1'
// },
// {
// 'title': 'Earthworms Article',
// 'filename': 'table_readings_2'
// },
// {
// 'title': 'Consume vs Consumed',
// 'filename': 'table_readings_3'
// },
// {
// 'title': 'An Alive Bug?',
// 'filename': 'table_readings_4'
// },
// {
// 'title': 'Nitrogen Cycle',
// 'filename': 'table_readings_5'
// },
// {
// 'title': 'Carbon Cycle',
// 'filename': 'table_readings_6'
// },
// {
// 'title': 'Recycling the Dead',
// 'filename': 'table_readings_7'
// },
// {
// 'title': 'Gut Bacteria',
// 'filename': 'table_readings_8'
// }
// ];

var articleList = [];
var groups = [{
'name': 'Group 1',
'id': 'group-1',
'password': 'test1',
'articles': [articleLibrary[10], articleLibrary[11], articleLibrary[12]]
},
{
'name': 'Group 2',
'id': 'group-2',
'password': 'test2',
'articles': [articleLibrary[13], articleLibrary[14], articleLibrary[15]]
}, {
'name': 'Group 3',
'id': 'group-3',
'password': 'test3',
'articles': [articleLibrary[16], articleLibrary[17], articleLibrary[18]]
}, {
'name': 'Group 4',
'id': 'group-4',
'password': 'test4',
'articles': [articleLibrary[19], articleLibrary[20], articleLibrary[21]]
}
];
var articles = [
articleLibrary[0],
articleLibrary[1],
articleLibrary[2],
articleLibrary[3],
articleLibrary[4],
articleLibrary[5],
articleLibrary[6],
articleLibrary[7],
articleLibrary[8],
articleLibrary[9]
];
var articlesPrev = [
articleLibrary[10],
articleLibrary[11],
articleLibrary[12],
articleLibrary[13],
articleLibrary[14],
articleLibrary[15],
articleLibrary[16],
articleLibrary[17],
articleLibrary[18],
articleLibrary[19],
articleLibrary[20],
articleLibrary[21]
];
if (localStorage.getItem("auth") == "guest") {
articleList = articles;
} else {
Expand All @@ -175,7 +155,6 @@ if (localStorage.getItem("auth") == "guest") {
}
});
}

if (localStorage.getItem("currentArticle") === null) {
localStorage.setItem("currentArticle", articleList[0].filename);
localStorage.setItem("currentArticleTitle", articleList[0].title);
Expand Down
1 change: 1 addition & 0 deletions assets/main-working.js
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,7 @@
);
});
$(".teacher-facing #article-menu p span").text(localStorage.getItem("currentArticleTitle"));
$(".student-robot-facing #article-menu p span").text(localStorage.getItem("currentArticleTitle"));
$("#assignment-title").text(localStorage.getItem("currentArticleTitle"));
window.pathArticleTitle = localStorage.getItem("currentArticleTitle");
$.each(emotionsList, function(i, v) {
Expand Down
123 changes: 123 additions & 0 deletions assets/session-recording.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
var audioRecorders = new Map(); // Map to store recorder objects with IDs
var audioChunks = new Map(); // Map to store chunks for each ID
const today = new Date();
var sessionRecordingData = {
'title': formatAudioFileName(localStorage.getItem("currentArticleTitle"))
// will add the student usernames, password, related articles and deadlines here
// for now reusing the teacher side login info for the demo purposes
};
sessionInit();
$(document).on("click", "#start-assignment", function() {
startRecording(sessionRecordingData.title);
});

function sessionInit() {
$.each(articleList, function(i, v) {
$("#assignment-list").append(
"<li" +
((today >= v.from && today <= v.to) ?
' class="active"' :
"") +
' data-article="' +
v.filename +
'">' +
v.title + '. <span>Due: ' + formatDate(v.to) + '</span>' +
"</li>"
);
});
}

function formatDate(date) {
return date.toLocaleString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: true, // 12-hour clock
});
}

function formatAudioFileName(articleTitle) {
// Convert the string to lowercase and replace spaces or word breaks with dashes
// This is for audio file naming convention
const formatted = articleTitle
.toLowerCase() // Convert to lowercase
.replace(/\s+/g, '-') // Replace spaces or word breaks with dashes
.replace(/[^\w\-]/g, ''); // Optionally remove any non-alphanumeric characters (except dashes)

return formatted;
}

function startRecording(id) {
if (!id) {
console.error("Error: Please provide a unique ID to start the recording.");
return;
}

// Check if a recording with the same ID already exists
if (audioRecorders.has(id)) {
console.warn(`Warning: Recording with ID ${id} already exists. Stopping and saving it before starting a new one.`);
stopRecording(id); // Stop and save the existing recording
}

navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
const mediaRecorder = new MediaRecorder(stream);
const chunks = [];

mediaRecorder.ondataavailable = (e) => {
chunks.push(e.data);
};

mediaRecorder.onstop = () => {
const blob = new Blob(chunks, { type: 'audio/webm' });
audioChunks.set(id, blob); // Save blob to map for later use
saveRecording(blob, id); // Save the recording as a file
audioRecorders.delete(id); // Clean up map entry
audioChunks.delete(id);
console.log(`Recording ${id} saved and removed from active recorders`);
};

mediaRecorder.start();
audioRecorders.set(id, mediaRecorder); // Add to map
console.log(`Recording ${id} started`);
})
.catch(err => console.error('Error accessing microphone:', err));
}

function stopRecording(id) {
if (audioRecorders.has(id)) {
const recorder = audioRecorders.get(id);
recorder.stop();
console.log(`Recording ${id} stopped`);
} else {
console.error(`No active recording found with ID ${id}`);
}
}

function saveRecording(blob, id) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = `${id}.webm`; // Filename includes recording ID
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(url);
}

window.addEventListener('beforeunload', (event) => {
audioRecorders.forEach((recorder, id) => {
if (recorder.state === 'recording') {
recorder.stop();
console.log(`Recording ${id} stopped on unload`);
}
});

// Prevent the immediate closing of the tab
event.preventDefault();
event.returnValue = '';
});
Loading

0 comments on commit f9d1d3c

Please sign in to comment.