File size: 4,079 Bytes
d48624f
 
0125dc0
d48624f
 
 
 
 
0125dc0
 
d48624f
 
 
0125dc0
 
d48624f
 
0125dc0
 
 
 
 
 
 
 
 
 
d48624f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0125dc0
d48624f
5a00d25
d48624f
 
5a00d25
 
d48624f
 
5a00d25
d48624f
 
0125dc0
 
 
 
 
 
 
 
 
 
5a00d25
0125dc0
5a00d25
d48624f
0125dc0
d48624f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5a00d25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import streamlit as st
import whisper
import torch
from transformers import pipeline
import spacy
from summa import keywords
import datetime
import os
from pydub import AudioSegment
import concurrent.futures

@st.cache_resource
def load_models():
    device = "cuda" if torch.cuda.is_available() else "cpu"
    whisper_model = whisper.load_model("small").to(device)  # Using 'small' for faster speed
    summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
    nlp = spacy.load("en_core_web_sm")
    return whisper_model, summarizer, nlp, device

def split_audio(file_path, chunk_length_ms=60000):  # 60 seconds per chunk
    audio = AudioSegment.from_file(file_path)
    chunks = [audio[i : i + chunk_length_ms] for i in range(0, len(audio), chunk_length_ms)]
    return chunks

def transcribe_chunk(whisper_model, chunk_path, device):
    options = {"fp16": False} if device == "cpu" else {"fp16": True}
    return whisper_model.transcribe(chunk_path, **options)["text"]

def extract_action_items(text, nlp):
    doc = nlp(text)
    actions = []
    
    for sent in doc.sents:
        for token in sent:
            if token.dep_ == "ROOT" and token.pos_ == "VERB":
                action = {
                    "text": sent.text,
                    "responsible": [],
                    "deadline": []
                }
                
                for ent in sent.ents:
                    if ent.label_ == "PERSON":
                        action["responsible"].append(ent.text)
                    elif ent.label_ == "DATE":
                        action["deadline"].append(ent.text)
                
                actions.append(action)
                break
    return actions

def main():
    st.title("πŸ€– Smart AI Meeting Assistant")
    
    whisper_model, summarizer, nlp, device = load_models()
    
    audio_file = st.file_uploader("Upload meeting audio", type=["wav", "mp3", "m4a", "ogg", "flac"])
    
    if audio_file is not None:
        file_path = f"uploaded_audio_{datetime.datetime.now().timestamp()}.wav"
        
        with open(file_path, "wb") as f:
            f.write(audio_file.getbuffer())

        st.subheader("Meeting Transcription")
        with st.spinner("Transcribing audio..."):
            chunks = split_audio(file_path)
            chunk_paths = []
            
            for i, chunk in enumerate(chunks):
                chunk_path = f"chunk_{i}.wav"
                chunk.export(chunk_path, format="wav")
                chunk_paths.append(chunk_path)
            
            with concurrent.futures.ThreadPoolExecutor() as executor:
                transcripts = list(executor.map(lambda cp: transcribe_chunk(whisper_model, cp, device), chunk_paths))
            
            transcript = " ".join(transcripts)
        
        st.write(transcript)
        os.remove(file_path)
        
        st.subheader("Meeting Summary")
        with st.spinner("Generating summary..."):
            truncated_text = transcript[:1024]
            summary = summarizer(truncated_text, max_length=150, min_length=50)[0]['summary_text']
        st.write(summary)
        
        st.subheader("πŸš€ Action Items")
        actions = extract_action_items(transcript, nlp)
        
        if not actions:
            st.write("No action items detected")
        else:
            for i, action in enumerate(actions, 1):
                responsible = ", ".join(action["responsible"]) or "Unassigned"
                deadline = ", ".join(action["deadline"]) or "No deadline"
                st.markdown(f"""
                **Action {i}**
                - Task: {action["text"]}
                - Responsible: {responsible}
                - Deadline: {deadline}
                """)
        
        st.subheader("πŸ”‘ Key Terms")
        key_phrases_result = keywords.keywords(transcript) or ""
        key_phrases = [kp.strip() for kp in key_phrases_result.split("\n") if kp.strip()]
        st.write(", ".join(key_phrases) if key_phrases else "No key terms extracted")

if __name__ == "__main__":
    main()