I have 3 audio files from a podcast. 1 file from Steve, one from john, and the other is from me.

I have a composition with the three audio files and also 3 png images of our faces, one for each of our faces. Each image has an opacity keyframe set to 50% by default. Now i want to connect each audio track to the right image and animate as follows:

✖ When audio intensity of a track is more than x decibels then gradually animate the image that's linked to that track from 50% opacity to 100% opacity. To give the visual effect of who is currently talking.

✖ When the sound intensity drops below the x decibels i have set before, then gradually animate the opacity back to 50%

How can i achieve that?

  • Have you seen this article on Reddit? – bret7600 Feb 25 '17 at 22:18
  • @bret7600 Thank you, but that didn't quite give me the full answer :) – Rafat Refai Feb 27 '17 at 11:37

The easiest way to do this is to use an expression. First you convert audio to keyframes. Then set an expression on your opacity channel. If you drag the pick-whip for the expression to the audio keyframe property you'll get an opacity that bounces all over the place like crazy, so we're going to have to do a bit more to it.

First, in the opacity channel for your layer, set up a variable like so:

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

(the expression on the right of the = is just what you get if you drag the pickwhip to the 'Both Channels' property).

We want to sample that property over time, to allow for slow fadeouts.

First, to make it easier to tweak we can set some properties that we can edit until we get the best results.

var numSamples = 200;
var sampleSpacing = thisComp.frameDuration;
var threshold = 5.0 //<--you set this
  • numSamples is the number of times we sample the amplitude to get a smooth average. The higher it is, the smoother the result, but also the slower the script is. If you set it really high you may want to convert the expression to keyframes once you've got it working right. The values I put in here are just pulled out of my hat, you'll have to tweak them until they work for you. This is the main setting that you can tweak. Have a go at setting it really high, like 2000 or low like 10, and see how it works.

  • sampleSpacing is the time between samples. Setting it to thisComp.frameDuration means one sample per frame. You could do a smaller sample, but given that the audio amplitude property only has one keyframe per frame it might not really help.

  • Threshold is the audio threshold above which no fading happens. Again you will have to tweak this depending on the audio level of your material.

Ok, here comes the hoo-hah.

var sum = 0;
for (var i = 0; i < numSamples; i++){
  sum += audioAmp.valueAtTime(time - i * sampleSpacing);
avAudio = sum / numSamples; //the average audio for all the samples
//now decide if the audio is low enough to start fading
if (avAudio < threshold) { 
  //normalises it to 0-100% where 100% = the threshold
  100 * avAudio / threshold; 
} else { //audio is above threshold

Basically it just averages the audio out for the last numSamples samples. When you have a sound followed by silence the average will go from the volume of the sound to zero in numSamples * sampleSpacing seconds, or in this case 200 frames.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.