irfansaleem48's picture
Update app.py
0125dc0 verified
raw
history blame
4.08 kB
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()