I am trying to get a downsampled audio so that I can use it for an hotword detection API. In the solution I am currently using, the audio is correctly converted and the API is able to recognize the content of the audio file. However, I am constantly forced to write temporary output files. I have tried several times to use "pipe:1" in ffmpeg to output the converted audio as a stream to stdout, but it has always given me errors.
function downsampleAudio(pcmBuffer) {
return new Promise((resolve, reject) => {
const inputStream = new PassThrough();
inputStream.end(pcmBuffer);
let filePath = path.join(__dirname, "output.wav")
const ffmpeg = spawn("ffmpeg", [
"-f", "s16le",
"-ar", "48000",
"-ac", "1",
"-i", "pipe:0",
"-ar", "16000",
"-ac", "1",
"-c:a", "pcm_s16le",
filePath
]);
ffmpeg.stdin.on('error', (error) => {
reject(new Error('Errore nello stream stdin di ffmpeg: ' + error.message));
});
ffmpeg.on('close', (code) => {
if (code !== 0) {
reject(new Error(`Il processo ffmpeg è terminato con codice ${code}`));
} else {
console.log('Conversione completata con successo');
const waveBuffer = fs.readFileSync(filePath);
fs.unlinkSync(filePath);
resolve(waveBuffer)
}
});
inputStream.pipe(ffmpeg.stdin);
});
}
Can anyone help me figure out how to correctly use ffmpeg to output the audio as a stream to stdout without errors? Thanks in advance!
Since I was using "FilePath" as the output, ffmpeg automatically set the output format to WAV. When I tried to set stdout as the output, ffmpeg could no longer recognize the output format because I forgot to specify it (I'm stupid, it was 5 AM where I am). Anyway, specifying WAV as the format worked.
function downsampleAudio(pcmBuffer) {
return new Promise((resolve, reject) => {
const inputStream = new PassThrough();
let chunks = [];
inputStream.end(pcmBuffer);
const ffmpeg = spawn("ffmpeg", [
"-f", "s16le",
"-ar", "48000",
"-ac", "1",
"-i", "pipe:0",
"-f", "wav",
"-ar", "16000",
"-ac", "1",
"-c:a", "pcm_s16le",
"pipe:1"
]);
ffmpeg.stdin.on('error', (error) => {
reject(new Error('Errore nello stream stdin di ffmpeg: ' + error.message));
});
ffmpeg.on('close', (code) => {
if (code !== 0) {
reject(new Error(`Il processo ffmpeg è terminato con codice ${code}`));
} else {
resolve(Buffer.concat(chunks));
}
});
inputStream.pipe(ffmpeg.stdin);
ffmpeg.stdout.on('data', (chunk) => {
chunks.push(chunk);
});
});
}