ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Trigger layer playback based on audio keyframes

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Kees Fluitman
Trigger layer playback based on audio keyframes
on Mar 21, 2019 at 7:29:27 am

Ive got a small animation where a gun is fired on a box. For each gunshot, I want an impact on the box or some random miss animation. But I dont want to keyframe it.

Id like to have for instance 10 layers, which are triggered by say, their index value.

I just cant figure out how to do it. I have a checkbox that is triggered by the audio keyframes to be on everytime a gunshot is heard. It also triggers the weapon recoil. But it would mean I should somehow save information, so after 2 gunshots, a slider is value 3, so next time a gun is fired, it would trigger the next indexed layer.

Ive searched around a little, but after a few hours, still without luck....Thanks for your help in advance.


Return to posts index

Dan Ebberts
Re: Trigger layer playback based on audio keyframes
on Mar 21, 2019 at 1:05:26 pm

You might find this helpful:

http://www.motionscript.com/design-guide/audio-count.html


Dan



Return to posts index

Kees Fluitman
Re: Trigger layer playback based on audio keyframes
on Mar 21, 2019 at 8:28:12 pm

exactly! I've seen similar expressions like this, but couldnt get it to work by changing it. It would keep switching between 0 and 1.


Return to posts index


Kees Fluitman
Re: Trigger layer playback based on audio keyframes
on Mar 22, 2019 at 3:25:51 pm

So I've worked around a little. I used your audio trigger to make a slider count the amount of gunshots.
Then I started to write an expression for the time remapping of Bullet 1, so that it will play when the slider is 1.

It triggers, but it doesnt play the animation properly. It starts at 1 for instance? Is there sth wrong with how I want to get the time at which the slider becomes 1?

slider = thisComp.layer("control").effect("Slider Control")("Slider");
check = effect("Checkbox Control")("Checkbox");
frame = Math.round(time / thisComp.frameDuration);


if(slider == 0)
{
0
}
else if(slider => 1)
{
t = time - frame * thisComp.frameDuration;
linear(time, t, 15, 0, 5)
}


Return to posts index

Dan Ebberts
Re: Trigger layer playback based on audio keyframes
on Mar 22, 2019 at 7:32:18 pm

I think I may have led you down the wrong path. I'm thinking now each layer may need its own expression which finds its own trigger beat, and publishes the time when that beat occurs. Then your animation expression(s) would use that time to determine if the animation has started, and if so, how far along it is. Here's an example that would be looking for the 5th beat:


target = 5; // find 5th beat

threshold = 10.0;

audioLev = thisComp.layer("Audio Amplitude").effect("Both Channels")("Slider");

above = false;
f = 0;
n = 0;
while (f < timeToFrames(thisComp.duration)){
t = framesToTime(f);
if (above){
if (audioLev.valueAtTime(t) < threshold){
above = false;
}

}else if (audioLev.valueAtTime(t) >= threshold){
above = true;
n++;
if (n == target){
break;
}
}
f++;
}

framesToTime(f)


The problem of course is that you would have a bunch of these expressions running on every frame, which is bound to slow things down. One thing you could do though is convert the expressions to keyframes once you're happy with the results.


Dan



Return to posts index

Kees Fluitman
Re: Trigger layer playback based on audio keyframes
on Mar 23, 2019 at 10:30:44 am

ah i see. Ye of course, It needs to check each frame every frame to get value f, the frame where the trigger happened.
Then I will need to write a code (to the time remap), that can tell at which frame it needs to be (f+t) i'm guessing? where t is timeinframes - f? and if, of course the target hasnt been reached, stay at 0.


Return to posts index


Dan Ebberts
Re: Trigger layer playback based on audio keyframes
on Mar 23, 2019 at 3:59:29 pm

If it's just time remap, you could put the expression in the time remap property and just change the last line, like this:


target = 5; // find 5th beat

threshold = 10.0;

audioLev = thisComp.layer("Audio Amplitude").effect("Both Channels")("Slider");

above = false;
f = 0;
n = 0;
while (f < timeToFrames(thisComp.duration)){
t = framesToTime(f);
if (above){
if (audioLev.valueAtTime(t) < threshold){
above = false;
}

}else if (audioLev.valueAtTime(t) >= threshold){
above = true;
n++;
if (n == target){
break;
}
}
f++;
}

Math.max(time-framesToTime(f),0)


Dan



Return to posts index

Kees Fluitman
Re: Trigger layer playback based on audio keyframes
on Mar 24, 2019 at 4:54:50 pm

Thank you very much. It seems so simple when you do it.

So why do you use the Math.max? It seems to work without?

I simply wanted to make it too complicated by getting a checkbox or slider extra, which was much harder to check when the frame was that it went on. Just double work. This works perfectly fine! Thank you.

Would it be smart to do more work in just Java or Python to get a better understanding of scripting? Maybe a course or sth similar?


Return to posts index

Dan Ebberts
Re: Trigger layer playback based on audio keyframes
on Mar 24, 2019 at 5:01:33 pm

>So why do you use the Math.max?

Just habit, to hold the result at zero before the trigger happens. I guess it wouldn't be necessary with time remapping.

>Would it be smart to do more work in just Java or Python to get a better understanding of scripting?

Maybe, but I think I'd just focus on JavaScript.


Dan



Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2019 CreativeCOW.net All Rights Reserved
[TOP]