generated from nhcarrigan/template
89 lines
2.5 KiB
Python
89 lines
2.5 KiB
Python
import subprocess
|
|
import json
|
|
import datetime
|
|
|
|
# === CONFIG ===
|
|
# Use current timestamp for file naming
|
|
TIMESTAMP = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
MEETING_FILE = f"meeting_audio_{TIMESTAMP}.wav"
|
|
WHISPER_MODEL = "small.en"
|
|
DURATION = 36000 # seconds (10 hour max)
|
|
OUTPUT_TRANSCRIPT = f"meeting_audio_{TIMESTAMP}.json"
|
|
OUTPUT_SUMMARY = f"summary_{TIMESTAMP}.txt"
|
|
|
|
def record_audio():
|
|
print("๐ Recording meeting audio... (q to stop early)")
|
|
subprocess.run([
|
|
"ffmpeg",
|
|
"-f", "pulse", # Linux (change for Windows/macOS)
|
|
"-i", "default", # capture default input/output mix
|
|
"-t", str(DURATION),
|
|
"-ac", "2",
|
|
"-ar", "44100",
|
|
MEETING_FILE
|
|
], check=True)
|
|
|
|
def transcribe_audio():
|
|
print("๐ Transcribing with WhisperX...")
|
|
subprocess.run([
|
|
"uvx",
|
|
"whisperx",
|
|
MEETING_FILE,
|
|
"--device", "cpu", # Use CPU
|
|
"--language", "en",
|
|
# Uncomment the next line to enable diarization, requires you to download the model from Hugging Face.
|
|
# "--diarize",
|
|
"--compute_type", "float32",
|
|
"--model", WHISPER_MODEL,
|
|
"--output_format", "json",
|
|
"--output_dir", "."
|
|
# You should only need to uncomment this once to perform the initial model download.
|
|
# "--hf_token", "your_huggingface_token_here"
|
|
], check=True)
|
|
|
|
def summarize_with_local_model():
|
|
print("๐งพ Summarizing locally with Ollama...")
|
|
with open(OUTPUT_TRANSCRIPT, "r", encoding="utf-8") as f:
|
|
transcript = json.load(f)
|
|
|
|
text = "\n".join(
|
|
f"{seg['speaker']}: {seg['text']}"
|
|
for seg in transcript["segments"]
|
|
)
|
|
|
|
prompt = f"""Summarize this meeting transcript into clear bullet points with:
|
|
- Key decisions
|
|
- Action items
|
|
- Notable discussion points
|
|
|
|
Transcript:
|
|
{text}
|
|
"""
|
|
|
|
result = subprocess.run(
|
|
["ollama", "run", "llama3:8b"],
|
|
input=prompt.encode(),
|
|
capture_output=True,
|
|
check=True
|
|
)
|
|
|
|
summary = result.stdout.decode()
|
|
|
|
with open(OUTPUT_SUMMARY, "w", encoding="utf-8") as f:
|
|
f.write(summary)
|
|
|
|
print("โ
Summary written to", OUTPUT_SUMMARY)
|
|
|
|
def cleanup():
|
|
import os
|
|
if os.path.exists(MEETING_FILE):
|
|
os.remove(MEETING_FILE)
|
|
if os.path.exists(OUTPUT_TRANSCRIPT):
|
|
os.remove(OUTPUT_TRANSCRIPT)
|
|
|
|
if __name__ == "__main__":
|
|
record_audio()
|
|
transcribe_audio()
|
|
summarize_with_local_model()
|
|
cleanup()
|