Software: Apache. PHP/8.1.30 uname -a: Linux server1.tuhinhossain.com 5.15.0-163-generic #173-Ubuntu SMP Tue Oct 14 17:51:00 UTC uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root) Safe-mode: OFF (not secure) /home/picotech/domains/note.picotech.app/public_html/src/services/ drwxr-xr-x | |
| Viewing file: Select action/file-type: const { AudioChunk, Recording, Transcript } = require('../models');
const { formatTranscript } = require('./transcriptionService');
/**
* Check if all chunks for a recording have completed transcription
* If yes, aggregate the transcription data and create a Transcript record
*/
async function checkAndAggregateTranscription(recordingId) {
try {
// Get all chunks for the recording
const chunks = await AudioChunk.findByRecording(recordingId);
if (chunks.length === 0) {
console.log(`No chunks found for recording ${recordingId}`);
return;
}
// Check if all chunks have completed transcription
const allCompleted = chunks.every(chunk => chunk.transcription_status === 'completed');
if (!allCompleted) {
console.log(`Not all chunks completed for recording ${recordingId}. Current statuses:`, chunks.map(c => ({ id: c.id, status: c.transcription_status })));
return;
}
// Get the recording to get meeting_id
const recording = await Recording.findByPk(recordingId);
if (!recording) {
console.error(`Recording ${recordingId} not found`);
return;
}
// Aggregate transcription data
const aggregatedData = await aggregateTranscriptionData(chunks);
// Create the transcript record
await createTranscriptRecord(recording, aggregatedData);
} catch (error) {
console.error(`Error in checkAndAggregateTranscription for recording ${recordingId}:`, error);
}
}
/**
* Aggregate transcription data from all chunks
*/
async function aggregateTranscriptionData(chunks) {
// Sort chunks by chunk_index to ensure order
chunks.sort((a, b) => a.chunk_index - b.chunk_index);
let allWords = [];
let totalConfidence = 0;
let confidenceCount = 0;
let speakerMap = {};
let speakerCount = 0;
let language = 'unknown';
for (const chunk of chunks) {
if (!chunk.transcription_data) continue;
const transcription = JSON.parse(chunk.transcription_data);
// Assuming transcription has 'words' array with speakerId, text, start, end, confidence
if (transcription.words && Array.isArray(transcription.words)) {
// Adjust timestamps to be relative to the entire recording
const adjustedWords = transcription.words.map(word => ({
...word,
start: word.start + chunk.start_time,
end: word.end + chunk.start_time,
// Keep speakerId as is, but map globally if needed
}));
allWords.push(...adjustedWords);
// Track speakers
transcription.words.forEach(word => {
if (word.speakerId && !speakerMap[word.speakerId]) {
speakerMap[word.speakerId] = ++speakerCount;
}
});
if(transcription.languageCode){
language = transcription.languageCode;
}
// Aggregate confidence if available
if (transcription.languageProbability) {
totalConfidence += transcription.languageProbability;
confidenceCount++;
}
}
}
// Create aggregated transcription object
const aggregated = {
words: allWords,
confidence: confidenceCount > 0 ? totalConfidence / confidenceCount : 0,
speakerCount: speakerCount,
language: language, // Could be detected from chunks
service_provider: 'openrouter', // Assuming all chunks use same provider
};
return aggregated;
}
/**
* Create the Transcript record
*/
async function createTranscriptRecord(recording, aggregatedData) {
// Format the transcription content
const formattedTranscription = formatTranscript(aggregatedData);
// Skip if no content
if (!formattedTranscription.text.trim()) {
console.log(`No transcription content for recording ${recording.id}, skipping transcript creation`);
return;
}
// Calculate additional fields
const wordCount = formattedTranscription.text.split(/\s+/).filter(word => word.length > 0).length;
// Create speaker data from aggregated words
const speakerData = [];
let currentSpeaker = null;
let currentSegment = null;
aggregatedData.words.forEach(word => {
if (word.speakerId !== currentSpeaker) {
if (currentSegment) {
speakerData.push(currentSegment);
}
currentSpeaker = word.speakerId;
currentSegment = {
speaker_id: word.speakerId,
start_time: word.start,
end_time: word.end,
text: word.text,
};
} else {
currentSegment.end_time = word.end;
currentSegment.text += ' ' + word.text;
}
});
if (currentSegment) {
speakerData.push(currentSegment);
}
// Create the transcript
const transcript = await Transcript.create({
recording_id: recording.id,
meeting_id: recording.meeting_id,
content: formattedTranscription.text,
speaker_count: aggregatedData.speakerCount,
speaker_data: speakerData,
confidence: aggregatedData.confidence,
language: aggregatedData.language,
word_count: wordCount,
service_provider: aggregatedData.service_provider,
status: 'completed',
});
return transcript;
}
module.exports = {
checkAndAggregateTranscription,
aggregateTranscriptionData,
createTranscriptRecord,
}; |
:: Command execute :: | |
--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0035 ]-- |