Simple ofVideoPlayer problem(?)

I’m still a very new OF user.

I have a piece of code which uses ofVideoPlayer to play back a movie and set the position to the beginning of the movie every half second. In the draw function I count frames and every time the framenumber reaches 14 I set the position of the movie to 0 as well as the counter counting frames.
For some reason all that happens after compiling is the video being played an looped.

I used the following piece of code, it would be nice to have some feedback on it:

  
#include "testApp.h"  
  
//--------------------------------------------------------------  
void testApp::setup(){  
	waitcount = 0;  
	  
	ofBackground(255,255,255);  
  
	frameByframe = false;  
  
	ofSetFrameRate(30);  
	  
	fingerMovie.loadMovie("movies/fingers.mov");  
	fingerMovie.play();  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
	fingerMovie.idleMovie();  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	  
	waitcount += waitcount;  
	  
	  
	if(waitcount == 14) {  
		  
		//fingerMovie.setPosition(ofRandom(fingerMovie.getDuration()));  
		fingerMovie.setPosition(0);  
		waitcount = 0;  
	}  
  
    fingerMovie.draw(20,20,640,480);  
}  

instead of fingerMovie.play() try something with the setFrame method like:

  
  
    #include "testApp.h"    
        
    //--------------------------------------------------------------    
    void testApp::setup(){    
        waitcount = 0;    
        ofBackground(255,255,255);    
        frameByframe = false;    
        ofSetFrameRate(30);    
        fingerMovie.loadMovie("movies/fingers.mov");    
    }    
        
    //--------------------------------------------------------------    
    void testApp::update(){    
          fingerMovie.setFrame(waitcount);  
    }    
        
    //--------------------------------------------------------------    
    void testApp::draw(){    
            
        waitcount += waitcount;    
            
            
        if(waitcount == 14) {    
                
            //fingerMovie.setPosition(ofRandom(fingerMovie.getDuration()));    
            fingerMovie.setPosition(0);    
            waitcount = 0;    
        }    
        
        fingerMovie.draw(20,20,640,480);    
    }    
  
  

Thanks for your help!

I tried your sugestion but the result is a non-moving image (I’ve attached a screenshot).

