CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pysrt

SubRip (.srt) subtitle parser and writer for Python

Pending
Overview
Eval results
Files

subtitle-items.mddocs/

Subtitle Items

Individual subtitle manipulation through the SubRipItem class. Each subtitle item contains timing information, text content, positioning data, and supports various text processing and timing operations.

Capabilities

Item Creation

Create subtitle items from various sources and formats.

class SubRipItem:
    def __init__(self, index=0, start=None, end=None, text='', position=''):
        """
        Create a new subtitle item.
        
        Args:
            index (int): Subtitle sequence number (default: 0)
            start: Start time (SubRipTime or coercible, default: 0)
            end: End time (SubRipTime or coercible, default: 0) 
            text (str): Subtitle text content (default: '')
            position (str): Display position/coordinates (default: '')
        """

    @classmethod
    def from_string(cls, source):
        """
        Parse subtitle item from string representation.
        
        Args:
            source (str): Complete subtitle item in SRT format
            
        Returns:
            SubRipItem: Parsed subtitle item
        """
        
    @classmethod  
    def from_lines(cls, lines):
        """
        Parse subtitle item from list of lines.
        
        Args:
            lines (list): List of strings representing subtitle lines
            
        Returns:
            SubRipItem: Parsed subtitle item
        """
        
    @classmethod
    def split_timestamps(cls, line):
        """
        Split timestamp line into start time, end time, and position.
        
        Args:
            line (str): Timestamp line (e.g., "00:00:01,500 --> 00:00:05,000")
            
        Returns:
            tuple: (start_time_str, end_time_str, position_str)
        """

Properties

Access and modify subtitle item properties.

@property
def index(self):
    """
    Subtitle sequence number.
    
    Returns:
        int: Index number in subtitle sequence
    """

@property
def start(self):
    """
    Start time of subtitle.
    
    Returns:
        SubRipTime: Start timestamp
    """

@property
def end(self):
    """
    End time of subtitle.
    
    Returns:
        SubRipTime: End timestamp  
    """

@property
def text(self):
    """
    Subtitle text content.
    
    Returns:
        str: Text content with formatting tags
    """

@property
def position(self):
    """
    Display position/coordinates string.
    
    Returns:
        str: Position specification (e.g., "X1:40 X2:600 Y1:20 Y2:50")
    """

@property
def duration(self):
    """
    Duration of subtitle (computed as end - start).
    
    Returns:
        SubRipTime: Duration of subtitle display
    """

@property
def text_without_tags(self):
    """
    Text content with HTML/formatting tags removed.
    
    Returns:
        str: Plain text without markup tags
    """

@property
def characters_per_second(self):
    """
    Reading speed metric based on character count and duration.
    
    Returns:
        float: Characters per second (0.0 if duration is zero)
    """

Timing Operations

Modify subtitle timing and perform time-based calculations.

def shift(self, *args, **kwargs):
    """
    Adjust start and end times by offset or ratio.
    
    Args:
        *args: Positional time arguments (hours, minutes, seconds, milliseconds)
        **kwargs: Named time arguments or ratio for proportional scaling
        
    Supported kwargs:
        hours (int): Hours to add
        minutes (int): Minutes to add
        seconds (int): Seconds to add  
        milliseconds (int): Milliseconds to add
        ratio (float): Multiply times by this ratio
    """

String Representation

Convert subtitle items to various string formats.

def __str__(self):
    """
    Convert to standard SRT format string.
    
    Returns:
        str: Complete subtitle item in SRT format
    """

Comparison Support

SubRipItem supports comparison operations based on timing.

# Comparison operators based on start time, then end time
item1 < item2      # item1 starts before item2
item1 <= item2     # item1 starts before or at same time as item2  
item1 == item2     # item1 and item2 have same timing
item1 >= item2     # item1 starts at or after item2
item1 > item2      # item1 starts after item2
item1 != item2     # item1 and item2 have different timing

Usage Examples

Creating Subtitle Items

import pysrt

# Create from scratch
item = pysrt.SubRipItem(
    index=1,
    start=pysrt.SubRipTime(0, 0, 1, 500),  # 00:00:01,500
    end=pysrt.SubRipTime(0, 0, 5, 0),      # 00:00:05,000
    text="Hello, World!"
)

