ofVideoPlayer playback optimizing

Hi, I’m new to oF but I’ve been doing media programming and development in node based softwares for years. So just trying to build simple apps to replicate some features for now.

I’m trying to make a simple setup where 2 movies are playing, and space bar crossfades between them. That seems to work alright, but then I’m trying to add another element, which is drag and dropping a movie onto the preview areas of each side of the crossfader to load a new video, I’m hitting a wall. It seems to stall the whole process when it tries to load the new movie, not sure if I have to do that on another thread? Anyways, would love some commentary and feedback on the overall app anyways to make sure I’m on the right track. Thanks!

On a side note, couldn’t figure out the best way to paste code in here, as it seems to have changed up my indentation a little bit. Any tips would be great.

This is in my ofApp.h

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

public:
	void setup();
	void update();
	void draw();

	void keyPressed(int key);
	void keyReleased(int key);
	void mouseMoved(int x, int y );
	void mouseDragged(int x, int y, int button);
	void mousePressed(int x, int y, int button);
	void mouseReleased(int x, int y, int button);
	void windowResized(int w, int h);
	void dragEvent(ofDragInfo dragInfo);
	void gotMessage(ofMessage msg);

    ofVideoPlayer deck1;
    ofVideoPlayer deck2;

    bool frameByFrame;

    float alphaBlend1;
    float alphaBlend2;

    float increment;
    float rampVal;

    enum animStates {
        ANIM_STOP,
        ANIM_UP,
        ANIM_DOWN
    };

    animStates currentState;
};

and this is in my ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

//setup the window
ofBackground(ofColor::black);
ofSetWindowTitle("video cross");
ofSetFrameRate(30);
ofSetVerticalSync(true);


//load and play decks
deck1.loadMovie("movies/01.mp4");
deck2.loadMovie("movies/02.mp4");

deck1.play();
deck1.setVolume(0.0);
deck2.play();
deck2.setVolume(0.0);


//setup ramp
currentState = ANIM_STOP;
increment = 1/120.0f;
rampVal = 0.0f;

//setup default alphas
alphaBlend1 = 0.0f;
alphaBlend2 = 1.0f - alphaBlend1;
}

//--------------------------------------------------------------
void ofApp::update(){
    //update movie frames
    deck1.update();
    deck2.update();
    
//do animation here if animation state changed
if (currentState == ANIM_STOP)
{
    
} else if (currentState == ANIM_UP)
{
    /*
    cout << "rising " << "rampVal = " << rampVal << " - increment = " <<                //print out all info
        increment << " - alphaBlend1 = " << alphaBlend1 << " - alphaBlend2 = " <<
            alphaBlend2 << endl;
    */
     
    alphaBlend2 += increment;                                                           //add to alphablend2
    alphaBlend1 = 1.0f - alphaBlend2;                                                   //invert alphablend2 for alphablend1
    
    if (alphaBlend2 >= 0.99)
    {
        cout << "done" << endl;                                                         //switch state back to animation stop
        currentState = ANIM_STOP;
    }
} else if (currentState == ANIM_DOWN)
{
    /*
    cout << "going down " << "rampVal = " << rampVal << " - increment = " <<            //print out all info
        increment << " - alphaBlend1 = " << alphaBlend1 << " - alphaBlend2 = " <<
            alphaBlend2 << endl;
    */
     
    alphaBlend2 -= increment;                                                           //decrease alphablend2
    alphaBlend1 = 1.0f - alphaBlend2;                                                   //invert for alphablend1
    
    if (alphaBlend2 <= 0.01)
    {
        cout << "done" << endl;
        currentState = ANIM_STOP;                                                       //switch state back to animation stop
    }
}


   
}

//--------------------------------------------------------------
void ofApp::draw(){

    //draw live window background
ofEnableAlphaBlending();
ofSetColor(255 * alphaBlend1,255 * alphaBlend1,255 * alphaBlend1,255 * alphaBlend1);            //set alpha of deck1
deck1.draw(0.0, 0.0, ofGetWindowWidth(),ofGetWindowHeight());                                   //draw deck 1 onto bg
ofSetColor(255 * alphaBlend2,255 * alphaBlend2,255 * alphaBlend2,255 * alphaBlend2);            //set alpha of deck 2
deck2.draw(0.0, 0.0, ofGetWindowWidth(),ofGetWindowHeight());                                   //draw deck 2 onto bg


//draw preview windows in top corners
ofSetHexColor(0xFFFFFF);
deck1.draw(0.0, 0.0, 300, 169);                                                                 //preview 1 - L
deck2.draw(ofGetWindowWidth()-300, 0.0, 300, 169);                                              //preview 2 - R


//labels
ofSetColor(255,255,255);
ofDrawBitmapString("Live view", ofGetWindowWidth()/2-25, ofGetWindowHeight()-10);               //live view label
ofDrawBitmapString("Deck 1", 7., 15.);                                                          //deck 1 - L
ofDrawBitmapString("Deck 2", ofGetWindowWidth()-53, 15.);                                       //deck 2 - R


//fps
ofDrawBitmapString("Framerate: " + ofToString(ofGetFrameRate(),0), ofGetWindowWidth()/2-45, 15.);   //draw fps
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    
if(currentState == ANIM_UP || currentState == ANIM_DOWN)            //block space bar clicks if transition is already in progress
{
    cout << "blocked" << endl;
}else
{
    //cross on space bar
    if(key == 32)
    {
        cout << "cross start" << endl;
    
        if (alphaBlend1 >= 0.99)                                    // check current alpha state, and set the currentState accordingly
        {
            cout << "going to deck B" << endl;
            currentState = ANIM_UP;
        }else if (alphaBlend1 <= 0.01)
        {
            cout << "going to deck A" << endl;
            currentState = ANIM_DOWN;
        }
    }
}

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
cout << dragInfo.position << endl;
cout << dragInfo.files[0] << endl;

if (dragInfo.position[1] <= 169)                                        // check to see if dropped file was in top half where previews are
{
    cout << "above range" << endl;
    
    if (dragInfo.position[0] <= 300)                                    // check to see if its first deck preview
    {
        deck1.stop();                                                   //stahp!
        deck1.closeMovie();                                             //drop rescources
        cout << "loading deck a" << endl;
        deck1.loadMovie(dragInfo.files[0]);                             //load 1st deck
        deck1.play();                                                   //play
        deck1.setVolume(0.0);                                           //kill volume
        
    }else if (dragInfo.position[0] >= (ofGetWindowWidth()-300))         // check to see if its second deck preview
    {
        deck2.stop();                                                   //stahp!
        deck2.closeMovie();                                             //drop resources
        cout << "loadin deck b" << endl;
        deck2.loadMovie(dragInfo.files[0]);                             //load 2nd deck
        deck2.play();                                                   //play
        deck2.setVolume(0.0);                                           //kill volume
        
    }
}

}

Some people seem to have good experiences with ofxHapPlayer, it will help in case your bottleneck is on CPU decoding. I haven’t used it personally.

In any case you could try loading video on separate threads to see if that helps. Have you had trouble using ofThread?