- Posted on
- • Artificial Intelligence
Artificial Intelligence Meeting Summaries
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
AI-Powered Meeting Summaries from the Linux Terminal (Bash-first Guide)
Ever left a meeting with a full recording but no time to write minutes? Or wished someone else would pull out the decisions and action items for you? With today’s speech-to-text and language models, you can automate accurate, private meeting summaries right from your Linux terminal—no SaaS required.
In this guide, you’ll build a simple, reliable Bash pipeline that:
Converts your meeting audio to clean text
Summarizes it into clear, structured minutes (Agenda, Key Points, Decisions, Action Items)
Automates the process for any new recording that lands in a folder
All with open tools you control.
Why this matters (and works)
Time savings: Manual minutes consume hours per week. Automation turns recordings into minutes in minutes.
Better recall: Transcripts let you search, link, and verify what was said.
Privacy-first: Run transcription and summarization locally—keep sensitive data off third-party servers.
Reliability: Whisper-based transcription is state-of-the-art; local LLMs can generate structured outcomes if you give them a good prompt.
Bash-native: The workflow glues together standard Linux tools you already use.
1) Install prerequisites
We’ll need:
ffmpeg for audio processing
inotify-tools to watch a folder for new files (optional but useful)
Python + pip for Whisper CLI
Ollama for local LLM summarization
Pick your package manager below and run the commands.
Debian/Ubuntu (apt)
sudo apt update
sudo apt install -y ffmpeg inotify-tools python3 python3-pip curl git
Fedora/RHEL/CentOS (dnf)
sudo dnf install -y ffmpeg inotify-tools python3 python3-pip curl git
If ffmpeg isn’t found on your Fedora/RHEL variant, enable RPM Fusion (then rerun the ffmpeg install):
sudo dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
sudo dnf install -y ffmpeg
openSUSE (zypper)
sudo zypper refresh
sudo zypper install -y ffmpeg inotify-tools python3 python3-pip curl git
Install Whisper CLI (transcription)
Whisper requires PyTorch; pip will install a CPU wheel automatically on most Linux distros.
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade openai-whisper torch
Validate:
whisper --help
Install Ollama (local LLM for summarization)
curl -fsSL https://ollama.com/install.sh | sh
Start the service and pull a model. Llama 3 8B is a good balance; Mistral 7B also works.
ollama serve &
ollama pull llama3:8b
# or
ollama pull mistral
Note: CPU works but is slower; a GPU will accelerate both Whisper (if you later install CUDA-enabled torch) and Ollama.
Optional fallback summarizer (if you don’t want a local LLM yet):
python3 -m pip install --upgrade sumy
2) Transcribe any meeting audio to text
Clean and normalize the audio with ffmpeg, then transcribe with Whisper.
# Convert to mono, 16kHz WAV for best results
ffmpeg -y -i meeting.mp4 -ac 1 -ar 16000 -af loudnorm meeting.wav
# Transcribe to plain text (choose a model: tiny, base, small, medium, large)
whisper meeting.wav --model small --language en --output_format txt --output_dir out
# This produces: out/meeting.txt
Tips:
If your meeting language isn’t English, omit --language en and let Whisper auto-detect.
Larger models increase accuracy but need more compute.
3) Summarize the transcript with a local LLM
Pipe the transcript into Ollama and prompt for structured minutes.
cat out/meeting.txt | ollama run llama3:8b -p 'You are a meticulous meeting-notes assistant.
Summarize the meeting transcript in {{ .input }} into a concise Markdown document with:
- Title (+ date if found)
- Attendees (guess if necessary)
- Agenda (bulleted)
- Key Points (bulleted)
- Decisions (D1, D2, ...)
- Action Items (A1, A2, ... with owner and due date if mentioned)
- Risks/Blockers
- Next Steps
Be specific, avoid fluff, and quote exact numbers/dates where present.' > out/meeting.summary.md
Open out/meeting.summary.md and you should see clean, structured minutes.
No LLM? Use a classic extractive fallback (less rich but instant):
sumy lex-rank --length=15% --file=out/meeting.txt > out/meeting.summary.md
4) One-command workflow script
Create a single script that:
Normalizes audio
Transcribes with Whisper
Summarizes with Ollama (or falls back to Sumy)
Writes a Markdown file with a timestamped name
Save as ai-minutes.sh and make it executable.
#!/usr/bin/env bash
set -euo pipefail
# Config
WHISPER_MODEL="${WHISPER_MODEL:-small}"
LANG="${LANG:-en}" # set to "" to auto-detect
SUM_MODEL="${SUM_MODEL:-llama3:8b}"
infile="${1:-}"
if [[ -z "${infile}" || ! -f "${infile}" ]]; then
echo "Usage: $0 <audio_or_video_file>"
exit 1
fi
outdir="${2:-out}"
mkdir -p "$outdir"
base="$(basename "$infile")"
stem="${base%.*}"
ts="$(date +%Y%m%d-%H%M%S)"
work="${outdir}/${stem}-${ts}"
mkdir -p "$work"
echo "[1/4] Normalizing audio..."
ffmpeg -y -i "$infile" -ac 1 -ar 16000 -af loudnorm "$work/audio.wav" >/dev/null 2>&1
echo "[2/4] Transcribing with Whisper ($WHISPER_MODEL)..."
lang_flag=()
[[ -n "$LANG" ]] && lang_flag+=(--language "$LANG")
whisper "$work/audio.wav" --model "$WHISPER_MODEL" --output_format txt --output_dir "$work" "${lang_flag[@]}" >/dev/null 2>&1
transcript="$work/audio.txt"
if [[ ! -s "$transcript" ]]; then
echo "Transcription failed or produced empty output."
exit 2
fi
echo "[3/4] Summarizing..."
summary="$work/summary.md"
if command -v ollama >/dev/null 2>&1; then
cat "$transcript" | ollama run "$SUM_MODEL" -p 'You are a meticulous meeting-notes assistant.
Summarize the meeting transcript in {{ .input }} into a concise Markdown document with:
- Title (+ date if found)
- Attendees (guess if necessary)
- Agenda (bulleted)
- Key Points (bulleted)
- Decisions (D1, D2, ...)
- Action Items (A1, A2, ... with owner and due date if mentioned)
- Risks/Blockers
- Next Steps
Be specific, avoid fluff, and quote exact numbers/dates where present.' > "$summary"
else
echo "Ollama not found; using extractive fallback (sumy)."
python3 -m pip show sumy >/dev/null 2>&1 || python3 -m pip install --user sumy >/dev/null 2>&1
sumy lex-rank --length=15% --file="$transcript" > "$summary"
fi
echo "[4/4] Done."
echo "Transcript: $transcript"
echo "Summary: $summary"
Usage:
chmod +x ai-minutes.sh
./ai-minutes.sh meeting.mp4
5) Auto-summarize every new recording dropped into a folder
Use inotify-tools to watch a directory and run the pipeline for each completed file.
Save as watch-minutes.sh:
#!/usr/bin/env bash
set -euo pipefail
WATCH_DIR="${1:-incoming}"
OUT_DIR="${2:-out}"
mkdir -p "$WATCH_DIR" "$OUT_DIR"
echo "Watching $WATCH_DIR for new files..."
inotifywait -m -e close_write --format '%w%f' "$WATCH_DIR" | while read -r file; do
case "$file" in
*.mp3|*.wav|*.m4a|*.mp4|*.mkv|*.webm)
echo "Detected new media: $file"
./ai-minutes.sh "$file" "$OUT_DIR" || echo "Failed to process: $file"
;;
*)
;;
esac
done
Run it:
chmod +x watch-minutes.sh
./watch-minutes.sh ./incoming ./out
# Now drop files into ./incoming and watch summaries appear in ./out
Real-world tips
Improve accuracy: Use a better Whisper model (e.g., medium) and ensure clean audio (headsets > room mics).
Multilingual: Omit --language to auto-detect or set LANG="" in the script.
Customize style: Edit the prompt in ai-minutes.sh to match your team’s format (e.g., include Jira ticket patterns).
GPU acceleration: Install CUDA-enabled torch for Whisper and ensure Ollama uses your GPU.
Privacy and policy: Even local pipelines handle sensitive data; set disk permissions and clean up raw audio if required.
Conclusion and next steps
With a few commands, you now have a private, Linux-native system that turns meetings into actionable minutes—accurately and on autopilot.
Your next steps:
Run ai-minutes.sh on your last meeting and review the result.
Tune the prompt to your team’s template.
Put watch-minutes.sh on a server or CI box and point your recorder uploads to the watch folder.
If this saved you time, share the script with your team—or extend it with calendar integration and automatic attendee detection. Happy automating!