added lib for transcription and audio redaction

This commit is contained in:
surajshivakumar
2024-06-05 17:09:29 -04:00
parent 5149d4fffc
commit 5ed5558faf
2 changed files with 126 additions and 0 deletions

44
lib/audioRedaction.js Normal file
View File

@@ -0,0 +1,44 @@
const ffmpeg = require('fluent-ffmpeg');
const fs = require('fs').promises;
function redactSensitiveInfo(transcriptionData, audioPath, audioOutputPath, delta = 0.15) {
const command = ffmpeg(audioPath)
.outputFormat('wav'); // Ensure output format is WAV
// Iterate over transcription data to apply audio filters
for (let i = 0; i < transcriptionData.length; i++) {
const {word, start} = transcriptionData[i];
let end = transcriptionData[i].end; // Default end time
// Check if the word needs redaction
if (word.startsWith('[') && word.endsWith(']')) {
// Find the start of the next non-redacted word
for (let j = i + 1; j < transcriptionData.length; j++) {
if (!(transcriptionData[j].word.startsWith('[') && transcriptionData[j].word.endsWith(']'))) {
end = transcriptionData[j].start;
break;
}
}
// Apply the volume filter to silence from the start of the current word to the start of the next non-redacted word
command.audioFilters({
filter: 'volume',
options: `volume=0:enable='between(t,${start - delta},${end})'` // Applying silence
});
// Log the redacted segments
console.log(`Redacting from ${start}s to ${end}s: "${word}"`);
}
}
// Handlers for command execution
command.on('end', () => {
console.log(`Redacted audio saved at ${audioOutputPath}`);
}).on('error', (err, stdout, stderr) => {
console.error('Error processing audio file:', err.message);
console.error('ffmpeg stdout:', stdout);
console.error('ffmpeg stderr:', stderr);
}).saveToFile(audioOutputPath);
}
module.exports = {redactSensitiveInfo};

82
lib/transcription.js Normal file
View File

@@ -0,0 +1,82 @@
const {createClient} = require("@deepgram/sdk");
const fs = require("fs");
class audioProcess {
constructor(apiKey, audioFilePath) {
this.deepgram = createClient(apiKey);
this.audioDir = audioFilePath
}
async transcribeFile(filePath) {
const {result, error} = await this.deepgram.listen.prerecorded.transcribeFile(
fs.readFileSync(filePath),
{
model: "nova-2",
smart_format: true,
detect_entities: true
}
);
return result;
}
async redactFile(filePath) {
const {result, error} = await this.deepgram.listen.prerecorded.transcribeFile(
fs.readFileSync(filePath),
{
model: "nova-2",
smart_format: true,
redact: "pii"
}
);
return result;
}
async analyzeText(text) {
const {result, error} = await this.deepgram.read.analyzeText(
{
text,
},
{
language: "en",
sentiment: true,
intents: true,
summarize: true
}
);
return result;
}
async processAudio(filePath = this.audioDir) {
try {
const transcription = await this.transcribeFile(filePath);
const redaction = await this.redactFile(filePath);
const transcript = transcription.results.channels[0].alternatives[0].transcript;
const timestamps = transcription.results.channels[0].alternatives[0].words;
const redactionTimestamps = redaction.results.channels[0].alternatives[0].words;
const redacted = redaction.results.channels[0].alternatives[0].transcript;
const entities = transcription.results.channels[0].alternatives[0].entities;
const analysisResult = await this.analyzeText(transcript);
const sentimentSegment = analysisResult.results.sentiments.segments[0];
const sentiment = sentimentSegment.sentiment;
const sentimentScore = sentimentSegment.sentiment_score;
return {
transcript,
timestamps,
redactionTimestamps,
redacted,
sentiment,
sentimentScore,
entities
};
} catch (error) {
throw error;
}
}
}
module.exports = {audioProcess};