# Create with position information
positioned_item = pysrt.SubRipItem(
    index=2,
    start={'seconds': 6}, 
    end={'seconds': 10},
    text="Bottom right text",
    position="X1:400 X2:600 Y1:300 Y2:350"
)

# Parse from string
srt_text = """1
00:00:01,500 --> 00:00:05,000
Hello, World!"""
item = pysrt.SubRipItem.from_string(srt_text)

Text Processing

# Working with formatted text
item.text = "<i>Italic text</i> and <b>bold text</b>"
plain_text = item.text_without_tags  # "Italic text and bold text"

# Multi-line subtitles
item.text = "First line\nSecond line\nThird line"

# Reading analysis
print(f"Reading speed: {item.characters_per_second:.2f} chars/sec")

Timing Operations

# Adjust timing
item.shift(seconds=2)                    # Delay by 2 seconds
item.shift(milliseconds=-500)            # Advance by 0.5 seconds
item.shift(ratio=1.1)                    # Speed up by 10%

# Duration calculations  
print(f"Duration: {item.duration}")      # Show how long subtitle displays
print(f"Start: {item.start}")           # Show start time
print(f"End: {item.end}")               # Show end time

# Create item with specific duration
start_time = pysrt.SubRipTime(minutes=1)
duration = pysrt.SubRipTime(seconds=3, milliseconds=500)
item = pysrt.SubRipItem(
    start=start_time,
    end=start_time + duration,
    text="3.5 second subtitle"
)

Item Modification

# Load and modify existing subtitles
subs = pysrt.open('movie.srt')

for item in subs:
    # Uppercase all text
    item.text = item.text.upper()
    
    # Add prefix to all subtitles
    item.text = f"[MOVIE] {item.text}"
    
    # Remove HTML tags
    if '<' in item.text:
        item.text = item.text_without_tags
        
    # Extend short subtitles
    if item.duration.ordinal < 1000:  # Less than 1 second
        item.end += pysrt.SubRipTime(milliseconds=500)

subs.save('modified_movie.srt')

Sorting and Comparison

# Sort subtitles by timing
subtitle_list = [item3, item1, item2]  # Out of order
subtitle_list.sort()  # Now sorted by start time

# Find overlapping subtitles
for i, current in enumerate(subs[:-1]):
    next_item = subs[i + 1]
    if current.end > next_item.start:
        print(f"Overlap detected between items {current.index} and {next_item.index}")

# Filter by timing criteria
long_subtitles = [item for item in subs if item.duration.ordinal > 5000]  # > 5 seconds
short_subtitles = [item for item in subs if item.duration.ordinal < 1000]  # < 1 second

Advanced Text Processing

import re

# Remove specific formatting tags
def clean_tags(text):
    # Remove specific HTML tags but keep content
    text = re.sub(r'</?[bi]>', '', text)  # Remove bold/italic tags
    text = re.sub(r'<font[^>]*>', '', text)  # Remove font tags
    text = re.sub(r'</font>', '', text)
    return text

# Process all subtitles
for item in subs:
    # Clean formatting
    item.text = clean_tags(item.text)
    
    # Fix common encoding issues
    item.text = item.text.replace('’', "'")  # Fix apostrophes
    item.text = item.text.replace('“', '"')  # Fix quotes
    item.text = item.text.replace(' ', '"')
    
    # Break long lines
    if len(item.text) > 50 and '\n' not in item.text:
        words = item.text.split(' ')
        mid = len(words) // 2
        item.text = ' '.join(words[:mid]) + '\n' + ' '.join(words[mid:])

Positioning and Display

# Create subtitles with specific positioning
top_subtitle = pysrt.SubRipItem(
    start={'seconds': 10},
    end={'seconds': 15}, 
    text="Top of screen",
    position="Y1:50 Y2:100"  # Top positioning
)

bottom_subtitle = pysrt.SubRipItem(
    start={'seconds': 10},
    end={'seconds': 15},
    text="Bottom of screen", 
    position="Y1:400 Y2:450"  # Bottom positioning
)

# Multiple simultaneous subtitles (different positions)
subs = pysrt.SubRipFile()
subs.append(top_subtitle)
subs.append(bottom_subtitle)
subs.save('positioned_subtitles.srt')

Install with Tessl CLI

npx tessl i tessl/pypi-pysrt

docs

command-line.md

index.md

subtitle-files.md

subtitle-items.md

time-handling.md

tile.json