Skip to main content

OpenVIMO video calling

OpenVIMO is a platform for videocalling built as a covfee task. It's main application is recording of online social interaction such as pair conversations or online meetings. Among its features are:

  • Different study designs can be specified in Python using a graph structure.
  • Crowdsourcing support through covfee.
  • Videocalls can be timed.
  • Chat with data subjects.
  • Admin can view the videocalls without interferring. Please use responsibly by informing data subjects if you intend to use this feature.
  • Admin can pause, restart or force stop the videocalls.

Installation

Here we provide instructions for testing OpenVIMO in development mode. To know how to move an OpenVIMO app to production, see below.

First install covfee following the development install instructions.

OpenVIMO is built on top of OpenVIDU, an open-source WebRTC framework with an on-premise server that integrates an API for handling calls, a STUN/TURN server and recording capabilities. The OpenVIDU server should be ran separately. To do it, follow OpenVIDU deployment instructions.

Sample 1: meeting room

Here we create a simple covfee app for meeting rooms with shareable URLs. This can function as a flexible deployment for holding (regular) meetings in covfee and recording them into a dataset.

In covfee experiments (HITs) are always specified by a list of nodes or tasks, and a list of journeys or paths through those nodes. Each of these journeys maps to a URL, and normally to one participant. However, because in this case we want to allow an arbitrary number of participants to join the videocall using the same URL, we will create a single journey. The graph structure of this deployment is therefore very simple:

First we will create a folder for the covfee project. This folder may be anywhere in the file system. Then we will create the following structure:

my_folder
- meeting.py

The naming is not relevant. Paste the following into the meeting.py:

from covfee import HIT, Project, tasks
from covfee.config import config
from covfee.shared.dataclass import CovfeeApp

config.load_environment("local")

spec_meeting = {
"name": "Videocall",
"serverRecording": {
"hasAudio": True,
"hasVideo": True,
"outputMode": "INDIVIDUAL",
},
}

t1 = tasks.VideocallTaskSpec(**spec_meeting)
hit = HIT("Videocalling")
hit.add_journey(nodes=[t1])

projects = [Project("My Project", email="example@example.com", hits=[hit])]
app = CovfeeApp(projects)

Here we import the necessary classes, create a VideocallTaskSpecs object holding the specification of our videocalling task, and assign it to a journey, a HIT and a project (more information). Finally, we create the app object. Covfee internally looks for this object by name (important that it is called app) and uses it as starting point to read the specification.

  • The full list of options for the VideocallTaskSpec is provided below.

That is all! We are now ready to start Covfee. To run it in development mode:

covfee make meeting.py --force --dev

This will parse the specification, create the database, and start the covfee server.

And make sure to start webpack on another tab (more info):

covfee webpack

