NodeJs: How to pipe two streams into one spawned process stdin (i.e. ffmpeg) resulting in a single output

偶尔善良 提交于 2019-12-12 19:16:45

问题


In order to convert PCM audio to MP3 I'm using the following:

function spawnFfmpeg() {
    var args = [
        '-f', 's16le',
        '-ar', '48000',
        '-ac', '1',
        '-i', 'pipe:0',
        '-acodec', 'libmp3lame',
        '-f', 'mp3',
        'pipe:1'
    ];

    var ffmpeg = spawn('ffmpeg', args);

    console.log('Spawning ffmpeg ' + args.join(' '));

    ffmpeg.on('exit', function (code) {
        console.log('FFMPEG child process exited with code ' + code);
    });

    ffmpeg.stderr.on('data', function (data) {
        console.log('Incoming data: ' + data);
    });

    return ffmpeg;
}

Then I pipe everything together:

writeStream = fs.createWriteStream( "live.mp3" );
var ffmpeg = spawnFfmpeg();
stream.pipe(ffmpeg.stdin);
ffmpeg.stdout.pipe(/* destination */); 

The thing is... Now I want to merge (overlay) two streams into one. I already found how to do it with ffmpeg: How to overlay two audio files using ffmpeg

But, the ffmpeg command expects two inputs and so far I'm only able to pipe one input stream into the pipe:0 argument. How do I pipe two streams in the spawned command? Would something like ffmpeg -i pipe:0 -i pipe:0... work? How would I pipe the two incoming streams with PCM data (since the command expects two inputs)?


回答1:


You could use named pipes for this, but that isn't going to work on all platforms.

I would instead do the mixing in Node.js. Since your audio is in normal PCM samples, that makes this easy. To mix, you simply add them together.

The first thing I would do is convert your PCM samples to a common format... 32-bit float. Next, you'll have to decide how you want to handle cases where both channels are running at the same time and both are carrying loud sounds such that the signal will "clip" by exceeding 1.0 or -1.0. One option is to simply cut each channel's sample value in half before adding them together.

Another option, depending on your desired output, is to let it exceed the normal range and pass it to FFmpeg. FFmpeg can take in 32-bit float samples. There, you can apply proper compression/limiting to bring the signal back under clipping before encoding to MP3.



来源:https://stackoverflow.com/questions/47460913/nodejs-how-to-pipe-two-streams-into-one-spawned-process-stdin-i-e-ffmpeg-res

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!