ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Use a switch like expression

FAQ   •   VIEW ALL Use a switch like expression on Dec 4, 2012 at 1:49:19 pm

Hi everyone!
Here's my problem:

I have a stepped graph in comp("Lipsync_Code").layer("Frames").effect("Frames")("Slider").

I'm writing a piece of code that I want to do the following:

Find the amount of frames in each 'step' and use that as it's value.

Example time:
Say from frames 1 to 20 the value of my stepped graph is 5. at Frame 21 to 23 the value steps up to 7. If the time slider is located on frames 1 - 20. I want it to be able to figure out and tell me how many frames on this step (There's 20). If it's on frames 21-23 I want it to be able to tell me there's 3 frames.

I'm fairly new to coding but I do consider myself to be half smart and I've been playing around with code for the past month though and here is my idea.

I need two similar pieces of code. Based off the current time, I need to be able to check how many frames SINCE the LAST change in value and how many frames UNTIL the NEXT change in value. Then I need to add them together.

But this idea turned out to be easier said than done. Here is my code to figuring out how long until the next variable change.

MouthPosFind = comp("Lipsync_Code").layer("Frames").effect("Frames")("Slider") ;
// the location of the stepped graph ;
Switch = 1 ;
if(Switch==1)
{
AddFrame = 1 ;
}
Switch = 0;
else

if(
MouthPosFind.valueAtTime(time)
==
)

Of course what happens is; the switch variable gets reset to 1 when the switch variable is reset to 1 at the 3rd line of the code and my hard work adding +1 to the AddFrame is for naught because the switch turns itself back on and consequently AddFrame it resets it back to 1. GRR! FOILED BY MY OWN CREATION! (I'm trying to make this a little entertaining so it's not terrible for you reading this long post.)

Maybe if could make another switch to turn that first switch off and continue doing it in an endless loop til either me or After Effects goes insane but that sounds unpleasant.

Am I in the right ballpark here? I know what I logically how to set this up, I just lack the coding know how to pull it off.

Any advice would be hugely appreciated. I've been stuck on this for 2 days now.

Thanks heaps!

MouthPosFind = comp("Lipsync_Code").layer("Frames").effect("Frames")("Slider") ;
// the location of the stepped graph ;
Switch = 1 ;
if(Switch==1)
{
AddFrame = 1 ;
}
Switch = 0;
else

if(
MouthPosFind.valueAtTime(time)
==
) Re: Use a switch like expressionon Dec 4, 2012 at 2:39:33 pm

How are you controlling the slider? If you're using hold keyframes, it seems like it would be easier to look at the keyframes which bracket the current value of the slider and get the times of those keyframes.

Dan Re: Use a switch like expressionon Dec 4, 2012 at 10:24:17 pm

The slider is controlled by a time remap. It's for lip sync so the time remap has a key frame on every frame in the composition. Even if the value doesn't change the program I used automatically makes every single frame into a key frame. Because of this, if I just find the value of the bracket keys it will only go forward one frame and back one frame.

Perhaps it would work if there was some way to loop one part of the code; the final If Condition and it's result. So it would keep adding +1 to AddFrame until it the last If condition changes to the Else result.

I wonder if there is a code for that. I've been looking but ask I can find is an expression that loops key frames. Re: Use a switch like expressionon Dec 4, 2012 at 11:42:24 pm

Just to be clear, is it the layer "Frames" that's time remapped, or is it the layer "Lipsync_Code" (your comp as a layer in another comp)? And where will the expression be?

Dan Re: Use a switch like expressionon Dec 5, 2012 at 12:40:17 am

Hi dan
The Frames layer is in a different Comp and it's value is set to be the same value of a different layer called Mouth. Mouth is a comp with the time remap. The Frames Slider Effect converts Mouth's time code value to a frame number (just because I find it easier to work with while numbers than time codes.) Re: Use a switch like expressionon Dec 5, 2012 at 1:07:58 am

This should be close:

L = comp("Lipsync_Code").layer("Frames");
slider = L.effect("Frames")("Slider");
f = timeToFrames(time);
s = slider.value;

count = 1;
for (i = f-1; i >= timeToFrames(L.inPoint); i--){
if (slider.valueAtTime(framesToTime(i)) != s) break;
count++
}

for (i = f+1; i < timeToFrames(L.outPoint); i++){
if (slider.valueAtTime(framesToTime(i)) != s) break;
count++
}
count

Dan Re: Use a switch like expressionon Dec 6, 2012 at 1:04:11 pm

Hi Dan

Thanks so much for your help. While looking at your script I looked up some of the terms you used and I wasn't aware of how to use a for () condition for looping. I played around with it and I managed to re write my original script to get it working the way I wanted. Thanks so much for all your help, I never would have figured it out without your assistance.

i = 1 ;
j = 1 ;
CurrentTime = timeToFrames(time) ;
MouthPosFind = comp("Lipsync_Code").layer("Frames").effect("Frames")("Slider") ;
FramesSinceKey = 1 ;
FramesSinceStart = timeToFrames(time - comp("PUT_LIPSYNC_CODE_IN_HERE").layer("Lipsync_Code").inPoint) ;
FramesUntillKey = 1 ;
FramesUntillEnd = timeToFrames(comp("PUT_LIPSYNC_CODE_IN_HERE").layer("Lipsync_Code").outPoint)-(timeToFrames(time)) ;

// find frames since last keyframe ;

for (i = 1 ; MouthPosFind.valueAtTime(time)== MouthPosFind.valueAtTime(time-(framesToTime(i))) ; i++)
{
if(MouthPosFind.valueAtTime(time)== MouthPosFind.valueAtTime(time-(framesToTime(i))))
{
FramesSinceKey++ ;
} ;
if(FramesSinceKey>FramesSinceStart)
{
break
} ;
// code stops the value from going backwards forever in the first few frames ;
} ;
// find frames untill next keyframe ;

for (j = 1 ; MouthPosFind.valueAtTime(time)== MouthPosFind.valueAtTime(time+(framesToTime(j))) ; j++)
{if(MouthPosFind.valueAtTime(time)== MouthPosFind.valueAtTime(time+(framesToTime(j))))
{
FramesUntillKey++ ;
}else{break ;} ;

if(FramesUntillKey>=FramesUntillEnd)
{
break
} ;
// code stops the value from going backwards forever in the first few frames ;
} ;

value = FramesSinceKey -1 + FramesUntillKey ;