0

This is an audio question, not a video question, but hope it belongs here. I am constructing complexFilters to procedurally generate audio with ffmpeg via fluent-ffmpeg. The interesting part of my fluent-ffmpeg complex filters look like:

{
   "filter": "volume",
   "options": {
       "volume": "min(1, max(0, ((cos(PI * t * 1 / 13) * 1 + cos(PI * t * 1 / 7) * 0.5 + cos(PI * t * 1 / 3) * 0.25) +
-0.5 ) * 0.75 * -1 + 0.5))",
       "eval": "frame"
    },
    "inputs": "track_1_output",
    "outputs": "track_1_adjusted"
},

Note that I am using an expression to determine the volume dynamically. To simplify my tests, I'm constructing complexFilters on the command line to understand the mysteries of some of the lightly-documented ffmpeg filters. Here's a working CLI test of using the volume filter to fade the sources in and out according to a time-based expresssion:

# working fade in/out
ffmpeg -i knox.mp3 -i static.mp3 -filter_complex \
"[0:a] \
    volume = 'min(1, max(0, 0.5 + 0.5 * cos(PI * t / 5)))': eval=frame \
    [a0]; \
[1:a] \
    volume = 'min(1, max(0, 0.5 - 0.5 * cos(PI * t / 5)))': eval=frame \
    [a1]; \
[a0][a1]
    amix = inputs=2: duration=shortest" \
-c:a libmp3lame -q:a 2 output.mp3

Now I want to apply lowpass, highpass, aphaser, and/or aecho to the transitions using a time-based expression. For instance, looking at lowpasss, according to ffmpeg -filters it says that it has time-based support:

  T.. = Timeline support
 TSC lowpass           A->A       Apply a low-pass filter with 3dB point frequency.

How can I similarly apply a time-based expression to lowpass, highpass, aphaser, or aecho? I thought the mix option might be the key, but I couldn't construct a working example and couldn't find any examples.

# applying a lowpass filter
ffmpeg -i knox.mp3 -filter_complex \
"[0:a] \
    lowpass=f=3000:mix='0.5 + 0.5 * cos(PI * t / 5)';" \
-c:a libmp3lame -q:a 2 output.mp3

Or if you prefer the fluent-ffmpeg filter:

const ffmpeg = require('fluent-ffmpeg');

ffmpeg('knox.mp3')
    .complexFilter([
        {
            filter: 'lowpass',
            options: {
                f: 3000,
                mix: '0.5 + 0.5 * cos(PI * t / 5)'
            },
            inputs: '[0:a]',
        }
    ])
    .audioCodec('libmp3lame')
    .audioQuality(2)
    .save('output.mp3')
    .on('end', () => {
        console.log('Processing finished successfully');
    })
    .on('error', (err) => {
        console.error('Error: ' + err.message);
    });

With the resultant error:

[Parsed_lowpass_1 @ 0x7f9a72005c00] [Eval @ 0x7ff7bec423d8] Undefined constant or missing '(' in 't/5)'
[Parsed_lowpass_1 @ 0x7f9a72005c00] Unable to parse option value "0.5 + 0.5 * cos(PI * t / 5)"
Error applying option 'mix' to filter 'lowpass': Invalid argument

What complicated fffmpeg faerie magic is needed to make some of the filters other than volume controlled by a time-based expr?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.