Garbage frames when switching ofVideoPlayers

So I’m writing an app that basically plays one video on loop until the user interacts, then it switches to another video while it runs a shell script, then switches back to a confirmation video, before switching back to the initial video loop. The problem is that every time I switch to that middle video (which I’m trying to start from frame 0), I get a flash frame of wherever it left off last time it was switched away from. The first time I start the app I get a garbage frame in there (icons, pieces of desktop, etc).

Setup:

ofHideCursor();                             // Hide the cursor
ofSetVerticalSync(true);

outputFile = "scriptstatus.txt";

loop.loadMovie("_loop.mov");                // Load the video file into the project
getReady.loadMovie("_getReady.mov");        // Load the video file into the project
printing.loadMovie("_printing.mov");        // Load the video file into the project

loop.play();                          // Start the intro-loop when launching the application
loop.setSpeed(1);
loop.setLoopState(OF_LOOP_NORMAL);

printing.play();                      // Start the printing screen playing
printing.setSpeed(1);
printing.setLoopState(OF_LOOP_NORMAL);

getReady.setPaused(true);             // prep the getReady screen
getReady.setSpeed(1);
getReady.setLoopState(OF_LOOP_NORMAL);

whichVidIsPlaying = "loop";

My draw funtion:

ofBackground(0, 0, 0);
ofSetColor(255, 255, 255);

// Play the appropriate video
if (whichVidIsPlaying == "loop" ){
    loop.draw(0, 0, ofGetWidth(), ofGetHeight());       // Draw the current video frame
}
else if (whichVidIsPlaying == "getReady" ){
    getReady.draw(0, 0, ofGetWidth(), ofGetHeight());   // Draw the current video frame
}
else if (whichVidIsPlaying == "printing" ){
    printing.draw(0, 0, ofGetWidth(), ofGetHeight());   // Draw the current video frame
}

Update function:

loop.update();          // Decode the new frame if needed
getReady.update();      // Decode the new frame if needed
printing.update();      // Decode the new frame if needed

// check to see if the output files exists and switch videos according to what it says
if (ofFile::doesFileExist(outputFile, true))
{
    // this is our buffer to store the text data
    ofBuffer buffer = ofBufferFromFile(outputFile);
    string bufferString(buffer); 
    scriptStatus = bufferString;
    scriptStatus.erase(std::remove(scriptStatus.begin(), scriptStatus.end(), '\n'), scriptStatus.end());  // remove newline characters
    
    // Play the printing video when the photos are done being taken
    if ( scriptStatus == "696969" ) {
        getReady.setFrame(0);
        getReady.update();
        getReady.setPaused(true);
        whichVidIsPlaying = "printing";
    }
    // Play the intro-loop when the printing video is done
    if ( scriptStatus == "969696" ) {
        whichVidIsPlaying = "loop";
        permissions.startThread(true);
    }
}

When the user clicks the mouse:

if (whichVidIsPlaying == "loop" ) {
    
    // Play the get-ready video
    getReady.setFrame(0);
    getReady.update();
    getReady.play();
    whichVidIsPlaying = "getReady";
    thread.startThread(true);
}

So it’s the getReady video that’s giving me trouble, because I’m trying to restart it from frame 0 – the others switch no problem (they just loop in the background happily I suppose). I’ve tried moving the .update() function just about everywhere I could think to but I still get a flash from the middle of the video before it restarts… any help would be much appreciated!

1 Like

OK I was finally able to solve this!

My problem lay here (in the mouse click):

if (whichVidIsPlaying == "loop" ) {
    // Play the get-ready video
    getReady.setFrame(0);
    getReady.update();
    getReady.play();
    whichVidIsPlaying = "getReady";
    thread.startThread(true);
}

with whichVidIsPlaying = "getReady"; I was telling it to switch to the “getReady” video with no regard to whether or not the video was ready to be played. So when it got back to my draw() function, it would try to draw the video, but since the first frame wasn’t ready yet, it would just draw the garbage frame that was in memory.

I solved this by removing whichVidIsPlaying = "getReady"; from the mouse-click listener and adding this line into my update function:

if (getReady->isFrameNew() == 1){   // only switch to the getReady video when it's ready to avoid garbage frame
    whichVidIsPlaying = "getReady";
}

so basically, instead of switching to getReady when the user clicks the mouse, I just play getReady when they click, and then switch a fraction of a second later when there’s a new frame ready (not a garbage frame).

Oh I also switched to pointers somewhere along the way which is why there’s a ->