Advanced SubStation Alpha python library
Easy macro commands for modifying .ass files
view on
github

ass.py

ass.py is a python library that handles (Advanced) SubStation Alpha subtitle files. Its functionality includes reading, writing, and editing of subtitle lines.

Its public interface provides several macro commands, and also allows for more fine-grain editing of specific lines, styles, and metadata.

Required software

  • python – versions 2.x or 3.x should both work

Download

Documentation

ass.py's usage paradigm is designed to make it quick and easy to use, with method design similar to that of jQuery. That is, a single command provides many options for what and how it should perform, and multiple commands can be chained easily.

The extended descriptions are minimized by default for ease of locating functions by name. Click the +/ or the function name to expand/shrink the description. (expand all | shrink all)

Module members

The following members are accessable at the module level:

  • version_info
    A tuple containing the version number information. For example, (1, 0) represents version "1.0". The length of this array is arbitrary and subject to change.
  • ASS
    The main class which contains all the useful methods. Methods and members of ASS are described below.

ASS

The ASS class contains values, methods, and classes related to subtitle file data. When instantiated, it represents a subtitles file which can then be modified.

Class members

The following are constants defined on the ASS class:

  • ASS.=1,
    ASS.=2,
    ASS.=3,
    ASS.=4,
    ASS.=5,
    ASS.=6,
    ASS.=7,
    ASS.=8,
    ASS.=9
    Constants representing the alignment of an event or style. Their names are self explanatory.

Class methods

The following are @classmethods defined on the ASS class:

  • ASS.(text, modify_text=None, modify_special=None, modify_tag_block=None, modify_tag=None, modify_comment=None, modify_geometry=None...) : string
    Modifies an ASS formatted event by the different types of parts found within it.
    return : string
    A modified version of the input text after having any specified modification functions performed on it
    text : string
    A formatted subtitle line string to modify
    modify_text : function
    A function to modify strings of text. The function should perform the following:
    modified_text = modify_text(original_text);
    modify_special : function
    A function to modify groupless tags (\h, \n, \N). The function should perform the following:
    modified_text = modify_special(original_text);
    If left as None, these tags will be captured along with text using modify_text
    modify_tag_block : function
    A function to modify groups of tags, including {} brackets. The function should perform the following:
    modified_text = modify_tag_block(original_text);
    modify_tag : function
    A function to modify tags found inside {} brackets. The function should perform the following:
    array_of_tag_args = modify_tag(tag_args);
    tag_args – an array in the form [ tag_name, tag_arg1, tag_arg2, ... ]
    array_of_tag_args – an array of tag arguments in the same form as the tag_args.
    To perform no change on the input, a function could look like: (lambda tag: [ tag ])
    modify_comment : function
    A function to modify comments found inside {} brackets. The function should perform the following:
    modified_text = modify_comment(original_text);
    modify_geometry : function
    A function to modify geometry drawing commands that aren't found in {} brackets. The function should perform the following:
    modified_text = modify_geometry(original_text);
  • ASS.(text, modify_tag=None, modify_comment=None, next_geometry_scale=0...) : 2-tuple
    Modifies a block of tags that would normally be found inside {} brackets.
    return : 2-tuple
    The first entry of the return tuple is the modified input text.
    The second entry is the number of the last \p# tag found, or next_geometry_scale if none are found.
    text : string
    The string of tags to modify, not including {} brackets
    next_geometry_scale : any
    The default value of the second entry in the return tuple
  • ASS.(text, space=' ', min_whitespace_length=1, max_whitespace_length=1...) : string
    Replaces special text escape codes (\h, \n, \N) with space. If the length of the new space and surrounding whitespace is outside the range [min_whitespace_length, max_whitespace_length], the total whitespace is replace with a single space.
    return : string
    A modified version of the input text
    space : string
    The character/string to use as a replacement
    min_whitespace_length : integer
    The minimum length a new group of whitespace can be before being replaced by a single space
    max_whitespace_length : integer
    The maximum length a new group of whitespace can be before being replaced by a single space
  • ASS.(event, deep=True...) : number
    Get the alignment value of an ASS.Event instance.
    return : number
    The alignment constant value of event
    event : ASS.Event
    An instance of a ASS.Event to check
    deep : boolean
    If True, the events's text are checked for any alignment tags
  • ASS.(align...) : 2-tuple
    Converts an alignment constant to its horizontal and vertical components
    return : 2-tuple
    A tuple containing the horizontal and vertical components. First entry is the horizontal component, and the second is the vertical.
    align : integer
    The alignment constant to convert

