Skip to content

Commit

Permalink
Merge pull request #83 from marianylund/main
Browse files Browse the repository at this point in the history
Added video several keyboard responses plugin
  • Loading branch information
jodeleeuw authored Dec 20, 2023
2 parents e41796c + 366e2d0 commit d7f4685
Show file tree
Hide file tree
Showing 12 changed files with 612 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/plugin-video-several-keyboard-responses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@jspsych/plugin-video-several-keyboard-responses": major
---

Added video plugin based on video-keyboard-response plugin that allows for multiple responses and records video time
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Plugin/Extension | Contributor | Description
[rdk](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-rdk/docs/jspsych-rdk.md#jspsych-rdk-plugin) | [Sivananda Rajananda](https://github.com/vrsivananda) | This plugin displays a Random Dot Kinematogram (RDK) and allows the subject to report the primary direction of motion by pressing a key on the keyboard.
[rok](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-rok/docs/jspsych-rok.md#jspsych-rok-plugin) | [Younes Strittmatter](https://github.com/younesStrittmatter) | This plugin displays a Random Object Kinematogram (ROK) and allows the subject to report the primary direction of motion or the primary orientation by pressing a key on the keyboard.
[self-paced-reading](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-self-paced-reading/docs/jspsych-self-paced-reading.md) | [@igmmgi](https://github.com/igmmgi) | Self-paced reading tasks with different display options.
[video-several-keyboard-responses](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-video-several-keyboard-responses/docs/jspsych-video-several-keyboard-responses.md)|[@marianylund](https://github.com/marianylund) | This plugin is based on [video-keyboard-response](https://github.com/jspsych/jsPsych/tree/main/packages/plugin-video-keyboard-response) with possibility of recording multiple responses together with video timestamps.
[vsl-animate-occlusion](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-vsl-animate-occlusion/docs/jspsych-vsl-animate-occlusion.md#jspsych-vsl-animate-occlusion-plugin) | [Josh de Leeuw](https://github.com/jodeleeuw) | The VSL (visual statistical learning) animate occlusion plugin displays an animated sequence of shapes that disappear behind an occluding rectangle while they change from one shape to another.
[vsl-grid-scene](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-vsl-grid-scene/docs/jspsych-vsl-grid-scene.md#jspsych-vsl-grid-scene-plugin) | [Josh de Leeuw](https://github.com/jodeleeuw) | The VSL (visual statistical learning) grid scene plugin displays images arranged in a grid.

Expand Down
Empty file.
3 changes: 3 additions & 0 deletions packages/plugin-video-several-keyboard-responses/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @jspsych/plugin-video-several-keyboard-responses


35 changes: 35 additions & 0 deletions packages/plugin-video-several-keyboard-responses/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# plugin-video-several-keyboard-responses

## Overview

This plugin plays a video and records responses generated by the keyboard, based on [plugin-video-keyboard-response](https://www.jspsych.org/latest/plugins/video-keyboard-response). The stimulus can be displayed until the end or for a pre-determined amount of time. In addition to responses and response times, the video time is saved when a response is given using a keyboard.

## Loading

### In browser

```js
<script src="https://unpkg.com/@jspsych-contrib/[email protected]">
```

### Via NPM

```
npm install @jspsych-contrib/plugin-video-several-keyboard-responses
```

```js
import jsPsychVideoSeveralKeyboardResponses from '@jspsych-contrib/plugin-video-several-keyboard-responses';
```

## Compatibility

jsPsych v7.3.4

## Documentation

See [documentation](docs/jspsych-video-several-keyboard-responses.md)

## Author / Citation

This plugin was created by [marianylund](https://github.com/marianylund) with support from the [Department of Psychology](https://www.sv.uio.no/psi/english/index.html) at the University of Oslo.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# jspsych-self-paced-reading plugin

Based on [video-keyboard-response](https://github.com/jspsych/jsPsych/tree/main/packages/plugin-video-keyboard-response) plugin, this plugin allows playing video and recording multiple responses together with video timestamps.

## Parameters

In addition to the [parameters available in all plugins](https://www.jspsych.org/overview/plugins#parameters-available-in-all-plugins) and [video-keyboard-response](https://github.com/jspsych/jsPsych/blob/main/docs/plugins/video-keyboard-response.md) plugin, this plugin accepts the following parameters. Parameters with a default value of _undefined_ must be specified. Other parameters can be left unspecified if the default value is acceptable.

| Parameter | Type | Default Value | Description |
| -------------------------- | ---- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| multiple_responses_allowed | bool | true | If true, multiple responses are recorded. If false, only the first response will be recorded, thus behaving as video-keyboard-response plugin. |

## Data Generated

In addition to the [default data collected by all plugins](https://www.jspsych.org/overview/plugins#data-collected-by-all-plugins), this plugin collects the following data for each trial.

| Name | Type | Value |
| ---------- | -------- | ---------------------------------------------------------------- |
| video_time | number[] | Array of playback positions of video when response was given (s) |

## Example

```javascript
const trial = {
type: VideoSeveralKeyboardResponsesPlugin,
stimulus: ['video/sample_video.mp4'],
choices: "ALL_KEYS",
prompt: "Press any keys",
width: 600,
autoplay: true,
trial_ends_after_video: true,
response_ends_trial: false,
response_allowed_while_playing: true,
multiple_responses_allowed: true,
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);
44 changes: 44 additions & 0 deletions packages/plugin-video-several-keyboard-responses/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@jspsych/plugin-video-several-keyboard-responses",
"version": "0.1.0",
"description": "jsPsych plugin for playing a video file and getting several keyboard responses",
"type": "module",
"main": "dist/index.cjs",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --passWithNoTests",
"test:watch": "npm test -- --watch",
"tsc": "tsc",
"build": "rollup --config",
"build:watch": "npm run build -- --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/jspsych/jspsych-contrib.git",
"directory": "packages/plugin-video-several-keyboard-responses"
},
"author": "Maria Emine Nylund",
"license": "MIT",
"bugs": {
"url": "https://github.com/jspsych/jspsych-contrib/issues"
},
"homepage": "https://github.com/jspsych/jspsych-contrib/tree/main/packages/plugin-video-several-keyboard-responses",
"peerDependencies": {
"jspsych": ">=7.1.0"
},
"devDependencies": {
"@jspsych/config": "^2.0.0",
"@jspsych/test-utils": "^1.1.2",
"jspsych": "^7.1.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { makeRollupConfig } from "@jspsych/config/rollup";

export default makeRollupConfig("jsPsychVideoSeveralKeyboardResponses");
82 changes: 82 additions & 0 deletions packages/plugin-video-several-keyboard-responses/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { pressKey, simulateTimeline, startTimeline } from "@jspsych/test-utils";
import { initJsPsych } from "jspsych";

import videoSeveralKeyboardResponses from ".";

jest.useFakeTimers();

beforeAll(() => {
window.HTMLMediaElement.prototype.pause = () => {};
});

// I can't figure out how to get this tested with jest
describe("video-several-keyboard-responses", () => {
test("throws error when stimulus is not array #1537", async () => {
const jsPsych = initJsPsych();

const timeline = [
{
type: videoSeveralKeyboardResponses,
stimulus: "foo.mp4",
},
];

await expect(async () => {
await jsPsych.run(timeline);
}).rejects.toThrowError();
});
});

describe("video-several-keyboard-responses simulation", () => {
test("data mode works", async () => {
const timeline = [
{
type: videoSeveralKeyboardResponses,
stimulus: ["foo.mp4"],
},
];

const { expectFinished, getData } = await simulateTimeline(timeline);

await expectFinished();

expect(getData().values()[0].rt).toBeGreaterThan(0);
expect(typeof getData().values()[0].response).toBe("string");
});

// can't run this until we mock video elements.
test("visual mode works", async () => {
const jsPsych = initJsPsych();

const timeline = [
{
type: videoSeveralKeyboardResponses,
stimulus: ["foo.mp4"],
prompt: "foo",
trial_duration: 1000,
},
];

const { expectFinished, expectRunning, getHTML, getData } = await simulateTimeline(
timeline,
"visual",
{},
jsPsych
);

await expectRunning();

expect(getHTML()).toContain("foo");

jest.runAllTimers();

await expectFinished();

const rt = getData().values()[0].rt;
const response = getData().values()[0].response;
const video_time = getData().values()[0].video_time;
expect(rt.every(value => value > 0)).toBe(true);
expect(response.every(value => typeof value === "string")).toBe(true);
expect(video_time.every(value => typeof value === "number")).toBe(true);
});
});
Loading

0 comments on commit d7f4685

Please sign in to comment.