我通过 Node.js 通过 fluent-ffmpeg 使用 FFmpeg 将多个小音频文件合并为一个。我正在组合的每个音频文件都有一个延迟的开始时间(因此它既不会在同一开始合并,也不会合并)。我可以使用并将我的音频文件成功地做到这一点,然后将所有内容都记录下来。但是,虽然我在文档中找不到对最大输入数的引用,但我在尝试78 个文件时得到了参考。显然有 32 个输入文件的限制。aevalsrc
=0
concat
amix
[amix @ 0x3fcd920] Value 78.000000 for parameter 'inputs' out of range [1 - 32]
amix
鉴于此限制,我不确定进行此操作的最佳方式。我知道amerge
存在,但它在最短的文件长度后停止,所以我需要apad
一切,我只是测试了它并确定amerge
有 64 个输入文件的限制,这并不总是适合我的需要(我有一个任意数字输入)。
我可以 amix
存储 32 个文件,将其存储在某个地方,再存储amix
32 个,等等,以及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);