ofVideoPlayer returning wrong pixels

So, I’m trying to extract 3 frames from an .mp4 video. But neither frame shows the image that’s supposed to show.
I set the position of the video at 50% and extract that frame into an ofImage object, but the image that I get is from the first second of the video. I then set the position at 30 seconds into the video, and that frame will now show what was supposed to appear at the first frame, so the image at 50% of the video.
Here is my code, i’m using OF0.9.2 on Windows 10 with QtCreator.

video.setPosition(0.5);//half of the video
ofImage dummy;
dummy.setFromPixels(video.getPixels());
dummy.save("dummy.jpg"); //I get the image at the start of the video

video.setPosition(30 / video.getDuration());//30 seconds into the video
ofImage img1;
img1.setFromPixels(video.getPixels());
img1.save("img1.jpg");//I get the image that I expected for dummy

video.setPosition(60 /video.getDuration());//60 seconds into the video
ofImage img2(video.getPixels());
img2.save("img2.jpg");//I get the image that I expected for img1

Hi, are you running all those lines one after the other or are they launched on keyPress or something? It’s always helpful to have a complete but minimal example to look at, sometimes a call is made earlier that makes a big difference.

Anyways, does it help if you call video.update() after video.setPosition() ?

/A

I’m running the lines one after the other in the setup() function. This is the full code:

void ofApp::setup(){
    video.load("WeFeel_1.mp4");
    //=======================
    video.play();
    video.setPaused(true);
    //=======================

    video.setPosition(0.5);//half of the video
    ofImage dummy;
    dummy.setFromPixels(video.getPixels());
    dummy.save("dummy.jpg");

    video.setPosition(30 / video.getDuration());//30 seconds into the video
    ofImage img1;
    img1.setFromPixels(video.getPixels());
    img1.save("img1.jpg");

    video.setPosition(60 /video.getDuration());//60 seconds into the video
    ofImage img2(video.getPixels());
    img2.save("img2.jpg");

}

And calling video.update() after video.setPosition() doesn’t help, but I’m already calling video.update() in the udate() function.

Hi, yeah very strange, had a quick look and I can’t get consistent results either.

I could get it to save by waiting a few framers and saving from update(), trying to use video.isLoaded() or video.isFrameNew() to wait for the right moment did not help.

I’ve had movies lock up my App when they load, depending on what codec they use, it could be worth trying some other movies just in case.

/A

Thanks for the help! I’ll see what I can do with other codecs.

Tried converting my video with ffmpeg with different codecs, but the problem still persists.

Hmm, I know James had functionality in ofxTimeline that generated thumbnails of video tracks you were using, perhaps he’s got something in there that’ll help:

seeking to the correct position in a video is a science!

i don’t know much about the built in video player, but skimming the code i think the problem is that the video player runs in the background. when it finds a new frame it sets a variable “new pixels available” internally. when you then call update it’ll actually go and update those pixels.

you are not giving it any time, so the background thread hasn’t found any new pixels, so the update method thinks it has no work do.

if i’m right this could/should/would work:

video.setPosition(30 / video.getDuration());//30 seconds into the video
ofSleepMillis(100); // give it some time to seek+grab fresh frames
ofImage img1;
video.update();
img1.setFromPixels(video.getPixels());
img1.save("img1.jpg");//I get the image that I expected for dummy

Yep! It works! Thanks for the help! :smiley: