Пример #1
0
def shift(input_file, output_file, shift_by, shift_start, shift_end,
          multiplier):
    """Shift all lines in a script by defined amount and/or change speed.

    \b
    You can use one of the following formats to specify the time for shift:
        - "1.5s" or just "1.5" means 1 second 500 milliseconds
        - "150ms" means 150 milliseconds
        - "1:7:12.55" means 1 hour, 7 minutes, 12 seconds and 550 milliseconds. All parts are optional.
    Every format allows a negative sign before the value, which means "shift back", like "-12s"

    \b
    Optionally, specify multiplier to change speed:
        - 1.2 makes subs 20% faster
        - 7/8 makes subs 12.5% slower

    \b
    To shift both start end end time by one minute and 15 seconds:
    $ prass shift input.ass --by 1:15 -o output.ass
    To shift only start time by half a second back:
    $ prass shift input.ass --start --by -0.5s -o output.ass
    """
    if not shift_start and not shift_end:
        shift_start = shift_end = True

    shift_ms = parse_shift_string(shift_by)
    multiplier = parse_fps_string(multiplier)
    if multiplier < 0:
        raise PrassError('Speed multiplier should be a positive number')
    script = AssScript.from_ass_stream(input_file)
    script.shift(shift_ms, shift_start, shift_end, multiplier)
    script.to_ass_stream(output_file)
Пример #2
0
def copy_styles(dst_file, src_file, output_file, clean, resample, forced_resolution):
    """Copy styles from one ASS script to another, write the result as a third script.
    You always have to provide the "from" argument, "to" defaults to stdin and "output" defaults to stdout.

    \b
    Simple usage:
    $ prass copy-styles --from template.ass --to unstyled.ass -o styled.ass
    With pipes:
    $ cat unstyled.ass | prass copy-styles --from template.ass | prass cleanup --comments -o out.ass
    """
    src_script = AssScript.from_ass_stream(src_file)
    dst_script = AssScript.from_ass_stream(dst_file)
    if forced_resolution:
        forced_resolution = parse_resolution_string(forced_resolution)

    dst_script.append_styles(src_script, clean, resample, forced_resolution)
    dst_script.to_ass_stream(output_file)
Пример #3
0
def copy_styles(dst_file, src_file, output_file, clean, resample, forced_resolution):
    """Copy styles from one ASS script to another, write the result as a third script.
    You always have to provide the "from" argument, "to" defaults to stdin and "output" defaults to stdout.

    \b
    Simple usage:
    $ prass copy-styles --from template.ass --to unstyled.ass -o styled.ass
    With pipes:
    $ cat unstyled.ass | prass copy-styles --from template.ass | prass cleanup --comments -o out.ass
    """
    src_script = AssScript.from_ass_stream(src_file)
    dst_script = AssScript.from_ass_stream(dst_file)
    if forced_resolution:
        forced_resolution = parse_resolution_string(forced_resolution)

    dst_script.append_styles(src_script, clean, resample, forced_resolution)
    dst_script.to_ass_stream(output_file)