Instance members

The following are members of instances of the ASS class. Not all of them should be modified directly.

  • ASS. : list
    A list of ASS.Info instances in the order they will be written to an output file. This list can be modified so long as nothing is added or removed; i.e., it can be re-arranged or sorted.
  • ASS. : dict
    A dict of info keys to ASS.Info instances. Used for easier and faster access to script info settings. Values in this dict can be modified, but values should not be manually added or deleted.
  • ASS. : list
    A list containing the format ordering and naming of styles to be used when outputting an .ass file.
  • ASS. : list
    A list of ASS.Style instances which may be in use by the instance.
  • ASS. : list
    A list containing the format ordering and naming of events to be used when outputting an .ass file.
  • ASS. : list
    A list of ASS.Event instances representing all of the events in the file.

Instance methods

The following are methods performable on instances of the ASS class:

  • () : instance
    Create a new instance. The instance will be empty, including the format order descriptors.
    return : instance
    A new instance of the ASS class
  • ASS.(filename...) : self
    Read an .ass file into the object, clearing all previous data in the process.
    return : self
    The return value is the instance the method was performed on
    filename : string
    The name of the .ass subtitles file to read in
  • ASS.(filename, comments=None...) : self
    Write the subtitles to an Advanced SubStation Alpha formatted file.
    return : self
    The return value is the instance the method was performed on
    filename : string
    The name of the file to write .ass subtitles to
    comments : None | list
    A list of comments to be added in the script info. If left as None, a single comment will be added indicating script was generated by ass.py.
  • ASS.(filename, overlap=True, newlines=False, remove_identical=True, join=True, filter_function=None...) : self
    Write the subtitles to a SubRip formatted file. This currently does not support formatting; as such, formatting/formatted lines may be removed.
    return : self
    The return value is the instance the method was performed on
    filename : string
    The name of the file to write .srt subtitles to
    overlap : boolean
    If True, overlapping timecodes are unchanged.
    If False, overlapping time codes are merged into groups of concurrent times.
    overlap=False is useful for things which don't support overlapping timecodes, such as YouTube.
    newlines : boolean
    If True, .ass newlines (\n, \N) are preserved.
    If False, newlines are replaced with spaces.
    remove_identical : boolean
    If True, identical lines (after removing formatting tags) are removed.
    If False, they are not removed.
    join : boolean
    If True, identical sequential lines are joined into a single line.
    If False, they are not joined.
    filter_function : None | function
    If not None, this is a function that specifies to modify or remove subtitle lines.
    The function takes two inputs: an ASS.Event instance and its formatted text.
    The function should return the (modified) text string, or None if the line should be removed.
  • ASS.(alias=False...) : self
    Updates the format keys and ordering of events
    return : self
    The return value is the instance the method was performed on
    alias : boolean
    Does nothing since there are no alternate spellings; kept for consistency with ASS.reformat_styles
  • ASS.(alias=False...) : self
    Updates the format keys and ordering of styles
    return : self
    The return value is the instance the method was performed on
    alias : boolean
    If True, the spelling "color" is used in format lists.
    If False, the spelling "colour" is used.
  • ASS.(event...) : self
    Adds a new event to the list of events
    return : self
    The return value is the instance the method was performed on
    event : ASS.Event instance
    The event to add
  • ASS.(style...) : self
    Adds a new style to the list of styles
    return : self
    The return value is the instance the method was performed on
    style : ASS.Style instance
    The style to add
  • ASS.(sort=False, join=False, join_naive=False, remove_unseen=True, snap_start=0.0, snap_end=0.0, snap_together=0.0...) : self
    Perform organization actions on the events of an ASS instance.
    return : self
    The return value is the instance the method was performed on
    sort : boolean
    If True, events are sorted by starting timecode
    join : boolean
    If True, sequential events that would appear as one are joined into a single event
    join_naive : boolean
    If True, event joining will ignore any animated tags and join them anyway
    remove_unseen : boolean
    If True, events with Start >= End will be removed since they will not be visible
    snap_start : float
    Starting timecodes within the specified amount of seconds will be snapped to the same timecode (of the first event)
    snap_end : float
    Ending timecodes within the specified amount of seconds will be snapped to the same timecode (of the first event)
    snap_together : float
    Starting/ending timecodes within the specified amount of seconds will be snapped to the same timecode (of the first event). Note that this only applies to a difference between a starting and ending timecode, and not start/start or end/end timecodes.
  • ASS.(sort=False, join=False, join_if_names_differ=False, rename=False, rename_function=None, remove_unused=False...) : self
    Perform organization actions on the styles of an ASS instance.
    return : self
    The return value is the instance the method was performed on
    sort : boolean
    If True, styles are sorted by name
    join : boolean
    If True, duplicate styles joined into a single style
    join_if_names_differ : boolean
    If True, duplicate styles that have different names are also joined
    rename : boolean
    If True, styles with identical names are renamed
    rename_function : function
    If not None, this function modifies the duplicate names. This is only called on duplicate named styles, and is called as:
    new_name = rename_function(old_name, index); # index starts at 0
    remove_unused : boolean
    If True, unused styles are removed
  • ASS.(start=None, end=None, full_inclusion=False, inverse=False, split=False, split_naive=False, filter_types=None, time_scale=1.0, time_scale_origin=0.0, time_offset=0.0, time_clip_start=None, time_clip_end=None, geometry_resolution=None, geometry_scale=None, geometry_scale_origin=(0.0, 0.0), geometry_offset=(0.0, 0.0), geometry_new_styles=True...) : self
    Shift and/or scale timecodes and/or geometry in a timecode range.
    The final equation for timecode modification is:
    tc = (tc - scale_origin) * scale + scale_origin + offset
    The final equation for geometry modification is:
    gx = (gx - scale_origin[0]) * scale[0] + scale_origin[0] + offset[0]
    gy = (gy - scale_origin[1]) * scale[1] + scale_origin[1] + offset[1]
    return : self
    The return value is the instance the method was performed on
    start : None | float
    Timecode to start at, or None for no lower bound
    end : None | float
    Timecode to start at, or None for no upper bound
    full_inclusion : boolean
    If True, event must be completely contained within specified timecode range; i.e.:
    event.Start >= start and event.End <= end
    If False, event must be partially contained within specified timecode range; i.e.:
    not (event.Start >= end or event.End <= start)
    inverse : boolean
    If True, the operation is performed on all events not contained in the timecode range
    split : boolean
    If True, timecodes that are partially contained in the timecode range are split into multiple events
    split_naive : boolean
    If True, timecode splitting ignores any animation tags in the text and naïvely copies the original text.
    If False, animation tags are properly split. (not implemented yet)
    filter_types : list | dict | ...
    An object used to filter certain types of events out, such as comments. Can be any object supporting the in operator.
    If None, no filtering is performed; else, events satisfying event.type in filter_types are included.
    time_scale : float
    The value by which timecodes will be scaled
    time_scale_origin : float
    The center time at which timecodes are scaled around
    time_offset : float
    The value which will be added to timecodes
    time_clip_start : None | float
    Starting cutoff timecode, or None for no lower bound. Applied after new timecodes are computed.
    time_clip_end : None | float
    Ending cutoff timecode, or None for no lower bound. Applied after new timecodes are computed.
    geometry_resolution : None | 2-tuple
    (width, height) tuple specifying the new resolution.
    If geometry_scale is not specified, all geometry values are scaled to the new resolution.
    If geometry_scale is specified, this acts as the new bounds for the subtitles.
    geometry_scale : None | 2-tuple
    (xscale, yscale) tuple specifying the values to scale geometry coordinates by.
    If left as None, no scaling is performed unless geometry_resolution is set.
    If the subtitle events are to retain their sizes, but the video size is to be changed, change geometry_resolution appropriately and set geometry_scale to (1, 1).
    geometry_scale_origin : 2-tuple
    (xcenter, ycenter) tuple specifying the coordinate at which geometry is scaled around
    geometry_offset : 2-tuple
    (xoffset, yoffset) tuple specifying values to be added to geometry coordinates
    geometry_new_styles : boolean
    If True, new styles will be generated for any changes in margins and geometric values.
    If False, margins and values will be updated inside their events.
  • ASS.(time=None, start=time, end=time, filter_types=None, length=None, count=None...) : self
    Extend a timecode to a range, or loop a range over a new range.
    At least one of (time, start, end) must be specified.
    return : self
    The return value is the instance the method was performed on
    time : None | float
    Timecode to loop, or None to use start and end instead
    start : None | float
    Timecode to start at, or None for the minimum timecode
    end : None | float
    Timecode to start at, or None for the maximum timecode
    filter_types : list | dict | ...
    An object used to filter certain types of events out, such as comments. Can be any object supporting the in operator.
    If None, no filtering is performed; else, events satisfying event.type in filter_types are included.
    length : None | float
    The new total length of time the section should be looped over. Must be greater than 0.
    count : None | float
    Number of times to loop the section in the specified range. If start == end, this value is ignored and length must be used. Must be greater than 0.
  • ASS.(start=None, end=None, full_inclusion=False, inverse=False, split=False, split_naive=False, filter_types=None, filter_function=None, remove=True, other=None...) : self
    Remove events from the ASS instance and/or copy them into another instance.
    return : self
    The return value is the instance the method was performed on
    start : None | float
    Timecode to start at, or None for no lower bound
    end : None | float
    Timecode to start at, or None for no upper bound
    full_inclusion : boolean
    If True, event must be completely contained within specified timecode range; i.e.:
    event.Start >= start and event.End <= end
    If False, event must be partially contained within specified timecode range; i.e.:
    not (event.Start >= end or event.End <= start)
    inverse : boolean
    If True, the operation is performed on all events not contained in the timecode range
    split : boolean
    If True, timecodes that are partially contained in the timecode range are split into multiple events
    split_naive : boolean
    If True, timecode splitting ignores any animation tags in the text and naïvely copies the original text.
    If False, animation tags are properly split. (not implemented yet)
    filter_types : list | dict | ...
    An object used to filter certain types of events out, such as comments. Can be any object supporting the in operator.
    If None, no filtering is performed; else, events satisfying event.type in filter_types are included.
    filter_function : None | function
    If None, no additional filtering is performed. Else, this function takes an ASS.Event instance as an input and should return a boolean value: True if it should be processed for extraction, False to skip; i.e.:
    process_event = filter_function(event);
    remove : boolean
    If True, events are removed from self; otherwise they are kept
    other : None | ASS instance
    If not None, events are removed/copied into this object
  • ASS.(filter_types=None, remove=True, other=None, time_offset=0.0...) : self
    Merge or copy events from one instance into another.
    return : self
    The return value is the instance the method was performed on
    filter_types : list | dict | ...
    An object used to filter certain types of events out, such as comments. Can be any object supporting the in operator.
    If None, no filtering is performed; else, events satisfying event.type in filter_types are included.
    remove : boolean
    If True, events are removed from the other object; otherwise they are copied.
    other : ASS instance
    Events are copied from this object into the self object
    time_offset : float
    A time by which to offset all added timecodes
  • ASS.(start=None, end=None, full_inclusion=False, inverse=False, split=False, split_naive=False, filter_types=None, tags=True, comments=True, geometry=True, special=False...) : self
    return : self
    The return value is the instance the method was performed on
    start : None | float
    Timecode to start at, or None for no lower bound
    end : None | float
    Timecode to start at, or None for no upper bound
    full_inclusion : boolean
    If True, event must be completely contained within specified timecode range; i.e.:
    event.Start >= start and event.End <= end
    If False, event must be partially contained within specified timecode range; i.e.:
    not (event.Start >= end or event.End <= start)
    inverse : boolean
    If True, the operation is performed on all events not contained in the timecode range
    split : boolean
    If True, timecodes that are partially contained in the timecode range are split into multiple events
    split_naive : boolean
    If True, timecode splitting ignores any animation tags in the text and naïvely copies the original text.
    If False, animation tags are properly split. (not implemented yet)
    filter_types : list | dict | ...
    An object used to filter certain types of events out, such as comments. Can be any object supporting the in operator.
    If None, no filtering is performed; else, events satisfying event.type in filter_types are included.
    tags : boolean
    If True, groups of tags are removed (along with any relevant drawing commands)
    comments : boolean
    If True, comments are removed
    geometry : boolean
    If True, geometry drawing commands (outside of tag groups) are removed
    special : boolean
    If True, groupless tags (\h, \n, \N) are replaced with whitespace
  • ASS.() : 2-tuple
    Get the resolution of a subtitles file.
    return : 2-tuple
    A (width, height) tuple of the resolution. Returns (0, 0) if the resolution could not be detected.

