File size: 3,528 Bytes
6e9392f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/bin/bash
# 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"