1

我通过 Node.js 通过 fluent-ffmpeg 使用 FFmpeg 将多个小音频文件合并为一个。我正在组合的每个音频文件都有一个延迟的开始时间(因此它既不会在同一开始合并,也不会合并)。我可以使用并将我音频文件成功地做到这一点,然后将所有内容都记录下来。但是,虽然我在文档中找不到对最大输入数的引用,但我在尝试78 个文件时得到了参考。显然有 32 个输入文件的限制。aevalsrc=0concatamix[amix @ 0x3fcd920] Value 78.000000 for parameter 'inputs' out of range [1 - 32]amix

鉴于此限制,我不确定进行此操作的最佳方式。我知道amerge存在,但它在最短的文件长度后停止,所以我需要apad一切,我只是测试了它并确定amerge有 64 个输入文件的限制,这并不总是适合我的需要(我有一个任意数字输入)。

可以 amix存储 32 个文件,将其存储在某个地方,再存储amix32 个,等等,以及amix结果。我宁愿不处理将临时文件写入磁盘然后必须稍后清理的问题。我考虑将“临时”输出写入双工节点流并在我的最终混音中读取它们,但我担心这可能效率很低。

以下是我目前正在做的事情。如果这是一个XY 问题,并且这是一种愚蠢的方式来完成我想要的,请告诉我。

ffmpeg()
    //INPUTS
    .input('/drummachine/www/audio/bd/bd5025.wav')
    .input('/drummachine/www/audio/bd/bd5025.wav')
    .input('/drummachine/www/audio/bd/bd5025.wav')
    .input('/drummachine/www/audio/sd/sd5025.wav')
    .input('/drummachine/www/audio/sd/sd5025.wav')
    .input('/drummachine/www/audio/rs/rs.wav')
    .input('/drummachine/www/audio/rs/rs.wav')
    .input('/drummachine/www/audio/rs/rs.wav')
    .input('/drummachine/www/audio/cp/cp.wav')
    .input('/drummachine/www/audio/cp/cp.wav')
    .input('/drummachine/www/audio/cp/cp.wav')
    .input('/drummachine/www/audio/oh/oh25.wav')
    .input('/drummachine/www/audio/oh/oh25.wav')
    .input('/drummachine/www/audio/oh/oh25.wav')
    .input('/drummachine/www/audio/ch/ch.wav')
    .input('/drummachine/www/audio/ch/ch.wav')
    .input('/drummachine/www/audio/ch/ch.wav')
    // ...
    // you get the picture
    // ...
    .audioCodec('libmp3lame').format('mp3')
    .complexFilter([
        //GENERATE SILENCE TO PREPEND TO INPUTS
        'aevalsrc=0:d=6.857142857142857[s78]',
        'aevalsrc=0:d=0[s0]',
        'aevalsrc=0:d=0.857[s1]',
        'aevalsrc=0:d=1.714[s2]',
        'aevalsrc=0:d=2.571[s3]',
        'aevalsrc=0:d=3.429[s4]',
        'aevalsrc=0:d=4.286[s5]',
        'aevalsrc=0:d=5.143[s6]',
        'aevalsrc=0:d=6[s7]',
        'aevalsrc=0:d=0.429[s8]',
        'aevalsrc=0:d=1.286[s9]',
        'aevalsrc=0:d=2.143[s10]',
        'aevalsrc=0:d=3[s11]',
        'aevalsrc=0:d=3.857[s12]',
        'aevalsrc=0:d=4.714[s13]',
        'aevalsrc=0:d=5.571[s14]',
        'aevalsrc=0:d=6.429[s15]',
        'aevalsrc=0:d=0.536[s16]',
        // ...
        //CONCAT SILENCE AND AUDIO
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s0', '0:a'], outputs: 'ac0'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s1', '1:a'], outputs: 'ac1'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s2', '2:a'], outputs: 'ac2'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s3', '3:a'], outputs: 'ac3'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s4', '4:a'], outputs: 'ac4'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s5', '5:a'], outputs: 'ac5'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s6', '6:a'], outputs: 'ac6'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s7', '7:a'], outputs: 'ac7'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s8', '8:a'], outputs: 'ac8'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s9', '9:a'], outputs: 'ac9'},
        {filter: 'concat', options: {v: 0, a: 1}, inputs: ['s10', '10:a'], outputs: 'ac10'},
        // ...
        // again, this goes on for a while
        // ...
        //MIX IT ALL
        {filter: 'amix', options: {inputs: 78, duration: 'longest'},
            inputs: ['s78', 'ac0', 'ac1', 'ac2', 'ac3', 'ac4', 'ac5',
            'ac6', 'ac7', 'ac8', 'ac9', 'ac10', 'ac11', 'ac12', 'ac13',
            'ac14', 'ac15', 'ac16', 'ac17', 'ac18', 'ac19', 'ac20',    
            // ...
            'ac74', 'ac75', 'ac76'], outputs: 'out'}], 'out')
    //ERROR
    .on('error', function (err, stdout, stderr) {
        console.log('an error happened: ' + err.message);
        console.log('ffmpeg stdout: ' + stdout);
        console.log('ffmpeg stderr: ' + stderr);
    //SUCCESS
    }).on('end', function () {
        console.log('Processing finished !');
        res.end();
    }).pipe(res);
4

0 回答 0