diff --git a/examples/jspsych-initialize-microphone.html b/examples/jspsych-initialize-microphone.html
index f0a859c1..fd8d5507 100644
--- a/examples/jspsych-initialize-microphone.html
+++ b/examples/jspsych-initialize-microphone.html
@@ -18,6 +18,7 @@
let ar = {
type: jsPsychHtmlAudioResponse,
stimulus: '
Speak!
',
+ allow_playback: true,
on_finish: (data) => {
console.log(data);
}
diff --git a/packages/plugin-html-audio-response/src/index.ts b/packages/plugin-html-audio-response/src/index.ts
index d4c556c3..31f389a2 100644
--- a/packages/plugin-html-audio-response/src/index.ts
+++ b/packages/plugin-html-audio-response/src/index.ts
@@ -16,7 +16,7 @@ const info = {
default: null,
},
/** How long to show the trial. */
- trial_duration: {
+ recording_duration: {
type: ParameterType.INT,
pretty_name: "Trial duration",
default: 2000,
@@ -25,6 +25,10 @@ const info = {
type: ParameterType.STRING,
default: "Continue",
},
+ allow_playback: {
+ type: ParameterType.BOOL,
+ default: false,
+ },
},
};
@@ -41,8 +45,10 @@ class HtmlAudioResponsePlugin implements JsPsychPlugin {
private stimulus_start_time;
private recorder_start_time;
private recorder: MediaRecorder;
+ private audio_url;
private response;
private load_resolver;
+ private rt: number = null;
constructor(private jsPsych: JsPsych) {}
@@ -52,22 +58,6 @@ class HtmlAudioResponsePlugin implements JsPsychPlugin {
this.setupRecordingEvents(display_element, trial);
this.startRecording();
-
- // setup timer for hiding the stimulus
- if (trial.stimulus_duration !== null) {
- this.jsPsych.pluginAPI.setTimeout(() => {
- this.hideStimulus(display_element);
- }, trial.stimulus_duration);
- }
-
- // setup timer for ending the trial
- if (trial.trial_duration !== null) {
- this.jsPsych.pluginAPI.setTimeout(() => {
- this.stopRecording().then(() => {
- this.endTrial(display_element, trial);
- });
- }, trial.trial_duration);
- }
}
private showDisplay(display_element, trial) {
@@ -95,9 +85,13 @@ class HtmlAudioResponsePlugin implements JsPsychPlugin {
private addButtonEvent(display_element, trial) {
display_element.querySelector("#finish-trial").addEventListener("click", () => {
const end_time = performance.now();
- const rt = Math.round(end_time - this.stimulus_start_time);
+ this.rt = Math.round(end_time - this.stimulus_start_time);
this.stopRecording().then(() => {
- this.endTrial(display_element, trial, rt);
+ if (trial.allow_playback) {
+ this.showPlaybackControls(display_element, trial);
+ } else {
+ this.endTrial(display_element, trial);
+ }
});
});
}
@@ -112,20 +106,44 @@ class HtmlAudioResponsePlugin implements JsPsychPlugin {
});
this.recorder.addEventListener("stop", () => {
- const url = new Blob(recorded_data_chunks, { type: "audio/webm" });
+ const data = new Blob(recorded_data_chunks, { type: "audio/webm" });
+ this.audio_url = URL.createObjectURL(data);
const reader = new FileReader();
reader.addEventListener("load", () => {
const base64 = (reader.result as string).split(",")[1];
this.response = base64;
this.load_resolver();
});
- reader.readAsDataURL(url);
+ reader.readAsDataURL(data);
});
this.recorder.addEventListener("start", (e) => {
+ // resets the recorded data
+ recorded_data_chunks.length = 0;
+
this.recorder_start_time = e.timeStamp;
this.showDisplay(display_element, trial);
this.addButtonEvent(display_element, trial);
+
+ // setup timer for hiding the stimulus
+ if (trial.stimulus_duration !== null) {
+ this.jsPsych.pluginAPI.setTimeout(() => {
+ this.hideStimulus(display_element);
+ }, trial.stimulus_duration);
+ }
+
+ // setup timer for ending the trial
+ if (trial.recording_duration !== null) {
+ this.jsPsych.pluginAPI.setTimeout(() => {
+ this.stopRecording().then(() => {
+ if (trial.allow_playback) {
+ this.showPlaybackControls(display_element, trial);
+ } else {
+ this.endTrial(display_element, trial);
+ }
+ });
+ }, trial.recording_duration);
+ }
});
}
@@ -140,13 +158,29 @@ class HtmlAudioResponsePlugin implements JsPsychPlugin {
});
}
- private endTrial(display_element, trial, rt: number = null) {
+ private showPlaybackControls(display_element, trial) {
+ display_element.innerHTML = `
+
+
+
+ `;
+
+ display_element.querySelector("#record-again").addEventListener("click", this.startRecording);
+ display_element.querySelector("#continue").addEventListener("click", () => {
+ this.endTrial(display_element, trial);
+ });
+
+ // const audio = display_element.querySelector('#playback');
+ // audio.src =
+ }
+
+ private endTrial(display_element, trial) {
// kill any remaining setTimeout handlers
this.jsPsych.pluginAPI.clearAllTimeouts();
// gather the data to store for the trial
var trial_data = {
- rt: rt,
+ rt: this.rt,
stimulus: trial.stimulus,
response: this.response,
estimated_stimulus_onset: Math.round(this.stimulus_start_time - this.recorder_start_time),