import streamlit as st from audio_recorder_streamlit import audio_recorder import os import tempfile from typing import List from pydub import AudioSegment from groq import Groq from langchain.chains import LLMChain from langchain_groq import ChatGroq from langchain.prompts import PromptTemplate from datetime import datetime import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication from reportlab.lib import colors from reportlab.lib.pagesizes import letter from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle import re from dotenv import load_dotenv load_dotenv() SENDER_EMAIL = os.environ.get('SENDER_EMAIL') SENDER_PASSWORD = os.environ.get('SENDER_PASSWORD') class PDFGenerator: @staticmethod def create_pdf(content: str, filename: str) -> str: doc = SimpleDocTemplate(filename, pagesize=letter) styles = getSampleStyleSheet() custom_style = ParagraphStyle( 'CustomStyle', parent=styles['Normal'], spaceBefore=12, spaceAfter=12, fontSize=12, leading=14, ) story = [] # Ajouter le titre title_style = ParagraphStyle( 'CustomTitle', parent=styles['Heading1'], fontSize=16, spaceAfter=30, ) story.append(Paragraph("Résumé Audio", title_style)) # Ajouter la date date_str = datetime.now().strftime("%d/%m/%Y %H:%M") story.append(Paragraph(f"Date: {date_str}", custom_style)) story.append(Spacer(1, 20)) # Convertir le contenu en paragraphes for line in content.split('\n'): if line.strip(): if line.startswith('#'): # C'est un titre story.append(Paragraph(line.strip('# '), styles['Heading2'])) else: story.append(Paragraph(line, custom_style)) doc.build(story) return filename class EmailSender: def __init__(self, sender_email: str, sender_password: str): self.sender_email = sender_email self.sender_password = sender_password def send_email(self, recipient_email: str, subject: str, body: str, pdf_path: str) -> bool: try: msg = MIMEMultipart() msg['From'] = self.sender_email msg['To'] = recipient_email msg['Subject'] = subject msg.attach(MIMEText(body, 'plain')) with open(pdf_path, 'rb') as f: pdf_attachment = MIMEApplication(f.read(), _subtype='pdf') pdf_attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(pdf_path)) msg.attach(pdf_attachment) server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(self.sender_email, self.sender_password) server.send_message(msg) server.quit() return True except Exception as e: st.error(f"Erreur d'envoi d'email: {str(e)}") return False # ... [Garder la classe AudioProcessor inchangée] ... class AudioProcessor: def __init__(self, chunk_length_ms: int = 60000): self.chunk_length_ms = chunk_length_ms self.groq_client = Groq( #api_key="" ) self.llm = ChatGroq( model="mixtral-8x7b-32768", temperature=0.7, #api_key="" ) def chunk_audio(self, file_path: str) -> List[AudioSegment]: audio = AudioSegment.from_file(file_path) chunks = [ audio[i:i + self.chunk_length_ms] for i in range(0, len(audio), self.chunk_length_ms) ] return chunks def transcribe_chunk(self, audio_chunk: AudioSegment) -> str: with tempfile.NamedTemporaryFile(suffix='.mp3', delete=True) as temp_file: audio_chunk.export(temp_file.name, format="mp3") with open(temp_file.name, "rb") as audio_file: response = self.groq_client.audio.transcriptions.create( file=audio_file, model="whisper-large-v3-turbo", language="fr" ) return response.text def generate_summary(self, transcription: str) -> str: prompt_template = """ Vous êtes un assistant expert spécialisé dans le résumé et l'analyse d'enregistrements audio en langue française. Voici la transcription à analyser: {transcript} Veuillez fournir: 1. Un résumé concis (3-4 phrases) 2. Les points clés (maximum 5 points) 3. Les actions recommandées (si pertinent) 4. Une conclusion brève Format souhaité: # Résumé [votre résumé] # Points Clés • [point 1] • [point 2] ... # Actions Recommandées 1. [action 1] 2. [action 2] ... # Conclusion [votre conclusion] """ chain = LLMChain( llm=self.llm, prompt=PromptTemplate( template=prompt_template, input_variables=["transcript"] ) ) return chain.run(transcript=transcription) def save_uploaded_file(uploaded_file): with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(uploaded_file.name)[1]) as tmp_file: tmp_file.write(uploaded_file.getvalue()) return tmp_file.name def is_valid_email(email: str) -> bool: pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$' return re.match(pattern, email) is not None def main(): st.set_page_config(page_title="Audio Summarizer", page_icon="🎙️") # Configuration email dans les secrets de Streamlit #SENDER_EMAIL = "" #SENDER_PASSWORD = "" email_sender = EmailSender(SENDER_EMAIL, SENDER_PASSWORD) st.title("🎙️ Audio Summarizer") # Initialisation des sessions states if 'audio_processor' not in st.session_state: st.session_state.audio_processor = AudioProcessor() # Interface utilisateur st.markdown("### 📤 Chargez votre fichier audio") uploaded_file = st.file_uploader("", type=['mp3', 'wav', 'm4a', 'ogg']) # Zone d'enregistrement audio st.markdown("### 🎤 Ou enregistrez directement") audio_bytes = audio_recorder() if audio_bytes: st.audio(audio_bytes, format="audio/wav") if uploaded_file or audio_bytes: with st.spinner("Traitement en cours..."): try: if uploaded_file: file_path = save_uploaded_file(uploaded_file) else: # Sauvegarder l'enregistrement audio timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") file_path = f"recording_{timestamp}.wav" with open(file_path, 'wb') as f: f.write(audio_bytes) # Traitement de l'audio chunks = st.session_state.audio_processor.chunk_audio(file_path) # Transcription with st.expander("Transcription", expanded=False): transcriptions = [] progress_bar = st.progress(0) for i, chunk in enumerate(chunks): transcription = st.session_state.audio_processor.transcribe_chunk(chunk) transcriptions.append(transcription) progress_bar.progress((i + 1) / len(chunks)) full_transcription = " ".join(transcriptions) st.text_area("Texte transcrit:", value=full_transcription, height=200) # Génération du résumé summary = st.session_state.audio_processor.generate_summary(full_transcription) st.markdown("### 📝 Résumé et Analyse") st.markdown(summary) # Création du PDF pdf_filename = f"resume_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf" pdf_path = PDFGenerator.create_pdf(summary, pdf_filename) # Options d'exportation with open(pdf_path, "rb") as pdf_file: pdf_bytes = pdf_file.read() st.download_button( label="📥 Télécharger le résumé (PDF)", data=pdf_bytes, file_name=pdf_filename, mime="application/pdf" ) # Section d'envoi par email st.markdown("### 📧 Recevoir le résumé par email") recipient_email = st.text_input("Entrez votre adresse email:") if st.button("Envoyer par email"): if not is_valid_email(recipient_email): st.error("Veuillez entrer une adresse email valide.") else: with st.spinner("Envoi de l'email en cours..."): email_body = "Veuillez trouver ci-joint le résumé de votre audio." if email_sender.send_email( recipient_email, "Résumé de votre enregistrement audio", email_body, pdf_path ): st.success("Email envoyé avec succès!") else: st.error("Échec de l'envoi de l'email.") except Exception as e: st.error(f"Une erreur est survenue: {str(e)}") finally: # Nettoyage des fichiers temporaires if 'file_path' in locals(): os.unlink(file_path) if 'pdf_path' in locals(): os.unlink(pdf_path) if __name__ == "__main__": main()