66408e291d
- meetrec.py: engine layer with a common transcribe() contract; WhisperCppEngine shells out to whisper-cli, GGML + Silero VAD models auto-download to ~/.cache/meetrec; faster-whisper import now lazy; new --engine CLI option - meetrec_gui.py: Engine dropdown; Device/Compute greyed out for whisper-cpp; model reload keyed on (engine, model, device, compute) - install.sh: --whisper-cpp builds whisper.cpp with -DWHISPER_VULKAN=ON, installs whisper-cli into the prefix and wires WHISPER_CPP_BIN via a generated whisper-cpp.env; build failures degrade to a warning - launchers source whisper-cpp.env; README documents engines - Recorder.stop() is now idempotent (GUI close path called it twice)
195 lines
7.2 KiB
Bash
Executable File
195 lines
7.2 KiB
Bash
Executable File
#!/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"
|
|
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"
|
|
install -m 0644 "$SCRIPT_DIR/share/applications/meetrec.desktop" \
|
|
"$DESKTOP_DIR/meetrec.desktop"
|
|
if command -v update-desktop-database >/dev/null 2>&1; then
|
|
update-desktop-database "$DESKTOP_DIR" 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" - <<EOF || echo "warning: model pre-download failed — it will download on first use."
|
|
from faster_whisper import WhisperModel
|
|
WhisperModel("$MODEL", device="cpu", compute_type="int8")
|
|
EOF
|
|
fi
|
|
|
|
if [ "$WHISPER_CPP" = 1 ] && [ "$DOWNLOAD_MODEL" = 1 ]; then
|
|
echo "==> 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
|