After this the Covfee admin panel should be accessible in the URL displayed when running the Covfee server (http://localhost:5000/admin# by default).

For more information about running Covfee in development mode see here.

Sample 2: dyadic conversations

This sample creates a more complex HIT structure. Here we want two subjects to fill in individual consent forms, then have a videocall together, and then fill in post-experiment surveys. The graph structure for this interaction is:

We can code this structure with the following code:

# from covfee import Task, HIT
from covfee import HIT, Project, tasks
from covfee.config import config
from covfee.shared.dataclass import CovfeeApp

config.load_environment("local")

spec_consent_form = {
"name": "Consent",
"content": {"type": "link", "url": "$$www$$/consent.md"},
"form": {
"fields": [
{
"name": "name",
"label": "Full name:",
"required": True,
"input": {"inputType": "Input"},
},
{
"name": "consent",
"label": "To proceed, you must expressly provide consent per the terms above.",
"required": True,
"input": {
"inputType": "Checkbox.Group",
"options": [
{
"label": "I consent to the sharing of my personal data.",
"value": "yes",
}
],
},
},
]
},
}

spec_instructions = {
"name": "Instructions",
"prerequisite": True,
"content": {"type": "link", "url": "$$www$$/instructions.md"},
"form": {
"fields": [
{
"name": "agreement",
"label": "To proceed, you must expressly agree to the provided instructions.",
"required": True,
"input": {
"inputType": "Checkbox.Group",
"options": [
{
"label": "I agree with the provided instructions.",
"value": "yes",
}
],
},
}
]
},
}

spec_videocall = {
"name": "Videocall",
}

spec_final_survey = {
"name": "Final Survey",
"form": {
"fields": [
{
"name": "enjoyment",
"label": "Did you enjoy your interaction?",
"required": True,
"input": {
"inputType": "Radio.Group",
"options": ["Yes", "No"],
},
}
]
},
}
j1_consent = tasks.InstructionsTaskSpec(**spec_consent_form)
j1_instructions = tasks.InstructionsTaskSpec(**spec_instructions)
j1_final = tasks.QuestionnaireTaskSpec(**spec_final_survey)

j2_consent = tasks.InstructionsTaskSpec(**spec_consent_form)
j2_instructions = tasks.InstructionsTaskSpec(**spec_instructions)
j2_final = tasks.QuestionnaireTaskSpec(**spec_final_survey)

videocall_task = tasks.VideocallTaskSpec(**spec_videocall)


hit = HIT("Dyadic videocall")
j1 = hit.add_journey(nodes=[j1_consent, j1_instructions, videocall_task, j1_final])
j1 = hit.add_journey(nodes=[j2_consent, j2_instructions, videocall_task, j2_final])

projects = [Project("My Project", email="example@example.com", hits=[hit])]
app = CovfeeApp(projects)

Moving to production

  1. Make sure that OpenVIDU is installed in your server in production mode. Recording requires a server with significant resources and open ports.

  2. Move your covfee app to production by following Covfee's deployment instructions.

Configuration options

The full list of configuration options for the videocalling task:

allowMute

Type: boolean

Default:

Description: Allow the user to mute their own audio

allowScreenShare

Type: boolean

Default:

Description: Allow the user to share their screen

allowStopVideo

Type: boolean

Default:

Description: Allow the user to stop their own video

countdown

Type: number

Default: 0

Description: Seconds countdown after start condition met.

instructions

Type: string

Description: Instructions to be displayed for the node

instructions_type

Type: string

Default: 'default'

Description: How the instructions will be displayed

layout

Type: string

Default: 'grid

Description: Layout mode

max_submissions

Type: number

Default: 0

Description: Maximum number of submissions a user can make for the task.

muted

Type: boolean

Default:

Description: Videocall is muted

n_pause

Type: number

Description: If the number of subjects is n_pause or less, the task will be paused

n_start

Type: number

Description: Number of jorneys required to start task

name

Type: string

prerequisite

Type: boolean

Default: False

Description: Node is marked as a prerrequisite Prerrequisite nodes must be completed before the rests of the nodes in the HIT are revealed.

required

Type: boolean

Default: True

Description: If true, this node must have a valid submission before the HIT can be submitted

serverRecording

Type: object

Description: Recording options for OpenVIDU

enable

Type: boolean

Description: Enable server recording

frameRate

Type: number

Default: 25

Description: Only applies for COMPOSED output mode

hasAudio

Type: boolean

Description: Record audio

hasVideo

Type: boolean

Description: Record video

outputMode

Type: string

Description: record all streams in a single file in a grid layout or record each stream in its own separate file.

resolution

Type: string

Default: 1280x720

Description: Video resolution. Only applies for COMPOSED output mode

timer

Type: number

Description: Time to complete the task

timer_empty

Type: number

Description: Empty timer is started everytime the task is empty (no journeys online) If the timer reaches zero, the task is set to finished state.

timer_pausable

Type: boolean

Description: If true, the timer will pause when the task is paused.

timer_pause

Type: number

Description: Pause timer is started every time the task enters paused state If timer reaches zero, the task is set to finished state.

type

Type: string

Default: VideocallTask

useSharedState

Type: boolean

Description: If true, the task state will be synced between clients. This applies both to multiple clients in the same journey and across journeys. Internally covfee uses socketio to synchronize task state.

videoOff

Type: boolean

Default:

Description: Call is audio only video is always off

wait_for_ready

Type: boolean

Description: If true, all journeys must click ready to start the task