Reputation: 11
Firstly, I do not need to concat them. I need them to be written simultaneously in to the same file. Detailed: I'm trying to record voices, its working but when there's more than 1 is speaking the output is getting corrupted (because I don't know how to merge opus data, also i'm not able to use web-audio-api).
Here is my code:
AudioStream Class:
const stream = require('stream');
function AudioStream(options) {
stream.Readable.call(this, options);
}
AudioStream.prototype = Object.create(stream.Readable.prototype);
AudioStream.prototype.constructor = stream.Readable;
AudioStream.prototype._read = function() {};
AudioStream.prototype.write = function(chunk) {
this.push(chunk);
};
module.exports = AudioStream;
Here is the code that doesn't work:
const { opus } = require('prism-media');
//const { pipeline } = require('stream');
const AudioStream = require('./utils/stream/AudioStream');
const receiver = connection.receiver;
const audioStream = new AudioStream();
const oggStream = new opus.OggLogicalBitstream({
opusHead: new opus.OpusHead({
channelCount: 2,
sampleRate: 48000,
}),
pageSizeControl: {
maxPackets: 10,
},
});
audioStream.pipe(oggStream);
oggStream.on('data', (chunk) => {
console.log(chunk)
out.write(chunk);
});
receiver.speaking.on('start', userId => {
if(!users.includes(userId)) {
users.push(userId);
const opusStream = receiver.subscribe(userId, {
end: {
behavior: EndBehaviorType.Manual,
},
});
// oggStream.pipe(audioStream);
opusStream.on('data', (chunk) => {
//console.log(chunk);
audioStream.pushData(chunk)
});
}
});
Upvotes: 1
Views: 889
Reputation: 2189
It wouldn't be much practical but you can write the streams to files, and merge them with FFmpeg
command:
ffmpeg -i first.wav -i second.wav -filter_complex "[0][1]amerge=inputs=2,pan=stereo|FL<c0+c1|FR<c2+c3[a]" -map "[a]" output.wav
node.js usage:
import { exec } from 'child_process'; // Or const { exec } = require('child_process'); if you are using javascript
const mergeAudios= (firstAudio: string, secondAudio: string, output: string) => {
return new Promise((resolve, reject) => {
exec(
"ffmpeg -i " + firstAudio + "-i " + secondAudio + ' -filter_complex "[0][1]amerge=inputs=2,pan=stereo|FL<c0+c1|FR<c2+c3[a]" -map "[a]" ' + output,
(error, stdout, stderr) => {
if (error) {
reject(error)
return;
} else {
resolve(null);
}
});
})
}
Upvotes: 1