Skip to content

External Application Data Recorder - Network Integration Guide

This guide explains how to control the SightLab Data Recorder from external applications like Unreal Engine, Unity, or other networked programs.

Overview

The recorder supports UDP-based networking to receive commands from external applications. This allows you to:
- Start/stop recording trials remotely
- Send synchronization markers during experiments
- Receive acknowledgment messages from the recorder

Configuration

In Data_Recorder_Config.py

# Enable network control
USE_NETWORK_EVENT = True          # Enable network listening
NETWORK_START = True              # Use network events to start trials (instead of spacebar)

# Network settings
NETWORK_HOST = 'localhost'        # Host to listen on
NETWORK_PORT = 4950               # UDP port number

# Event names (must match what your external app sends)
NETWORK_START_EVENT_NAME = 'start_trial'  # JSON event name to trigger recording

# Sync settings
NETWORK_SYNC_KEY = 't'            # Keyboard key for manual sync
NETWORK_SYNC_EVENT = 'triggerPress'  # Event name for sync markers

How It Works

1. Network Setup

The recorder creates a UDP listener on the specified NETWORK_HOST and NETWORK_PORT. It listens for incoming JSON messages from external applications.

2. Message Format

External applications should send JSON-formatted strings via UDP:

{
  "event": "start_trial"
}

3. Supported Events

Event Name Purpose Response
start_trial (configurable via NETWORK_START_EVENT_NAME) Starts a recording trial Sends {"event":"ack_start", "trial": N}
sync Inserts a synchronization marker in the data Broadcasts sync to external apps

4. Bidirectional Communication

The recorder can also send messages back to external apps:
- Acknowledgments when trials start
- Sync event notifications
- Custom trial/timestamp data

Example: Unreal Engine Integration

Unreal Blueprint Setup

  1. Create a UDP Socket (port 4950)
  2. Send JSON string to start recording:
{"event": "start_trial"}
  1. Listen for acknowledgment:
{"event": "ack_start", "trial": 1}

Sample Unreal C++ Code

// Send start command
FString JsonMsg = TEXT("{\"event\":\"start_trial\"}");
Socket->SendTo((uint8*)TCHAR_TO_UTF8(*JsonMsg), JsonMsg.Len(), BytesSent, *RemoteAddr);

Example: Unity Integration

using System.Net;
using System.Net.Sockets;
using System.Text;

UdpClient client = new UdpClient();
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4950);

// Start recording
string json = "{\"event\":\"start_trial\"}";
byte[] data = Encoding.UTF8.GetBytes(json);
client.Send(data, data.Length, endPoint);

Workflow

With NETWORK_START = True:

  1. External app sends {"event": "start_trial"}
  2. Recorder receives message and starts trial automatically
  3. Recorder sends acknowledgment back
  4. Recording begins
  5. Use timer or manual stop to end trial

With NETWORK_START = False:

  1. Use spacebar (or START_END_SESSION_KEY) to start
  2. External app can still send sync events during recording
  3. Spacebar to stop

Sync Markers

During a trial, send sync events to mark important moments:

{"event": "sync"}

This will:
- Log a timestamp in the trial data
- Insert a marker in Biopac (if enabled)
- Broadcast the sync to all connected apps

Testing

Simple Python Test Script

import socket
import json

# Create UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('localhost', 4950)

# Send start command
message = json.dumps({"event": "start_trial"})
sock.sendto(message.encode(), server_address)

print("Sent start command to recorder")

Troubleshooting

  1. No response from recorder
  2. Verify USE_NETWORK_EVENT = True
  3. Check firewall settings for UDP port 4950
  4. Ensure recorder is running before sending messages

  5. Wrong event name

  6. Match NETWORK_START_EVENT_NAME in config with JSON "event" field
  7. Case-sensitive matching

  8. Port conflicts

  9. Change NETWORK_PORT if 4950 is already in use
  10. Update external app to match

Advanced: Custom Data Exchange

You can extend the network handler in External_Application_Data_Recorder.py (around line 770):

def onNetwork(e):
    try:
        msg = e.raw_data.decode('utf-8', errors='ignore')
        data = json.loads(msg)
        evt = data.get('event')

        if evt == 'custom_event':
            # Your custom handling here
            print('Received custom event:', data)

    except Exception:
        print('[NET] Error parsing:', e.raw_data)

Summary

  • UDP-based: Lightweight, connectionless protocol
  • JSON messages: Simple, human-readable format
  • Bidirectional: Recorder can send acknowledgments back
  • Flexible: Works with Unity, Unreal, Python, and any UDP-capable app
  • Sync markers: Insert timestamps during experiments for alignment
Was this page helpful?