Spaces:
Sleeping
Sleeping
| # transcribe_vod.sh — transcribes vod.mp4 using whisper.cpp (CPU, no GPU needed) | |
| # Usage: bash transcribe_vod.sh /path/to/vod.mp4 | |
| # Output: vod_transcript.txt in the same directory as the video | |
| set -e | |
| VIDEO="${1:-vod.mp4}" | |
| if [[ ! -f "$VIDEO" ]]; then | |
| echo "Error: file not found: $VIDEO" | |
| echo "Usage: bash transcribe_vod.sh /path/to/vod.mp4" | |
| exit 1 | |
| fi | |
| VIDEO_DIR="$(dirname "$VIDEO")" | |
| BASENAME="$(basename "$VIDEO" .mp4)" | |
| AUDIO="/tmp/${BASENAME}_audio.wav" | |
| TRANSCRIPT_OUT="${VIDEO_DIR}/${BASENAME}_transcript.txt" | |
| echo "==> Checking dependencies..." | |
| if ! command -v ffmpeg &>/dev/null; then | |
| echo "Error: ffmpeg not found in PATH." | |
| echo "Install ffmpeg with: brew install ffmpeg" | |
| exit 1 | |
| fi | |
| # ---- Option A: Homebrew whisper.cpp (fastest to set up on Mac) ---- | |
| if command -v brew &>/dev/null && brew list whisper-cpp &>/dev/null 2>&1; then | |
| echo "==> Found whisper-cpp via Homebrew" | |
| WHISPER_CLI="$(brew --prefix whisper-cpp)/bin/whisper-cli" | |
| MODEL_PATH="$(brew --prefix whisper-cpp)/share/whisper-cpp/ggml-base.en.bin" | |
| if [[ ! -f "$MODEL_PATH" ]]; then | |
| echo "==> Downloading base.en model via Homebrew..." | |
| brew install --formula whisper-cpp --with-base-model 2>/dev/null || \ | |
| curl -L -o "$MODEL_PATH" \ | |
| "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin" | |
| fi | |
| # ---- Option B: Install via Homebrew now ---- | |
| elif command -v brew &>/dev/null; then | |
| echo "==> Installing whisper-cpp via Homebrew..." | |
| brew install whisper-cpp | |
| WHISPER_CLI="$(brew --prefix whisper-cpp)/bin/whisper-cli" | |
| MODEL_DIR="$(brew --prefix whisper-cpp)/share/whisper-cpp" | |
| mkdir -p "$MODEL_DIR" | |
| MODEL_PATH="${MODEL_DIR}/ggml-base.en.bin" | |
| echo "==> Downloading base.en model (~147 MB)..." | |
| curl -L --progress-bar -o "$MODEL_PATH" \ | |
| "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin" | |
| # ---- Option C: openai-whisper via pip (fallback) ---- | |
| elif command -v pip3 &>/dev/null || command -v pip &>/dev/null; then | |
| echo "==> Homebrew not found — falling back to openai-whisper (pip)..." | |
| pip3 install -q openai-whisper 2>/dev/null || pip install -q openai-whisper | |
| echo "==> Transcribing with openai-whisper (this may take a while)..." | |
| python3 - "$VIDEO" "$TRANSCRIPT_OUT" <<'PYEOF' | |
| import sys, whisper | |
| video, out = sys.argv[1], sys.argv[2] | |
| model = whisper.load_model("base.en") | |
| print(f"Transcribing {video} ...") | |
| result = model.transcribe(video, verbose=False) | |
| with open(out, "w") as f: | |
| for seg in result["segments"]: | |
| ts = f"[{seg['start']:.1f}s - {seg['end']:.1f}s]" | |
| f.write(f"{ts} {seg['text'].strip()}\n") | |
| print(f"Transcript saved to {out}") | |
| PYEOF | |
| exit 0 | |
| else | |
| echo "Error: neither Homebrew nor pip found." | |
| echo "Install Homebrew first: https://brew.sh" | |
| exit 1 | |
| fi | |
| # ---- Shared: extract audio + run whisper-cli ---- | |
| echo "==> Extracting audio from $VIDEO..." | |
| ffmpeg -i "$VIDEO" -vn -acodec pcm_s16le -ar 16000 -ac 1 "$AUDIO" -y | |
| echo "==> Running whisper transcription (base.en model)..." | |
| "$WHISPER_CLI" \ | |
| --model "$MODEL_PATH" \ | |
| --file "$AUDIO" \ | |
| --output-txt \ | |
| --output-file "${VIDEO_DIR}/${BASENAME}_transcript" \ | |
| --language en \ | |
| --print-progress \ | |
| 2>&1 | |
| # whisper-cli appends .txt automatically | |
| if [[ -f "${VIDEO_DIR}/${BASENAME}_transcript.txt" ]]; then | |
| echo "" | |
| echo "==> Done! Transcript saved to: ${VIDEO_DIR}/${BASENAME}_transcript.txt" | |
| else | |
| echo "Warning: output file not found at expected path." | |
| echo "Check ${VIDEO_DIR}/ for transcript files." | |
| fi | |
| rm -f "$AUDIO" | |