Пример #4
0
def tpp(input_file, output_file, styles, lead_in, lead_out, max_overlap,
        max_gap, adjacent_bias, keyframes_path, timecodes_path, fps,
        kf_before_start, kf_after_start, kf_before_end, kf_after_end):
    """Timing post-processor.
    It's a pretty straightforward port from Aegisub so you should be familiar with it.
    You have to specify keyframes and timecodes (either as a CFR value or a timecodes file) if you want keyframe snapping.
    All parameters default to zero so if you don't want something - just don't put it in the command line.

    \b
    To add lead-in and lead-out:
    $ prass tpp input.ass --lead-in 50 --lead-out 150 -o output.ass
    To make adjacent lines continuous, with 80% bias to changing end time of the first line:
    $ prass tpp input.ass --overlap 50 --gap 200 --bias 80 -o output.ass
    To snap events to keyframes without a timecodes file:
    $ prass tpp input.ass --keyframes kfs.txt --fps 23.976 --kf-before-end 150 --kf-after-end 150 --kf-before-start 150 --kf-after-start 150 -o output.ass
    """

    if fps and timecodes_path:
        raise PrassError(
            'Timecodes file and fps cannot be specified at the same time')
    if fps:
        timecodes = Timecodes.cfr(parse_fps_string(fps))
    elif timecodes_path:
        timecodes = Timecodes.from_file(timecodes_path)
    elif any((kf_before_start, kf_after_start, kf_before_end, kf_after_end)):
        raise PrassError(
            'You have to provide either fps or timecodes file for keyframes processing'
        )
    else:
        timecodes = None

    if timecodes and not keyframes_path:
        raise PrassError(
            'You have to specify keyframes file for keyframes processing')

    keyframes_list = parse_keyframes(
        keyframes_path) if keyframes_path else None

    actual_styles = []
    for style in styles:
        actual_styles.extend(x.strip() for x in style.split(','))

    script = AssScript.from_ass_stream(input_file)
    script.tpp(actual_styles, lead_in, lead_out, max_overlap, max_gap,
               adjacent_bias, keyframes_list, timecodes, kf_before_start,
               kf_after_start, kf_before_end, kf_after_end)
    script.to_ass_stream(output_file)
Пример #5
0
def cleanup(input_file, output_file, drop_comments, drop_empty_lines, drop_unused_styles,
            drop_actors, drop_effects, drop_spacing, drop_sections):
    """Remove junk data from ASS script

    \b
    To remove commented and empty lines plus clear unused styles:
    $ prass cleanup input.ass --comments --empty-lines --styles output.ass
    """
    sections_map = {
        "fonts": "[Fonts]",
        "graphics": "[Graphics]",
        "aegi": "[Aegisub Project Garbage]",
        "extradata": "[Aegisub Extradata]"
    }
    drop_sections = [sections_map[x] for x in drop_sections]

    script = AssScript.from_ass_stream(input_file)
    script.cleanup(drop_comments, drop_empty_lines, drop_unused_styles, drop_actors, drop_effects, drop_spacing, drop_sections)
    script.to_ass_stream(output_file)
Пример #6
0
def cleanup(input_file, output_file, drop_comments, drop_empty_lines, drop_unused_styles,
            drop_actors, drop_effects, drop_spacing, drop_sections):
    """Remove junk data from ASS script

    \b
    To remove commented and empty lines plus clear unused styles:
    $ prass cleanup input.ass --comments --empty-lines --styles output.ass
    """
    sections_map = {
        "fonts": "[Fonts]",
        "graphics": "[Graphics]",
        "aegi": "[Aegisub Project Garbage]",
        "extradata": "[Aegisub Extradata]"
    }
    drop_sections = [sections_map[x] for x in drop_sections]

    script = AssScript.from_ass_stream(input_file)
    script.cleanup(drop_comments, drop_empty_lines, drop_unused_styles, drop_actors, drop_effects, drop_spacing, drop_sections)
    script.to_ass_stream(output_file)
