We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpVideo Capture,  Movie Playback,  Vision Libraries › Access to individual frames in a Quicktime movie
Page Index Toggle Pages: 1
Access to individual frames in a Quicktime movie? (Read 2581 times)
Access to individual frames in a Quicktime movie?
Dec 5th, 2007, 5:04pm
 
I'd really like to be able to jump to and read specific frames in a Quicktime movie. I realize I can sort of do this with duration() and jump() if I know the frame rate of the Quicktime. But what if I don't?

I'd love to be able to just query the number of frames in a Quicktime and then address them by number.

Specifically, I'd like to be able to read a frame,  do some non-realtime calculating with it, and then read the next frame and repeat.

Can anybody help?
Re: Access to individual frames in a Quicktime mov
Reply #1 - Dec 6th, 2007, 12:22am
 
I did something similar. But I remember that I didn't find a way to get the movies *real* framerate. Actually, Quicktime for Java does not seem to be able to read out the framerate. I'd be happy if someone proofed me wrong here.

So, in my app the movie framerate was adjustable in a textbox. Then, the trick is to use a speed of 0, then jump to a location, wait for the movieEvent() to be called, calculate, jump to the next location, wait, calculate, etc.
The jump-step is measured in seconds and is calculated by
movie.duration() / framerate * movie.duration()
You can't access frames by their number, but by their time. If you think of compressed movies - where not every *frame* is actually available as pixels but is put together during runtime - this makes sense.
Re: Access to individual frames in a Quicktime mov
Reply #2 - Dec 6th, 2007, 1:41am
 
I've been using this code to access each frame of a movie. You have to enter the fps manually. I haven't put enough time into figuring out how to read it from the .mov.

On a related note the time it takes to access the pixels of a frame of video increases the further the frame is from a keyframe.  At least with this access method. When you give it a video with a keyframe at each frame it's fast. If anyone has a better way please share.

Hope this helps

Quote:
import processing.video.*;

Movie myMovie;

float increase = 0;

int movieFPS = 30;

float movieFrameTime = 1.0/movieFPS;

float movieTime;


void setup() {

 size(640, 480);

 myMovie = new Movie(this, "CHANGE TO THE MOVIE NAME.MOV");

 myMovie.loop();

 myMovie.speed(0);
}


void draw() {

 movieTime = (increase * movieFrameTime) % myMovie.duration();

 myMovie.jump(movieTime);

 myMovie.read();

 image(myMovie, 0, 0);

 increase++;

}
Re: Access to individual frames in a Quicktime mov
Reply #3 - Dec 6th, 2007, 2:13am
 
cool, just tried your keyframe trick, it speeds it up a bit.

i think your code reads from the movie object too often. isn't it possible for the draw-loop to be way faster than frame-loading? This might be relevant if one tries to process all the frames, but not process the same frame several times.

googling didn't help a lot for getting the framerate in qt java:
http://lists.apple.com/archives/QuickTime-java/2006/Jun/msg00024.html

as a workaround, you could try to play through the movie first at normal speed and count the calls to movieEvent(). fps = nrFrames/movie.duration()
Re: Access to individual frames in a Quicktime mov
Reply #4 - Dec 6th, 2007, 3:22am
 
This is a pointer, not a concrete solution, but it looks promising:

http://www.onjava.com/pub/a/onjava/2003/02/19/qt_file_format.html

Lots of info on how to crack open the QT file manually (in addition to loading it via Processing's methods) and peek at the QT metadata. I am assuming one of the 'atoms' will tell you what the frame rate is. (But, I am curious about the solution as well, so if you dig deeper into this, definitely post if back here as well!)
Re: Access to individual frames in a Quicktime mov
Reply #5 - Dec 6th, 2007, 4:58am
 
I was doing a lot of pixel editing from the movie so doing the myMovie.read() every time through draw guaranteed that I would get the new pixels for the frame. I found that if you move the myMovie.read() call out to a movieEvent function there is a chance that you will get the same pixels twice.

It's a little brute force and not the best for real time manipulation but when you need every pixel you've got to beat that sucker into submission. Smiley

Re: Access to individual frames in a Quicktime mov
Reply #6 - Dec 10th, 2007, 5:12pm
 
Thanks everyone for your help.

I ended up accessing each frame using polymonkey's technique and it seems to be working fine. I guess I have a bit of a bias thinking about time in frames because I work as an animator/compositor.

It'd still be great to be able to call something like myMovie.frame(n) to access each individual frame in a Quicktime.

Thanks again, and happy sketching!

-t
Re: Access to individual frames in a Quicktime mov
Reply #7 - May 8th, 2008, 7:47pm
 
Hey,
This post really helped me out.  I'm trying to do a morphing video trick in shake similar to Gondry's Rolling Stones video or that Underworld video where the guy jumps through a window.  But I needed to take a still frame from my video every ten frames and hold it for ten frames.  Then do the same thing to the same video with an offset of 5 frames.  I can then take the two videos and fade morph back and forth every five frames.  I took your code and updated it do this and I added a MovieMaker to render them down again.  Thanks again.  here's the code




import processing.video.*;
Movie myMovie;
MovieMaker mm;  // Declare MovieMaker object

int i;
int increase = 0; //<------------start frame
int movieFPS = 30;
float movieFrameTime = 1.0/movieFPS;
float movieTime;

void setup() {
 size(720, 480);
 myMovie = new Movie(this, "Me02.mov");
  myMovie.speed(0);
 myMovie.loop();
 frameRate(30);
 // Create MovieMaker object with size, filename,
 // compression codec and quality, framerate
 mm = new MovieMaker(this, width, height, "Everyten.mov",
                      30, MovieMaker.RAW, MovieMaker.LOSSLESS);
}

void draw() {
 movieTime = (increase * movieFrameTime) % myMovie.duration();


 myMovie.jump(movieTime);
 myMovie.read();
 image(myMovie, 0, 0);  
 increase+=10;            //<------------how many frames to skip
 for(i=0 ; i<10 ; i++){  //<-----how many times to print a frame
   mm.addFrame(); //addframe ten times hopefully
 }
}
void keyPressed() {
 if (key == ' ') {
   mm.finish();  // Finish the movie if space bar is pressed!
 }
}

// Called every time a new frame is available to read
//void movieEvent(Movie m) {
//  m.read();


Re: Access to individual frames in a Quicktime mov
Reply #8 - May 20th, 2008, 9:47pm
 
This may be a dumb question, as I am coming into this discussion late, but do any of the other video libraries (like JMyron, GSVideo, or LibCV) support frames?
Page Index Toggle Pages: 1