ASS.Formatters

Members of this class are primarily used internally for decoding/encoding subtitle file information, but a few methods can also be useful externally:

Class methods

  • Formatters.(timecode, decimal_length=2, seconds_length=2, minutes_length=2, hours_length=1...) : string
    Takes a timecode as a float and converts it into a string.
    return : string
    A string representation of the input timecode
    timecode : float
    A time in seconds
    decimal_length : integer
    Number of digits after the decimal indicator
    seconds_length : integer
    Minimum number of digits used to represent the integer part of the seconds
    minutes_length : integer
    Minimum number of digits used to represent the number minutes
    hours_length : integer
    Minimum number of digits used to represent the number of hours
  • Formatters.(val...) : float
    Takes a timecode as a string and converts it into a float.
    return : float
    A floating point representation of the input timecode, in seconds
    val : string
    A string formatted timecode. The following are acceptable formats:
    (the number of digits for each part doesn't matter)
    S.SSS
    MM:SS.SSS
    H:MM:SS.SSS

ASS.Info

An instance of ASS.Info represents a line found in the [Script Info] section of an .ass file. It should be obvious what the key and value members refer to.

Instance members

  • Info. : string
    The key of the entry
  • Info. : string
    The value of the entry

ASS.Style

This class contains info about a certain style found in a subtitles file. Data is loaded from the [V4+ Styles] section of a file.

Instance members

  • Event. : string
    The type of style; typically "Style".
  • Event. : boolean
    True if the style name could not be resolved when loading; False if it's a valid style.
  • Style. : string
    The name of the style
  • Style. : string
    The name of the font used
  • Style. : float
    The size of the font
  • Style. : 4-tuple
    The primary color for text, represented as a tuple of (R, G, B, A).
    RGBA values range from 0 - 255 inclusive. For alpha, 255 is opaque and 0 is transparent.
  • Style. : 4-tuple
    The secondary (karaoke) color for text, represented as a tuple of (R, G, B, A).
    RGBA values range from 0 - 255 inclusive. For alpha, 255 is opaque and 0 is transparent.
  • Style. : 4-tuple
    The outline color for text, represented as a tuple of (R, G, B, A).
    RGBA values range from 0 - 255 inclusive. For alpha, 255 is opaque and 0 is transparent.
  • Style. : 4-tuple
    The shadow color for text, represented as a tuple of (R, G, B, A).
    RGBA values range from 0 - 255 inclusive. For alpha, 255 is opaque and 0 is transparent.
  • Style. : boolean
    Whether or not the text should be bold
  • Style. : boolean
    Whether or not the text should be italic
  • Style. : boolean
    Whether or not the text should be underlined
  • Style. : boolean
    Whether or not the text should have a strikethrough
  • Style. : integer
    The horizontal scaling of the text, in percent. 100 is the normal value.
  • Style. : integer
    The vertical scaling of the text, in percent. 100 is the normal value.
  • Style. : integer
    Extra spacing used inbetween letters, in script pixels
  • Style. : float
    Rotation of the text, in counter-clockwise degrees
  • Style. : integer
    The style of the border. 1 = outline + drop shadow, 3 = opaque box.
  • Style. : integer
    The size of the outline around text, in script pixels
  • Style. : integer
    The offset of the shadow from the text, in script pixels
  • Style. : integer
    The alignment of the text. The value will be one of the alignment constants.
  • Style. : integer
    The left margin for text
  • Style. : integer
    The right margin for text
  • Style. : integer
    The vertical margin for text.
    If the alignment is to the top, this value is the top margin.
    If the alignment is to the bottom, this value is the bottom margin.
  • Style. : integer
    The font character set or encoding; this value is usually 0.

Instance methods

  • () : instance
    Create a new instance. The instance will contain all default values.
    return : instance
    A new instance of the Style class
  • Style.(other=None...) : ASS.Style
    Copys one instance to another
    return : ASS.Style
    If other was None, a copy of self is returned.
    If other was not None, self is returned.
    other : None | ASS.Style
    If None, self is copied into a new instance and that instance is returned.
    Otherwise, values from other are copied into self. (self is modified, not other)
  • Style.(other...) : boolean
    Compares all the members of two instances
    return : boolean
    Returns True if they match, False otherwise
    other : ASS.Style
    The second instance to compare against

ASS.Event

This class represents a single event found in a subtitles file. Data is loaded from the [Events] section of a file.

Instance members

  • Event. : string
    The type of event; typically "Comment" or "Dialogue".
  • Event. : integer
    The layer the event is on
  • Event. : float
    The starting timecode for the event
  • Event. : float
    The ending timecode for the event
  • Event. : ASS.Style
    The style instance for the event; this instance is shared among multiple Event objects.
  • Event. : string
    The name of the character speaking
  • Event. : integer
    The left margin for text
  • Event. : integer
    The right margin for text
  • Event. : integer
    The vertical margin for text.
    If the alignment is to the top, this value is the top margin.
    If the alignment is to the bottom, this value is the bottom margin.
  • Event. : string
    The contents of the event; typically a subtitle line

Instance methods

  • () : instance
    Create a new instance. The instance will contain all default values.
    return : instance
    A new instance of the Event class
  • Event.(other=None...) : ASS.Event
    Copys one instance to another
    return : ASS.Event
    If other was None, a copy of self is returned.
    If other was not None, self is returned.
    other : None | ASS.Event
    If None, self is copied into a new instance and that instance is returned.
    Otherwise, values from other are copied into self. (self is modified, not other)
  • Event.(other...) : boolean
    Compares all the members of two instances
    return : boolean
    Returns True if they match, False otherwise
    other : ASS.Event
    The second instance to compare against
  • Event.(other...) : boolean
    Compares the styles of event to another. Basically the same as equals, except it ignores timecodes and text differences.
    return : boolean
    Returns True if they match, False otherwise
    other : ASS.Event
    The second instance to compare against