refactor (untested)

This commit is contained in:
Mariano Gabriel
2026-06-28 21:12:13 -03:00
parent 5ea05eb553
commit cc64544d50
26 changed files with 540 additions and 340 deletions

121
ctrl/transcribe_oneoff.sh Executable file
View File

@@ -0,0 +1,121 @@
#!/usr/bin/env bash
# One-off "high-quality" transcription that overrides the cached transcript
# in the most recent run directory for the given video, then re-runs the
# merger so the enhanced transcript is regenerated using the existing frames.
#
# Usage:
# ./ctrl/transcribe_oneoff.sh <video> [language]
# language: optional ISO code (es, en). Omit for auto-detect.
#
# What this does differently from the main pipeline:
# 1. Reuses the existing run directory (frames cache stays put).
# 2. Preprocesses audio: loudnorm + light denoise + speech-band filter.
# 3. Uses whisperx large-v3 with int8 quantization (fits in ~3-4 GB GPU).
# 4. Stricter no-speech / logprob thresholds to suppress hallucinations on
# silent stretches (the source of the random Arabic/etc. drift).
# 5. Backs up the old <stem>.json before overwriting, so it is recoverable.
# 6. Re-runs process_meeting.py without --run-whisper/--diarize so the new
# transcript is picked up from cache and merged with the cached frames.
set -euo pipefail
VIDEO="${1:?usage: $0 <video> [language]}"
LANG="${2:-}"
VENV_DIR="/home/mariano/wdir/venv/def"
if [[ ! -f "$VENV_DIR/bin/activate" ]]; then
echo "ERROR: venv not found at $VENV_DIR" >&2
exit 1
fi
# shellcheck disable=SC1091
source "$VENV_DIR/bin/activate"
WHISPERX="whisperx"
PYTHON="python"
if [[ ! -f "$VIDEO" ]]; then
echo "ERROR: video not found: $VIDEO" >&2
exit 1
fi
STEM="$(basename "${VIDEO%.*}")"
# Locate the most recent run dir for this video stem.
RUN_DIR="$(ls -1dt output/*-"$STEM" 2>/dev/null | head -n1 || true)"
if [[ -z "$RUN_DIR" || ! -d "$RUN_DIR" ]]; then
echo "ERROR: no existing run dir found under output/ for stem '$STEM'." >&2
echo " Run process_meeting.py at least once first to extract frames." >&2
exit 1
fi
echo "==> Using run dir: $RUN_DIR"
TRANSCRIPT_JSON="$RUN_DIR/${STEM}.json"
# Back up the old transcript before overwrite.
if [[ -f "$TRANSCRIPT_JSON" ]]; then
BACKUP="$TRANSCRIPT_JSON.bak.$(date +%Y%m%d-%H%M%S)"
cp "$TRANSCRIPT_JSON" "$BACKUP"
echo "==> Backed up old transcript → $BACKUP"
fi
# No audio preprocessing: previous attempts with afftdn/loudnorm caused VAD
# to drop the bulk of the meeting after ~20min. Feed the raw video directly;
# whisperx will extract audio internally.
INPUT_AUDIO="$VIDEO"
# cuDNN libs for whisperx (mirrors what process_meeting.py does).
SITE_PKGS="$(python -c 'import site; print(site.getsitepackages()[0])')"
CUDNN_LIB="$SITE_PKGS/nvidia/cudnn/lib"
if [[ -d "$CUDNN_LIB" ]]; then
export LD_LIBRARY_PATH="$CUDNN_LIB:${LD_LIBRARY_PATH:-}"
fi
# whisperx writes <input_basename>.json into --output_dir.
# Our input basename is "${STEM}_clean", so we redirect to a temp dir and
# move the result into place under the canonical name.
TX_TMP="$(mktemp -d)"
trap 'rm -rf "$TX_TMP"' EXIT
CMD=(
"$WHISPERX" "$INPUT_AUDIO"
--model large-v3
--compute_type int8
--batch_size 4
--output_format json
--output_dir "$TX_TMP"
--diarize
)
if [[ -n "$LANG" ]]; then
echo "==> Forcing language: $LANG"
CMD+=(--language "$LANG")
else
echo "==> Auto-detecting language"
fi
if [[ -n "${HF_TOKEN:-}" ]]; then
CMD+=(--hf_token "$HF_TOKEN")
fi
echo "==> Running: ${CMD[*]}"
"${CMD[@]}"
# Move whisperx output into place under the canonical name expected by the cache.
# whisperx names output by the input basename (without extension).
NEW_JSON="$TX_TMP/${STEM}.json"
if [[ ! -f "$NEW_JSON" ]]; then
echo "ERROR: expected whisperx output not found: $NEW_JSON" >&2
exit 1
fi
mv "$NEW_JSON" "$TRANSCRIPT_JSON"
echo "==> Wrote new transcript → $TRANSCRIPT_JSON"
echo
echo "==> Re-running merger to regenerate enhanced transcript with cached frames"
"$PYTHON" process_meeting.py "$VIDEO" \
--embed-images \
--scene-detection \
--scene-threshold 10
echo
echo "==> Done."