Outputting current MovieStim name to be read by Unity

Hi all,

Is there a way to have PsychoPy output what MovieStim file is currently playing to the console, or in some way that is readable to another program like Unity?

I’m creating a reaction time task by randomly presenting 24 videos with button press responses. This is to be synced up with another task in Unity which is displaying objects depending on what video is currently playing. I need the filename of the current MovieStim object that is playing to be outputted in some way that can be read into Unity to load the right content.

I’ve tried adding code blocks in Builder and adding print(MovieStim.name) statements when the item is called in Coder, but with no luck. Since I want the videos to play in random order, I need PsychoPy to tell me what file it has chosen from the list to play and then present that to Unity dynamically.

Thanks in advance!

One way that I can think of is to send a message over the localhost network using the UDP protocol. In Python you could send a message as follows:

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"

print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE.encode(), (UDP_IP, UDP_PORT))

Listening to the message in Unity (using C#) can be somewhat complicated depending on whether you want to listen for the message synchronously (i.e., your application blocks until a message is received) or asynchronously (the application does not block and the message is received in a callback function).

Alternatively, I think in C# you also have something called a File Watcher which you can use to trigger events in case a specific file has changed. In that case, you could write the name of the movie to a file and in Unity the file watcher will pick this up.

Extending Cristophe’s answer, you might want to do this via LabStreamingLayer (LSL) which is designed to provide a steam of experiment events like this, timestamped and across any machines/processes. Cristophe isn’t wrong that you could do this with UDP sockets, but LSL might get some of the tricker bits done for you.

PsychoPy provides the python LSL library and there is also one for Unity as below, so with both of those you should be good to go!

Thank you both for your responses! In the end I’m using a somewhat hacky way to write the file name by removing the path and printing it to a text file to be read by Unity.

I couldn’t get LSL working to just print a string with the example files. Is there a tutorial or something anywhere?

Here’s the very basic but functional python code chunk for anyone in the future with the same problem


printed = False # Assign the variable before starting the trial loop

if printed is False:
   VidName = hazard_video.filename # assign the name of the MovieStim object to a variable
   #print(VidName)
    StopNameIndex = VidName.find("\\", -20,) # takes from the back of the file path - needs to be long!
    ShortVidName = VidName[StopNameIndex+1:-4] # remove the .mp4 characters at the back and 
    with open("VideoName.txt", "w") as f:
        f.write(ShortVidName) # write a textfile containing only the name of the current clip
    printed = True

and the short C# script to read the outputted file if it’s on the same machine

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class FileReader : MonoBehaviour
{
    
    public string currentClip;

    public string ReadString()
    {
        string path = "%PATH/TO/TXT/FILE%/VideoName.txt";

        StreamReader reader = new StreamReader(path, true);
        currentClip = reader.ReadToEnd();
        reader.Close();

        return currentClip;
    }

    void Update()
    {
        ReadString();
    }

}