![](http://forum.openframeworks.cc/uploads/default/1861/Screen shot 2011-09-29 at 12.34.18 .png)

woops sorry that was slightly retarted I didn’t check the code.

this should work. You may need to try with a different video apart from fingers.mov to see it working.

  
#include "testApp.h"      
  
//--------------------------------------------------------------      
void testApp::setup(){      
	waitcount = 0;      
	ofBackground(255,255,255);      
	ofSetFrameRate(30);      
	fingerMovie.loadMovie("movies/fingers.mov");      
}      
  
//--------------------------------------------------------------      
void testApp::update(){      
	fingerMovie.setFrame(waitcount);    
	fingerMovie.idleMovie();  
}      
  
//--------------------------------------------------------------      
void testApp::draw(){      
	  
	waitcount++;      
	  
	if(waitcount == 14) {   		  
		fingerMovie.setPosition(0);      
		waitcount = 0;      
	}      
	fingerMovie.draw(20,20,640,480);      
}      
  

Again thanks!

It works fine now. I might need some clarity about how the thing works. I don’t really understand the relationship between the update and the draw function. Why for instance did you put fingerMovie.setFrame(waitcount); in the update function and not in the draw function?

Iv’e tried to make the position to go to random by using the code posted below. For some reason the duration intervals for choosing a new position seem to be random and sometimes the video hangs for a moment (this is shown more clearly when using another movie).

  
#include "testApp.h"  
  
//--------------------------------------------------------------  
void testApp::setup(){  
	frame = 0;  
	position = 0;  
	ofBackground(255,255,255);  
	ofSetFrameRate(30);  
	fingerMovie.loadMovie("movies/fingers.mov");  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
	fingerMovie.setFrame(frame);  
	fingerMovie.idleMovie();  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	  
	if(frame == (position + 14)) {  
		//fingerMovie.setPosition(ofRandom(0,fingerMovie.getDuration()));  
		frame = position = ofRandom((fingerMovie.getDuration()*30)-15);  
	}  
	  
	frame ++;  
	  
    fingerMovie.draw(20,20,640,480);  
}  

you need to change your if statement in the draw to

  
	if(frame == (position + 14)) {     
		position = ofRandom(0,fingerMovie.getTotalNumFrames());  
		frame = position;  
	}    
  

Usually in oF you dont out any code in your draw() unless it is *actually* drawing something.

update() gets called before every call to draw() so its a perfect place to put any variables that are being updated like changing frame numbers etc… Im sure someone else will be able to give you a better answer than that but thats the general gist.

The video hangs because you’re calling setFrame every frame, which is computationally expensive. If you want the video to actually play, only call setFrame() when you’re actually setting the frame. Otherwise pause the movie and advance through each frame. Also, fwiw your OF application runs at 60 frames a second by default, so 14 frames is 1/4 second, which is hard to visually process.

  
void testApp::update(){  
    fingerMovie.idleMovie();  
	  
	if(frame == (position + 60)) {  
		//fingerMovie.setPosition(ofRandom(0,fingerMovie.getDuration()));  
		frame = position = ofRandom((fingerMovie.getDuration()*30)-15);  
		fingerMovie.setFrame(frame); // call if you're playing the movie  
	}  
	//fingerMovie.setFrame(frame); // only if you've called fingerMovie.setPaused(true); in setup()  
	frame ++;  
	  
}  

1 Like

Does this do what you want:

  
//--------------------------------------------------------------  
void testApp::setup(){  
	ofBackground(255,255,255);  
	ofSetVerticalSync(true);	// stops frame "tearing"  
	//ofSetFrameRate(30);			// this is not really necessary it controls the oF framerate, not the movie framerate  
	fingerMovie.loadMovie("movies/fingers.mov");  
	lastTime = ofGetElapsedTimeMillis(); // set an initial var to the internal clock (you need to put an int lastTime in testApp.h  
	//fingerMovie.play(); // uncomment this if you want it to "play" and jump around or leave it out if you just want stills jumping around  
}  
  
//--------------------------------------------------------------  
void testApp::update() {  
	//if (ofGetFrameNum()%(15) == 0) { // this a frame counting method but is less reliable than using milliseconds and relies on the oF framerate being set to 30:  
	if (ofGetElapsedTimeMillis() - lastTime > 500) { // check if the clock is more than 500 millisecs greater than last time  
		fingerMovie.setFrame(ofRandom(fingerMovie.getTotalNumFrames())); // jump to a random from in the movie  
		lastTime = ofGetElapsedTimeMillis(); // reset the lastTime so we can check again  
	}  
    fingerMovie.update();  
}  
  
//--------------------------------------------------------------  
void testApp::draw() {  
	fingerMovie.draw(20,20);  
}  

A couple of things:

* idleMovie is deprecated, update is the preferred call
* It actually doesn’t matter (in terms of things working on a basic level) whether you setFrame in draw or update…it’s just that draw is reserved for “drawing” code and update is where calculations should happen
* in this case using getTotalNumFrames() is easier than doing all the multiplying with getDuration() -> for instance it eliminates errors such as getting the wrong timebase (is the movie 25 fps or 30 fps?)

1 Like

Thanks for all the wonderful reply’s!!

Could anybody tell me what is meant with “tearing”? in the line form gameovers example code:

  
ofSetVerticalSync(true);	// stops frame "tearing"  

I’ve copied gameover’s example and it’s working fine. Thanks gameover!

I’ve added some code to get a little dot every time a new position is chosen so I can see if that function is working well. I was wondering if I could get any feedback on the way I coded it in relation to the update and draw function separation? Did I put the right pieces of code in the right functions?

I just notice I forgot the post the code I was talking about in my previous post. It has changed a little in the meanwhile but I’m still wondering if I’ve put the right code in the right place considering the update and draw function distinction. Furthermore it seems there is problem with large movies(a couple of minutes), could that be possible?

  
#include "math.h"  
#include "testApp.h"  
//--------------------------------------------------------------  
void testApp::setup(){  
	circlec = 0;  
	movdraw = pow(ofRandom(0,1),2) > 0.5;  
	choicedur = (pow(ofRandom(0,1),2) * 990) +10;  
	lastTime = ofGetElapsedTimeMillis();  
	  
	movie1_alpha = 255;  
	  
	ofBackground(0,0,0);  
	ofSetVerticalSync(true);  
	  
	movie1.loadMovie("movies/tutorialzero.mov");  
	movie1.setVolume(0);  
	movie1.setSpeed(0.25);  
	movie1.play();  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
	if((ofGetElapsedTimeMillis() - lastTime) > choicedur) {  
		if (movdraw) {  
			movie1.setFrame(ofRandom(movie1.getTotalNumFrames()-  
									 (movie1.getTotalNumFrames()/  
									  movie1.getDuration())));  
			choicedur = (pow(ofRandom(0,1),2) * 1000) + 900;  
		} else {  
			choicedur = (pow(ofRandom(0,1),2) * 2000) + 500;  
		}  
		lastTime = ofGetElapsedTimeMillis();  
		movdraw = pow(ofRandom(0,1),2) > 0.5;  
		circlec = 0;  
	}  
	circlec ++;  
	movie1.update();  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	  
	if(circlec < 10) {  
		ofSetColor(255,255,255);  
		ofCircle(2,2,2);  
	}  
	if (movdraw) {  
		ofEnableAlphaBlending();  
		ofSetColor(255, 255, 255, movie1_alpha);  
		movie1.draw(0,0,800,600);  
		ofDisableAlphaBlending();  
	}  
}  

How large are the files that you’re working with? If they’re more than (random number) 1/4 available RAM or so, I could see it being a problem depending on where you’re trying to seek to in the video. How big is the file you’re working with? What sorts of problems are you running into?

Also, to answer your earlier question tearing means when a video feed sent to a display isn’t in sync with the display’s refresh, (different refresh rates or just non-sync). It makes things look unaligned within the same frame, a la http://upload.wikimedia.org/wikipedia/commons/thumb/0/03/Tearing-%28simulated%29.jpg/797px-Tearing-%28simulated%29.jpg

There’s a nice essay at the top here: http://hardforum.com/showthread.php?t=928593

Hey there

When you say “problem” with movies longer than a few minutes, what do you mean…I’m having no problem with an 11 minute movie I’m testing on right now…but don’t have anything longer on my laptop right now…

The division between update and draw looks fine.

Is there a particular reason you’re using

  
pow(ofRandom(0,1),2)  

all the time? Are you after that exponential weighting in your random numbers? Or do you just want a simple “flip-a-coin” for choices? And a simple range of numbers from “some number” to “some other number”?

If it’s the latter then you could replace:

  
pow(ofRandom(0,1),2) > 0.5;  

with:

  
ofRandomuf() > 0.5; // for a simple "coin flip" choice or...  
ofRandomuf > 0.7071; // to get the same "possibility" of "true" as your code is giving at the moment  

and

  
(pow(ofRandom(0,1),2) * 990) +10  

could be just

  
ofRandom(10, 1000)  

etc

The only other thing I’d mention is it’s good practice to use slightly more descriptive variable names, like “timeTillNextMovJump”, “framesCircleDisplayed”, “doDrawMovie” - they make reading the code for others (and you after 6 months!) easier :slight_smile:

EDIT: it might be an idea to store:

  
movie1.getTotalNumFrames()-(movie1.getTotalNumFrames()/movie1.getDuration()))  

in a variable right after loading a movie -> I’m sure it’s not too expensive but at the moment only getTotalNumFrames() is retrieving a variable stored in ofVideoPlayer, getDuration() actually makes a quicktime call in order to give you the length in seconds…I doubt it slows things down much but maybe better to store a number like this in a var…or just subtract 30

Thanks for all help and tips!

I was using those pow functions for weighted distributions indeed. Didn’t think of

  
ofRandomuf > 0.7071;  

though, thanks!