#!/usr/bin/env bash # # install.sh — install MeetRec (GUI + CLI) into a local prefix. # # Usage: # ./install.sh install, pre-downloading the 'small' model # ./install.sh --whisper-cpp also build whisper.cpp (Vulkan GPU backend) # ./install.sh --model base pre-download a different Whisper model # ./install.sh --no-model skip the model pre-download # ./install.sh --uninstall remove everything the installer created # # Environment: # PREFIX install prefix (default: $HOME/.local) # PYTHON Python interpreter to use (default: python3) set -euo pipefail PREFIX="${PREFIX:-$HOME/.local}" APP_DIR="$PREFIX/share/meetrec" VENV="$APP_DIR/venv" BIN_DIR="$PREFIX/bin" DESKTOP_DIR="$PREFIX/share/applications" PYTHON="${PYTHON:-python3}" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MODEL="small" DOWNLOAD_MODEL=1 UNINSTALL=0 WHISPER_CPP=0 while [ $# -gt 0 ]; do case "$1" in --model) [ $# -ge 2 ] || { echo "error: --model needs a value" >&2; exit 1; } MODEL="$2" shift 2 ;; --no-model) DOWNLOAD_MODEL=0; shift ;; --whisper-cpp) WHISPER_CPP=1; shift ;; --uninstall) UNINSTALL=1; shift ;; -h|--help) sed -n '2,14p' "$0" | sed 's/^# \{0,1\}//' exit 0 ;; *) echo "error: unknown option: $1" >&2 echo "try: ./install.sh --help" >&2 exit 1 ;; esac done # ---------------------------------------------------------------- uninstall if [ "$UNINSTALL" = 1 ]; then echo "Uninstalling MeetRec from $PREFIX ..." rm -rf "$APP_DIR" rm -f "$BIN_DIR/meetrec" "$BIN_DIR/meetrec-cli" rm -f "$DESKTOP_DIR/meetrec.desktop" find "$PREFIX/share/icons/hicolor" -name 'meetrec.*' -type f -delete 2>/dev/null || true if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database "$DESKTOP_DIR" 2>/dev/null || true fi echo "Done. (Whisper models remain in ~/.cache/huggingface and ~/.cache/meetrec — remove those if you want them gone.)" exit 0 fi # ------------------------------------------------------------------- checks echo "==> Checking prerequisites" if ! command -v "$PYTHON" >/dev/null 2>&1; then echo "error: $PYTHON not found. Install Python 3.10+ first." >&2 exit 1 fi if ! "$PYTHON" -c 'import sys; sys.exit(0 if sys.version_info >= (3, 10) else 1)'; then echo "error: Python 3.10+ required, found: $("$PYTHON" --version 2>&1)" >&2 exit 1 fi if ! command -v pactl >/dev/null 2>&1; then echo "warning: 'pactl' not found — is PipeWire/PulseAudio running?" echo " On Arch: sudo pacman -S pipewire pipewire-pulse" fi if ! command -v aplay >/dev/null 2>&1 && ! command -v arecord >/dev/null 2>&1; then echo "warning: ALSA utils not found — recording may not work." fi # -------------------------------------------------------------------- install echo "==> Installing app to $APP_DIR" mkdir -p "$APP_DIR" "$BIN_DIR" "$DESKTOP_DIR" cp "$SCRIPT_DIR/meetrec.py" "$SCRIPT_DIR/meetrec_gui.py" "$SCRIPT_DIR/requirements.txt" "$APP_DIR/" echo "==> Creating virtualenv" if ! "$PYTHON" -m venv "$VENV"; then echo "error: could not create a venv." >&2 echo " Debian/Ubuntu: sudo apt install python3-venv" >&2 echo " Arch: sudo pacman -S python-virtualenv (or ensure python3-venv)" >&2 exit 1 fi "$VENV/bin/pip" install --upgrade pip --quiet echo "==> Installing Python dependencies (numpy, sounddevice, faster-whisper, pyside6)" "$VENV/bin/pip" install -r "$APP_DIR/requirements.txt" # ----------------------------------------------------------- whisper.cpp build if [ "$WHISPER_CPP" = 1 ]; then echo "==> Building whisper.cpp (Vulkan GPU backend)" build_ok=1 for t in git cmake g++ make; do command -v "$t" >/dev/null 2>&1 || { echo "warning: '$t' not found — skipping the whisper.cpp build." >&2 build_ok=0 } done if [ "$build_ok" = 1 ]; then if command -v pkg-config >/dev/null 2>&1 && ! pkg-config --exists vulkan; then echo "warning: Vulkan dev headers not found — the build may fail." echo " On Arch: sudo pacman -S vulkan-headers" fi SRC="$APP_DIR/src/whisper.cpp" if [ -d "$SRC/.git" ]; then git -C "$SRC" pull --ff-only || true else git clone --depth 1 https://github.com/ggml-org/whisper.cpp "$SRC" fi # The GPU engine is optional: a failed build must not leave the core # install half-done, so degrade to a warning and continue. if ! (cmake -S "$SRC" -B "$SRC/build" -DCMAKE_BUILD_TYPE=Release \ -DWHISPER_VULKAN=ON \ && cmake --build "$SRC/build" -j"$(nproc)" \ && install -Dm755 "$SRC/build/bin/whisper-cli" \ "$PREFIX/share/meetrec/whisper-cpp/bin/whisper-cli"); then echo "warning: whisper.cpp build failed — continuing without the GPU engine." >&2 echo " faster-whisper (CPU) still works; retry the build later with ./install.sh --whisper-cpp" >&2 fi fi fi echo "==> Installing launchers into $BIN_DIR" install -m 0755 "$SCRIPT_DIR/bin/meetrec" "$BIN_DIR/meetrec" install -m 0755 "$SCRIPT_DIR/bin/meetrec-cli" "$BIN_DIR/meetrec-cli" if [ -x "$PREFIX/share/meetrec/whisper-cpp/bin/whisper-cli" ]; then printf 'WHISPER_CPP_BIN="%s"\n' \ "$PREFIX/share/meetrec/whisper-cpp/bin/whisper-cli" \ > "$APP_DIR/whisper-cpp.env" echo " (whisper.cpp engine installed — select 'whisper-cpp' to use the GPU)" fi echo "==> Installing XDG desktop entry and icon" install -m 0644 "$SCRIPT_DIR/share/applications/meetrec.desktop" \ "$DESKTOP_DIR/meetrec.desktop" for f in "$SCRIPT_DIR"/share/icons/hicolor/*/apps/meetrec.* \ "$SCRIPT_DIR"/share/icons/hicolor/scalable/apps/meetrec.svg; do rel="${f#"$SCRIPT_DIR"/share/icons/}" install -Dm 0644 "$f" "$PREFIX/share/icons/$rel" done if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database "$DESKTOP_DIR" 2>/dev/null || true fi if command -v gtk-update-icon-cache >/dev/null 2>&1; then gtk-update-icon-cache -q -t -f "$PREFIX/share/icons/hicolor" 2>/dev/null || true fi if [ "$DOWNLOAD_MODEL" = 1 ]; then echo "==> Pre-downloading Whisper model '$MODEL' (first run only, can take a while)" "$VENV/bin/python" - < Pre-downloading whisper.cpp model ggml-$MODEL.bin" CACHE="$HOME/.cache/meetrec/whisper-cpp" mkdir -p "$CACHE" if command -v curl >/dev/null 2>&1; then curl -fL --retry 3 -C - -o "$CACHE/ggml-$MODEL.bin.part" \ "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-$MODEL.bin" \ && mv "$CACHE/ggml-$MODEL.bin.part" "$CACHE/ggml-$MODEL.bin" \ || echo "warning: ggml model download failed — it will retry on first use." else echo "warning: curl not found — skipping ggml model pre-download" fi fi # ----------------------------------------------------------------- summary echo echo "Installed MeetRec to $PREFIX" echo echo " GUI: meetrec (also available from your app menu as 'MeetRec')" echo " CLI: meetrec-cli --help" echo " Uninstall: ./install.sh --uninstall" echo if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then echo "note: $BIN_DIR is not in your PATH. Add it, e.g.:" echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> ~/.bashrc" fi