VideoBox is a Swiss army knife for video recording, streaming, mirroring that we have used for our experiments in gesture and artificial sign language research. It enables researchers to use familiar tools like PsychoPy but still carry our experiments involving streaming and recording videos between multiple machines on a network which would be very difficult otherwise. There are two versions of the software. VideoBoxABCD, which is the simpler version, allowing single videos to be played in each window, and VideoBoxMulti, which lets you tile four videos for playback, and overlay graphics on the video (e.g. for indicating correct or incorrect choices of video stimuli).
Full instructions are included in each zip file, but the setup that is common to both is given below. VideoBox is available as a Mac app, and was developed by Simon Kirby in Max 7. Source code is included.
Note that a security feature on the Mac means that you won’t be able to run VideoBox by default (and indeed, an unhelpful message about the file being “damaged” may pop up). If you are using a version of OSX prior to Sierra, you will be able to change your settings in the “Security & Privacy” preference pane to allow apps to be run that have been downloaded from anywhere (as opposed to just the App Store). Unfortunately, in Sierra, Apple removed this possibility. To get it back, you need to enter the following command in the Terminal app:
sudo spctl --master-disable
If you use VideoBox, please cite it as follows:
Kirby, S. (2016). VideoBox: video recording, streaming and mirroring for experiments [Computer software]. Retrieved from
All communications with VideoBox are done using a UDP socket (usually port 7605).
For example, in Python:
from socket import * socket(AF_INET, SOCK_DGRAM).sendto('COMMAND',('127.0.0.1',7605))
where “COMMAND” is one of the following:
- device NUMBER, selects the camera attached to your computer with the device number (defaults to 0)
- ip IP_ADDRESS, selects the destination for the streamed unmirrored camera feed (defaults to 127.0.0.1)
- camera, makes the camera visible (mirrored)
- file “FILENAME”, starts playing the named video file (note quote marks, needed in case of spaces etc. in the file path)
- pause, pauses playback
- play, restarts playback
- loop, sets the mode of playback to looping
- noloop, sets the mode of playback to one shot (the default)
- frame NUMBER, jumps playback to a particular frame in the file
- jump NUMBER, jumps playback to a frame relative to the current playback point
- stream, shows whatever video is being streamed to the computer
- record “FILENAME”, starts recording camera to video file (non mirrored). N.B. Recording never overwrites a file.
- stop, stops any recording
- blank, shows blank screen
Streaming, file recording, playing other streams, and mirrored video all happen simultaneously and independently. For example, this means you can stream to another computer while watching the stream from a different machine, and record to a file the camera feed. You can also switch camera devices and destinations for the feed on the fly. If necessary, you can even control the VideoBox software from a different device, such as an iPad – just change the 127.0.0.1 bit above to the IP address of the VideoBox machine.
The videos are saves in PhotoJPEG format at 30 frames per second, 640×360 resolution in “normal” quality. This format is quite expensive in terms of space, but very good quality, and does no temporal compression at all, which is important for motion analysis. The streaming is lower quality, in order to make it run fast, but I can probably tweak this if necessary.
To get the IP address of the VideoBox machine, you can look in system preferences, option-clicking the wifi icon in the mac toolbar, or sometimes the following works in Python (if it shows 127.0.0.1, then it hasn’t worked):
from socket import * gethostbyname(gethostname())
Below is an example session, setting up IP address to stream to, showing the camera, after 1 second recording a 3 second clip, blanking the screen, after 1 second showing the clip back, blanking the screen again for 1 second, then watching a stream if being sent one from another machine:
from socket import * from time import sleep def video_command(command): socket(AF_INET,SOCK_DGRAM).sendto(command,('127.0.0.1',7605)) video_command('ip 172.20.131.89') video_command('camera') sleep(1) video_command('record "~/Desktop/test.mov"') sleep(3) video_command('stop') video_command('blank') sleep(1) video_command('file "~/Desktop/test.mov"') sleep(3) video_command('blank') sleep(1) video_command('stream')