import logging import json from sqlalchemy.orm import Session from .ffmpeg_service import FFmpegService from .transcription_service import TranscriptionService from ..database import Meeting, TranscriptChunk from ..config import settings logger = logging.getLogger(__name__) def parse_time_to_seconds(time_str): try: parts = time_str.split(':') if len(parts) == 2: # MM:SS return int(parts[0]) * 60 + int(parts[1]) elif len(parts) == 3: # HH:MM:SS return int(parts[0]) * 3600 + int(parts[1]) * 60 + int(parts[2]) except: return 0 return 0 def process_meeting_task(meeting_id: int, db_session_factory): db = db_session_factory() meeting = db.query(Meeting).filter(Meeting.id == meeting_id).first() if not meeting: return try: ffmpeg = FFmpegService() transcriber = TranscriptionService() # Phase 1: Split meeting.status = "SPLITTING" db.commit() meeting.duration_seconds = ffmpeg.get_duration(meeting.file_path) chunks = ffmpeg.split_audio(meeting.file_path, meeting.id) # Phase 2: Transcribe meeting.status = "TRANSCRIBING" db.commit() all_text = [] for i, chunk_path in enumerate(chunks): offset = i * settings.CHUNK_DURATION_SEC logger.info(f"Processing chunk {i+1}/{len(chunks)} with offset {offset}s") result = transcriber.transcribe_chunk(chunk_path, offset) # Parse JSON and Adjust Timestamps json_data = [] try: raw_json = json.loads(result["raw_text"]) if isinstance(raw_json, list): for entry in raw_json: seconds = parse_time_to_seconds(entry.get("time", "00:00")) absolute_seconds = seconds + offset entry["absolute_seconds"] = absolute_seconds h = int(absolute_seconds // 3600) m = int((absolute_seconds % 3600) // 60) s = int(absolute_seconds % 60) entry["display_time"] = f"{h:02}:{m:02}:{s:02}" json_data.append(entry) except Exception as e: logger.error(f"JSON Parsing failed for chunk {i}: {e}") # Save chunk result db_chunk = TranscriptChunk( meeting_id=meeting.id, chunk_index=i, raw_text=result["raw_text"], json_content=json_data ) db.add(db_chunk) all_text.append(result["raw_text"]) db.commit() # Phase 3: Finalize meeting.status = "COMPLETED" # Combine summary (first attempt - can be refined later with separate LLM call) # meeting.summary = ... db.commit() logger.info(f"Meeting {meeting.id} processing completed.") except Exception as e: logger.error(f"Error processing meeting {meeting_id}: {e}", exc_info=True) meeting.status = "ERROR" db.commit() finally: db.close()