Пример #7
0
def tpp(input_file, output_file, styles, lead_in, lead_out, max_overlap, max_gap, adjacent_bias,
        keyframes_path, timecodes_path, fps, kf_before_start, kf_after_start, kf_before_end, kf_after_end):
    """Timing post-processor.
    It's a pretty straightforward port from Aegisub so you should be familiar with it.
    You have to specify keyframes and timecodes (either as a CFR value or a timecodes file) if you want keyframe snapping.
    All parameters default to zero so if you don't want something - just don't put it in the command line.

    \b
    To add lead-in and lead-out:
    $ prass tpp input.ass --lead-in 50 --lead-out 150 -o output.ass
    To make adjacent lines continuous, with 80% bias to changing end time of the first line:
    $ prass tpp input.ass --overlap 50 --gap 200 --bias 80 -o output.ass
    To snap events to keyframes without a timecodes file:
    $ prass tpp input.ass --keyframes kfs.txt --fps 23.976 --kf-before-end 150 --kf-after-end 150 --kf-before-start 150 --kf-after-start 150 -o output.ass
    """

    if fps and timecodes_path:
        raise PrassError('Timecodes file and fps cannot be specified at the same time')
    if fps:
        timecodes = Timecodes.cfr(parse_fps_string(fps))
    elif timecodes_path:
        timecodes = Timecodes.from_file(timecodes_path)
    elif any((kf_before_start, kf_after_start, kf_before_end, kf_after_end)):
        raise PrassError('You have to provide either fps or timecodes file for keyframes processing')
    else:
        timecodes = None

    if timecodes and not keyframes_path:
        raise PrassError('You have to specify keyframes file for keyframes processing')

    keyframes_list = parse_keyframes(keyframes_path) if keyframes_path else None

    actual_styles = []
    for style in styles:
        actual_styles.extend(x.strip() for x in style.split(','))

    script = AssScript.from_ass_stream(input_file)
    script.tpp(actual_styles, lead_in, lead_out, max_overlap, max_gap, adjacent_bias,
               keyframes_list, timecodes, kf_before_start, kf_after_start, kf_before_end, kf_after_end)
    script.to_ass_stream(output_file)
Пример #8
0
def sort_script(input_file, output_file, sort_by, descending):
    """Sort script by one or more parameters.

    \b
    Sorting by time:
    $ prass sort input.ass --by time -o output.ass
    Sorting by time and then by layer, both in descending order:
    $ prass sort input.ass --by time --by layer --desc -o output.ass

    """
    script = AssScript.from_ass_stream(input_file)
    attrs_map = {
        "start": "start",
        "time": "start",
        "end": "end",
        "style": "style",
        "actor": "actor",
        "effect": "effect",
        "layer": "layer"
    }
    getter = attrgetter(*[attrs_map[x] for x in sort_by])
    script.sort_events(getter, descending)
    script.to_ass_stream(output_file)
Пример #9
0
def shift(input_file, output_file, shift_by, shift_start, shift_end):
    """Shift all lines in a script by defined amount.

    \b
    You can use one of the following formats to specify the time:
        - "1.5s" or just "1.5" means 1 second 500 milliseconds
        - "150ms" means 150 milliseconds
        - "1:7:12.55" means 1 hour, 7 minutes, 12 seconds and 550 milliseconds. All parts are optional.
    Every format allows a negative sign before the value, which means "shift back", like "-12s"

    \b
    To shift both start end end time by one minute and 15 seconds:
    $ prass shift input.ass --by 1:15 -o output.ass
    To shift only start time by half a second back:
    $ prass shift input.ass --start --by -0.5s -o output.ass
    """
    if not shift_start and not shift_end:
        shift_start = shift_end = True

    shift_ms = parse_shift_string(shift_by)
    script = AssScript.from_ass_stream(input_file)
    script.shift(shift_ms, shift_start, shift_end)
    script.to_ass_stream(output_file)
Пример #10
0
def sort_script(input_file, output_file, sort_by, descending):
    """Sort script by one or more parameters.

    \b
    Sorting by time:
    $ prass sort input.ass --by time -o output.ass
    Sorting by time and then by layer, both in descending order:
    $ prass sort input.ass --by time --by layer --desc -o output.ass

    """
    script = AssScript.from_ass_stream(input_file)
    attrs_map = {
        "start": "start",
        "time": "start",
        "end": "end",
        "style": "style",
        "actor": "actor",
        "effect": "effect",
        "layer": "layer"
    }
    getter = attrgetter(*[attrs_map[x] for x in sort_by])
    script.sort_events(getter, descending)
    script.to_ass_stream(output_file)