Skip to main content
Paul Cristo
Inspiring
October 5, 2023
Question

Expression to determine each value of next 100 frames

  • October 5, 2023
  • 3 replies
  • 2775 views

I'm trying to write an expression that gets the value of a property for each of the next 100 frames and determine if they're all below a certain value. If they are, change a boolean to true and vice versa. Is this possible in the After Effects paradigm? Thanks. 

This topic has been closed for replies.

3 replies

Dan Ebberts
Community Expert
Community Expert
October 5, 2023

Something like this, probably (this example is for the layer's rotation property):

prop = rotation;
threshold = 20;
val = true;
for (i = 0; i < 100; i++){
  if (prop.valueAtTime(time + framesToTime(i)) >= threshold){
    val = false;
    break;
  }
}
val

 

Paul Cristo
Inspiring
October 5, 2023

Thank you for the help, Dan. This worked! Would you mind helping me with the second aspect of this project, which is rotating a camera 90º if the boolean is true, and back to 0º if the boolean is false, but using ease() to make the rotation happen over time? Is this possible? Here's what I've tried and ease() isn't kicking in:

t = timeToFrames(time);
tFor = t + 48;
startRot = 0;
endRot = 90;

if (val){
	ease(time,t,tFor,startRot,endRot);
	} else if (! val) {
	ease(time,t,tFor,endRot,startRot);	
	}

 

Paul Cristo
Inspiring
October 6, 2023

Paul, that changes things. In that case the expression needs to figure how far into the future the threshold crossing occurs and use that to drive the ease expression. So that's probably going to look somethng like this:

prop = rotation;
threshold = 20;
startRot = 0;
endRot = 90;

if (prop.value >= threshold){
  endRot;
}else{
  for (i = 1; i <= 100; i++){
    if (prop.valueAtTime(time + framesToTime(i)) >= threshold){
      break;
    }
  }
  ease(i,1,100,endRot,startRot);
}

Thank you for your help, Dan. If you wouldn't mind one more imposition, I was wondering if you could look at the entire expression in context and tell me where my logic is wrong. 

 

I've analyzed an audio file of two people talking and am using the amplitude keyframes of one of the channels to determine when to pan a 3D camera to a picture of the two speakers. This expression lies in the Y Rotation property of the 3D camera. The rotation value changes as expected, but the ease() functions don't work. Here is the expression:

//variables for determining if Jon is talking
jon = thisComp.layer("Audio Amplitude").effect("Jon Channel")("Slider");
threshold = 3;
jonHush = false;
lookAhead = 65;
counter = 0

//variables for rotation
startRot = 0;
endRot = 90;
durRot = 96;

//determines if Jon is talking
for (i = 0; i < lookAhead; i++){
	if (jon.valueAtTime(time + framesToTime(i)) < threshold){
		counter++;
		if (counter >= lookAhead){
			jonHush = true;
			}
	} else {
		jonHush = false; 
		counter = 0;
		break;
		}
	} 

//rotates camera on Y axis according to if Jon is talking
if (! jonHush){
	ease(time,timeToFrames(time),timeToFrames(time)+durRot,endRot,startRot);
	} else if (jonHush){
		ease(time,timeToFrames(time),timeToFrames(time)+durRot,startRot,endRot);
		}
Community Expert
October 5, 2023

If you are trying to look forward from the current time to the next 100 frames, you are going to end up with a recursive expression that slows down the farther down the timeline you go. The slowdown can be exponential. You will have to take time and create a loop that looks forward 100 * thisComp.frameDuration and looks for your critical value. It can throw a switch or change a color if it finds it and returns a false value.

 

Add this expression to a text layer above a layer with an animated position property, and it will tell you whether the layer is above or below the center of the comp 100 frames ahead of the current time.

 

lookForward = 100 * thisComp.frameDuration;
v = thisComp.layer(index + 1).transform.position.valueAtTime(time + lookForward);
trgtVal = thisComp.height/2;
if (v[1] < trgtVal){
	p = ": Top"
}
else{
	p = ": Bottom"
}
"Position" + p

 

It won't compare all 100 frames, but it would look ahead to detect the change.

 

If I get some free time later on, I will take a look at adding a loop operator to check if any frame is above the target value.

Mylenium
Legend
October 5, 2023

Sure. A simple for() loop will do.

 

Mylenium