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
100;
}
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.