Skip to main content
The Subtitles component adds stylized, timed subtitles to videos using transcription data with automatic scaling and positioning.

Functions

add_subtitles_to_video

Adds timed subtitles to a video based on transcription segments with dynamic sizing and styling.
add_subtitles_to_video(input_video: str, output_video: str, 
                       transcriptions: list, video_start_time: float = 0) -> None
input_video
str
required
Path to the input video file
output_video
str
required
Path where the subtitled video will be saved
transcriptions
list
required
List of transcription segments from transcribeAudio(), formatted as:
[[text, start_time, end_time], ...]
Each segment contains:
  • text (str): The subtitle text
  • start_time (float): Start time in seconds
  • end_time (float): End time in seconds
video_start_time
float
default:"0"
Start time offset if the video was cropped from a longer video. Adjusts transcription times to match the video segment.

Subtitle Styling

fontsize
int
default:"dynamic"
Dynamically calculated as 6.5% of video height:
  • 1080p video → 70px
  • 720p video → 47px
  • 480p video → 31px
color
str
default:"#2699ff"
Bright blue color for high contrast on vertical videos
stroke_color
str
default:"black"
Black outline for readability on any background
stroke_width
int
default:"2"
2-pixel outline width for clear text edges
font
str
default:"Franklin-Gothic"
Modern, readable sans-serif font

Positioning

  • Horizontal: Centered with 50px margin on each side
  • Vertical: 100px from bottom of video
  • Width: Video width minus 100px (50px margin each side)
  • Method: Caption mode for automatic text wrapping
from Components.Transcription import transcribeAudio
from Components.Subtitles import add_subtitles_to_video

# Get transcriptions
transcriptions = transcribeAudio("audio.wav")
# Result: [["Hello world", 0.0, 2.5], ["Welcome", 2.5, 5.0], ...]

# Add subtitles to full video
add_subtitles_to_video(
    input_video="video.mp4",
    output_video="video_with_subs.mp4",
    transcriptions=transcriptions,
    video_start_time=0
)

# Output:
# Adding 45 subtitle segments to video...
# ✓ Subtitles added successfully -> video_with_subs.mp4

Features

Automatic Time Adjustment

Filters and adjusts transcriptions to match video segment:
for text, start, end in transcriptions:
    # Adjust times relative to video start
    adjusted_start = start - video_start_time
    adjusted_end = end - video_start_time
    
    # Only include if within video duration
    if adjusted_end > 0 and adjusted_start < video_duration:
        adjusted_start = max(0, adjusted_start)
        adjusted_end = min(video_duration, adjusted_end)
        relevant_transcriptions.append([text.strip(), adjusted_start, adjusted_end])
Example: For a video cropped from 45s to 165s:
  • Original transcription: ["Hello", 50.0, 52.5]
  • Adjusted for video: ["Hello", 5.0, 7.5]

Dynamic Font Scaling

Subtitles automatically scale to video resolution:
# Font size is 6.5% of video height
dynamic_fontsize = int(video.h * 0.065)

# Examples:
# 1080p (1920x1080) → 70px
# 720p (1280x720)  → 47px
# 480p (854x480)   → 31px

Text Wrapping

Automatic text wrapping for long subtitles:
TextClip(
    text,
    method='caption',
    size=(video.w - 100, None)  # Width constraint, auto height
)

Empty Segment Handling

If no transcriptions match the video segment:
if not relevant_transcriptions:
    print("No transcriptions found for this video segment")
    # Output video without subtitles
    video.write_videofile(output_video, codec='libx264', audio_codec='aac')
    return

Output Specifications

  • Video Codec: libx264 (H.264)
  • Audio Codec: AAC
  • FPS: Preserves original video frame rate
  • Preset: medium (balanced speed/quality)
  • Bitrate: 3000k

Subtitle Appearance

  • Text Color: #2699ff (bright blue)
  • Stroke Color: black
  • Stroke Width: 2px
  • High contrast for readability on any background

Example Output

# Console output during processing
Adding 24 subtitle segments to video...
Moviepy - Building video __temp__.mp4.
Moviepy - Writing video __temp__.mp4
t: 100%|████████████████████| 3600/3600 [00:45<00:00, 79.41it/s]
Moviepy - Done !
✓ Subtitles added successfully -> output_with_subs.mp4

Visual Example

┌─────────────────────┐
│                     │
│   Video Content     │
│                     │
│                     │
├─────────────────────┤  ← 100px from bottom
│  Today we'll be     │  ← Subtitle text
│  discussing AI      │     (auto-wrapped)
└─────────────────────┘
   ↑50px margins↑
The function automatically handles videos without audio by preserving the video track and adding a silent audio track if needed.
Requires MoviePy and ImageMagick. The font ‘Franklin-Gothic’ must be available on the system, or MoviePy will fall back to a default font.

Performance

  • Processing Time: ~30-60 seconds per minute of video
  • Memory Usage: Proportional to video resolution
  • Text Rendering: Uses ImageMagick for high-quality text

Error Handling

try:
    add_subtitles_to_video(input_video, output_video, transcriptions)
except Exception as e:
    print(f"Error adding subtitles: {e}")
    # Common issues:
    # - Missing ImageMagick installation
    # - Font not found
    # - Invalid transcription format
    # - Video file read/write errors

Font Installation

If Franklin-Gothic is not available:
# Linux (Debian/Ubuntu)
sudo apt-get install msttcorefonts

# Mac
brew install --cask font-franklin-gothic

# Windows
# Usually pre-installed, or download from Microsoft Typography

Build docs developers (and LLMs) love