Skip to content

Commit 861cd1e

Browse files
authored
Merge pull request #3495 from jspsych/camera-recorder-default-mimetype
add default `mimeType` if none is specified
2 parents 51aefac + 54a9014 commit 861cd1e

File tree

5 files changed

+41
-4
lines changed

5 files changed

+41
-4
lines changed

.changeset/sixty-ears-tan.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"jspsych": patch
3+
---
4+
5+
add a default `mimeType` of `"video/webm" to `initializeCameraRecorder()`

docs/plugins/initialize-camera.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ button_label | string | 'Use this camera.' | The label for the select button.
2222
include_audio | bool | false | Set to `true` to include an audio track in the recordings.
2323
width | int | null | Request a specific width for the recording. This is not a guarantee that this width will be used, as it depends on the capabilities of the participant's device. Learn more about `MediaRecorder` constraints [here](https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints#requesting_a_specific_value_for_a_setting).
2424
height | int | null | Request a specific height for the recording. This is not a guarantee that this height will be used, as it depends on the capabilities of the participant's device. Learn more about `MediaRecorder` constraints [here](https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints#requesting_a_specific_value_for_a_setting).
25-
mime_type | string | null | Set this to use a specific [MIME type](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/mimeType) for the recording. Set the entire type, e.g., `'video/mp4; codecs="avc1.424028, mp4a.40.2"'`.
25+
mime_type | string | null | Set this to use a specific [MIME type](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/mimeType) for the recording. Set the entire type, e.g., `'video/mp4; codecs="avc1.424028, mp4a.40.2"'`. When provided with the default value of `null`, jsPsych will search for a compatible container/codec combination, with [common types listed here](../reference/jspsych-pluginAPI.md#initializecamerarecorder). If none are found, jsPsych will default to `'video/webm'` as the MIME type.
2626

2727

2828
## Data Generated

docs/reference/jspsych-pluginAPI.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,9 @@ None.
507507

508508
#### Description
509509

510-
Generates a `MediaRecorder` object from provided `MediaStream` and stores this for access via [`getCameraRecorder()`](#getcamerarecorder).
510+
Generates a `MediaRecorder` object from provided `MediaStream` and stores this for access via [`getCameraRecorder()`](#getcamerarecorder). By default, `mimeType` is set to the first compatible container/codec combination found in a list of common types, or `"video/webm"` if no supported combination is found.
511+
512+
The common container/codec combinations that jsPsych checks for are `"video/webm;codecs=vp9,opus"`, `"video/webm;codecs=vp8,opus"`, `"video/mp4;codecs=avc1.42E01E,mp4a.40.2"`, `"video/mp4;codecs=h264,aac"`, and `"video/mp4;codecs=hevc,aac"`.
511513

512514
#### Example
513515

examples/extension-record-video.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
const jsPsych = initJsPsych({
1414
extensions: [
1515
{type: jsPsychExtensionRecordVideo}
16-
]
16+
],
17+
on_finish: function() {
18+
jsPsych.data.displayData();
19+
}
1720
});
1821

1922
const initCamera = {

packages/jspsych/src/modules/plugin-api/MediaAPI.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,38 @@ export class MediaAPI {
284284
private camera_recorder: MediaRecorder = null;
285285

286286
initializeCameraRecorder(stream: MediaStream, opts?: MediaRecorderOptions) {
287+
let mimeType = this.getCompatibleMimeType() || "video/webm";
288+
const recorderOptions: MediaRecorderOptions = {
289+
...opts,
290+
mimeType
291+
}
292+
287293
this.camera_stream = stream;
288-
const recorder = new MediaRecorder(stream, opts);
294+
const recorder = new MediaRecorder(stream, recorderOptions);
289295
this.camera_recorder = recorder;
290296
}
291297

298+
// mimetype checking code adapted from https://github.com/lookit/lookit-jspsych/blob/develop/packages/record/src/videoConfig.ts#L673-L699
299+
/** returns a compatible mimetype string, or null if none from the array are supported. */
300+
private getCompatibleMimeType(): string {
301+
const types = [
302+
// chrome firefox edge
303+
"video/webm;codecs=vp9,opus",
304+
"video/webm;codecs=vp8,opus",
305+
// general
306+
"video/mp4;codecs=avc1.42E01E,mp4a.40.2",
307+
// safari
308+
"video/mp4;codecs=h264,aac",
309+
"video/mp4;codecs=hevc,aac",
310+
]
311+
for (const mimeType of types) {
312+
if (MediaRecorder.isTypeSupported(mimeType)) {
313+
return mimeType;
314+
}
315+
}
316+
return null;
317+
}
318+
292319
getCameraStream(): MediaStream {
293320
return this.camera_stream;
294321
}

0 commit comments

Comments
 (0)