Turn short videos into searchable text in minutes
Welcome to another official UVF IT build guide. Today, we are constructing a minimal clone of HiTranscript, a tool that converts video content into searchable transcripts.
We will use Python with the whisper library for speech recognition and ffmpeg for audio extraction. This stack is free, open-source, and runs entirely on your local machine without paid APIs.
ffmpeg installed and available in your system PATH; this is required for extracting audio from video files.whisper library (OpenAI) requires PyTorch. Installation may take a few minutes and requires ~2-4GB of disk space for the model weights.tiny model for speed; it is less accurate than larger models but sufficient for a beginner demo.Create a project directory and a virtual environment to isolate dependencies.
Install openai-whisper (which includes PyTorch) and ffmpeg-python for easy media handling.
mkdir uvf-transcriber
cd uvf-transcriber
python3 -m venv venv
source venv/bin/activate
pip install openai-whisper ffmpeg-pythonWhisper requires audio input. We will write a helper function to extract audio from a video file using ffmpeg.
This step converts the video to a .wav file, which is the standard format for speech recognition.
transcriber.py
import ffmpeg
import os
def extract_audio(video_path, audio_path):
"""
Extracts audio from a video file and saves it as a .wav file.
"""
try:
(ffmpeg
.input(video_path)
.output(audio_path, acodec='pcm_s16le', ac=1, ar='16k')
.overwrite_output()
.run(capture_stdout=True, capture_stderr=True))
print(f"Audio extracted to: {audio_path}")
except ffmpeg.Error as e:
print(f"FFmpeg error: {e.stderr.decode()}")
raiseLoad the Whisper model. We use 'tiny' for speed, but you can change this to 'base' or 'small' for better accuracy.
The transcribe method returns a dictionary containing the full text and segmented timestamps.
transcriber.py
import whisper
def transcribe_audio(audio_path, model_name='tiny'):
"""
Loads the Whisper model and transcribes the audio file.
"""
print(f"Loading model '{model_name}'...")
model = whisper.load_model(model_name)
print("Transcribing...")
result = model.transcribe(audio_path)
return result['text']We now combine our helper functions into a single, executable script. By using Python's argparse, we create a simple command-line interface that accepts a video file path as an argument.
This main block orchestrates the workflow: it extracts audio, runs the Whisper model, and saves the resulting text to a file named after the input video. This makes the tool reusable for any video file you throw at it.
transcriber.py
import argparse
import os
import whisper
from moviepy.editor import VideoFileClip
def extract_audio(video_path, audio_path):
"""Extract audio from video and save as .wav"""
video = VideoFileClip(video_path)
video.audio.write_audiofile(audio_path, codec='pcm_s16le')
video.close()
print(f"Audio extracted to: {audio_path}")
def transcribe_audio(audio_path):
"""Transcribe audio file using Whisper"""
print("Loading Whisper model (tiny)...")
model = whisper.load_model("tiny")
print("Transcribing...")
result = model.transcribe(audio_path)
return result["text"]
def main():
parser = argparse.ArgumentParser(description="Video to Text Transcriber")
parser.add_argument("video_path", help="Path to the input video file")
args = parser.parse_args()
if not os.path.exists(args.video_path):
print(f"Error: File '{args.video_path}' not found.")
return
base_name = os.path.splitext(os.path.basename(args.video_path))[0]
audio_path = f"{base_name}_audio.wav"
output_txt = f"{base_name}_transcript.txt"
try:
# Step 1: Extract Audio
extract_audio(args.video_path, audio_path)
# Step 2: Transcribe
text = transcribe_audio(audio_path)
# Step 3: Save Output
with open(output_txt, "w", encoding="utf-8") as f:
f.write(text)
print(f"Success! Transcript saved to: {output_txt}")
# Cleanup optional: remove audio file if desired
# os.remove(audio_path)
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__":
main()To test your new tool, you need a sample video file. You can use any short .mp4 file from your computer or download a free stock video from sites like Pexels.
Run the script from your terminal, ensuring your virtual environment is active. The first run will download the Whisper model weights, which may take a moment, but subsequent runs will be much faster.
# Activate your virtual environment first (if not already active)
# On Mac/Linux:
source venv/bin/activate
# On Windows:
# venv\Scripts\activate
# Run the transcriber with your video file
python transcriber.py sample_video.mp4
# Check the output
ls -l sample_video_transcript.txt
cat sample_video_transcript.txt| Check | Command / Why it matters |
|---|---|
| Virtual environment activated | Run which python (Mac/Linux) or where python (Windows) to ensure it points to ./venv/bin/python. |
| FFmpeg installed | Run ffmpeg -version in terminal. If command not found, install FFmpeg via Homebrew (brew install ffmpeg) or package manager. |
| Transcript generated | Check for a .txt file in your directory containing readable text that matches the video audio. |
| No errors during model load | The first run downloads the model. Subsequent runs should be faster. Ensure no PyTorch CUDA errors if running on CPU. |
To extend this, try adding a simple Flask API to accept file uploads via a web form, or switch the model to 'base' for higher accuracy on noisy audio.