add compile meeting, summarize. both for local llm run
This commit is contained in:
121
transcribe_oneoff.sh
Executable file
121
transcribe_oneoff.sh
Executable 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:
|
||||
# ./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."
|
||||
Reference in New Issue
Block a user