Files
video2document/services/modules/extraction/ffmpegExtractor.js
T
Azeufack Noupeu Willy a0ed2ab7bd feat(extraction): add audio_ready event emission
- Add EventEmitter to emit audio_ready when extraction completes
- Pass sessionId and audioPath in event data
- Export audioEvents for Main process orchestrator

Refs: S3-06 AC1,AC3,AC7
2025-11-20 14:05:52 +01:00

101 lines
3.7 KiB
JavaScript

const EventEmitter = require('events');
const audioEvents = new EventEmitter();
// Ensure ffmpeg binary is available
if (!ffmpegPath) {
throw new Error('FFmpeg binary not found!');
}
ffmpeg.setFfmpegPath(ffmpegPath);
// Prepare output directory (always storage/audio under project root)
const outputDir = `${__dirname}/../../../storage/audio`;
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
module.exports = {
name:"extraction-video-to-audio", // Unique name for our function that will later be used to get the function from the map via "mapFunctions.get("example").function()"
type:"extractor", // value used to differentiate each module to order them in the UI
displayname:"Default extractor", // The displayname used within the UI
async function(parameter){
/*
parameter structure:
{
inputVideoPath: String, // Path to the file
outputType: String // Audio file output format
}
*/
let progressBar = new cliProgress.SingleBar({
format: 'Processing |{bar}| {percentage}% | {timemark}',
barCompleteChar: '\u2588',
barIncompleteChar: '\u2591',
hideCursor: true
});
try {
// if (meta.url === `file://${process.argv[1]}`) {
this.extractAudioFromVideo(parameter.inputVideoPath, progressBar, parameter.outputType)
.then(() => console.log('Audio extraction successful.'))
.catch((err) => console.error(err));
// }
} catch (error) {
console.log(parameter.outputType);
}
},
// Derive input and output paths
// const inputVideoPath = process.argv[2];
// console.log(process.argv);
/**
* Extracts audio from a video using ffmpeg.
* - Converts video to WAV (16 kHz, Mono, PCM optional if needed)
* - Shows CLI progress bar
* - Handles errors gracefully (without errors)
*/
extractAudioFromVideo: async function (videoFilePath, progressBar, outputType){
let inputVideoName = path.basename(videoFilePath, path.extname(videoFilePath));
let outputAudioPath = path.join(outputDir, `${inputVideoName}.${outputType}`);
return new Promise((resolve, reject) => {
try {
ffmpeg(videoFilePath)
.outputFormat(outputType)
// .audioCodec('pcm_s16le')
.audioChannels(1)
.audioFrequency(16000)
// .setFfmpegPath("./ffmpeg.exe")
.on('progress', (progress) => {
if (!progressBar.isActive) progressBar.start(100, 0, { timemark: '00:00:00' });
if (progress.percent) {
progressBar.update(progress.percent, { timemark: progress.timemark });
}
})
.on('end', () => {
progressBar.update(100, { timemark: 'done' });
progressBar.stop();
console.log(`Extraction completed: ${outputAudioPath}`);
audioEvents.emit('audio_ready', {
sessionId: inputVideoName,
audioPath: outputAudioPath
});
resolve();
})
.on('error', (err) => {
progressBar.stop();
console.error(`failed_audio_extraction on type ${outputType}: ${err.message}`);
reject(err);
})
.save(outputAudioPath);
} catch (error) {
console.log();
}
});
},
audioEvents: audioEvents
}