Exemple #1
0
def test_r_named_tag():
    styles = {"other style": SSAStyle(bold=True)}
    text = "Hello, {\\rother style\\i1}world!"

    assert parse_tags(text, styles=styles) == \
        [("Hello, ", SSAStyle()),
         ("world!", SSAStyle(italic=True, bold=True))]
Exemple #2
0
def test_import_styles():
    red1 = SSAStyle()
    red2 = SSAStyle()
    green = SSAStyle()
    subs1 = SSAFile()
    subs2 = SSAFile()

    def prepare():
        subs1.styles = {}
        subs2.styles = {}
        subs1.styles["green"] = green
        subs1.styles["red"] = red1
        subs2.styles["red"] = red2

    prepare()
    subs2.import_styles(subs1)
    assert subs2.styles["green"] is green
    assert subs2.styles["red"] is red1

    prepare()
    subs2.import_styles(subs1, overwrite=False)
    assert subs2.styles["green"] is green
    assert subs2.styles["red"] is red2

    with assert_raises(TypeError):
        subs2.import_styles({})
Exemple #3
0
def test_rename_style():
    subs = SSAFile()
    red = SSAStyle()
    green = SSAStyle()

    def prepare():
        subs.events = [SSAEvent(style="red"), SSAEvent(style="unrelated")]
        subs.styles = dict(red=red, green=green)

    prepare()
    subs.rename_style("red", "blue")
    assert "red" not in subs.styles
    assert subs.styles["blue"] is red
    assert subs[0].style == "blue"
    assert subs[1].style == "unrelated"

    prepare()
    with assert_raises(ValueError):
        # cannot delete style via move
        subs.rename_style("red", "green")

    prepare()
    with assert_raises(ValueError):
        subs.rename_style("red", "illegal,name")
    with assert_raises(ValueError):
        subs.rename_style("red", "illegal\nname")
    with assert_raises(KeyError):
        subs.rename_style("nonexistent-style", "blue")
Exemple #4
0
def build_ref():
    subs = SSAFile()
    subs.info["My Custom Info"] = "Some: Test, String."
    subs.styles["left"] = SSAStyle(alignment=7, bold=True)
    subs.styles["topleft"] = SSAStyle(alignment=4)
    subs.append(SSAEvent(start=0, end=make_time(m=1), text="An, example, subtitle."))
    subs.append(SSAEvent(start=0, end=make_time(m=1), type="Comment", text="You can't see this one."))
    subs.append(SSAEvent(start=make_time(m=1), end=make_time(m=2), text="Subtitle number\\Ntwo."))
    return subs
Exemple #5
0
def test_repr_simple():
    subs = SSAFile()
    subs.append(SSAEvent(start=make_time(m=5), end=make_time(m=6)))
    subs.append(SSAEvent(start=make_time(m=125), end=make_time(m=126)))
    subs.append(SSAEvent(start=make_time(m=15), end=make_time(m=16)))
    subs.styles["style1"] = SSAStyle()
    subs.styles["style2"] = SSAStyle()
    ref = "<SSAFile with 3 events and 3 styles, last timestamp 2:06:00>"
    assert repr(subs) == ref
Exemple #6
0
def test_non_ascii_str_fields():
    # see issue #12
    STYLE_NAME = "my-style"
    FONT_NAME = b"NonAsciiString\xff"

    subs = SSAFile()
    line = SSAEvent(style=STYLE_NAME)
    subs.events.append(line)
    style = SSAStyle(fontname=FONT_NAME)
    subs.styles[STYLE_NAME] = style

    # in all Pythons, saving subtitles with non-unicode fields
    # fails when they are not in ASCII range
    with assert_raises(TypeError):
        subs.to_string("ass")
Exemple #7
0
def create_ssa_file():
    subs = SSAFile()
    subs.styles['top'] = SSAStyle(alignment=8)
    subs.styles['bottom'] = SSAStyle(alignment=2)
    subs.styles['left'] = SSAStyle(alignment=4)
    subs.styles['left_red'] = SSAStyle(alignment=4,
                                       primarycolor=Color(255, 0, 0, 0))
    subs.styles['red'] = SSAStyle(primarycolor=Color(255, 0, 0, 0))
    subs.styles['right'] = SSAStyle(alignment=6)
    return subs
Exemple #8
0
def test_write_read():
    subs = SSAFile()
    e1 = SSAEvent(text="Hello, world!")
    e2 = SSAEvent(text="The other subtitle.\\NWith two lines.",
                  style="custom style")
    s1 = SSAStyle(italic=True, primarycolor=Color(r=255, g=0, b=0, a=0))

    subs.append(e1)
    subs.append(e2)
    subs.styles["custom style"] = s1

    json_text = subs.to_string("json")

    subs2 = SSAFile.from_string(json_text, "json")

    assert subs2.equals(subs)
Exemple #9
0
def test_ascii_str_fields():
    # see issue #12
    STYLE_NAME = b"top-style"

    subs = SSAFile()
    line = SSAEvent(style=STYLE_NAME)
    subs.events.append(line)
    style = SSAStyle()
    subs.styles[STYLE_NAME] = style

    if sys.version_info.major == 2:
        # in Python 2, saving subtitles with non-unicode fields is tolerated
        # as long as they do not fall outside of ASCII range
        subs.to_string("ass")
    else:
        # in Python 3, we are strict and enforce Unicode
        with assert_raises(TypeError):
            subs.to_string("ass")
Exemple #10
0
def test_writer_tags():
    subs = SSAFile()
    subs.styles["italic_style"] = SSAStyle(italic=True)
    subs.events = [
        SSAEvent(start=0, end=10, text=r"Plain."),
        SSAEvent(start=0, end=10, text=r"{\i1}Inline."),
        SSAEvent(start=0, end=10, text=r"Styled.", style="italic_style"),
        SSAEvent(start=0,
                 end=10,
                 text=r"{\i1}Also{\i0} {\ritalic_style}italic."),
        SSAEvent(start=0, end=10, text=r"Not {\i1}italic.")
    ]

    f = dedent("""\
    {0}{0}1000
    {0}{10}Plain.
    {0}{10}{Y:i}Inline.
    {0}{10}{Y:i}Styled.
    {0}{10}{Y:i}Also italic.
    {0}{10}Not italic.
    """)

    assert subs.to_string("microdvd", 1000) == f
Exemple #11
0
import os

import pysubs2
from pysubs2 import SSAStyle
from zhconv import convert

DEFAULT_STYLE = SSAStyle(fontname='STKaiti', fontsize=18, outline=1, shadow=1)
OUTPUT_DIR = 'K:\\书包\\自制字幕'


def main():
    while (file := input('srt path: ')) != '':
        trans(file)


def trans(file):
    try:
        subs = pysubs2.load(file)
    except UnicodeDecodeError:
        try:
            subs = pysubs2.load(file, 'gbk')
        except UnicodeDecodeError:
            subs = pysubs2.load(file, 'utf-16')
    subs.styles['Default'] = DEFAULT_STYLE
    subs.info['PlayResX'] = '384'
    subs.info['PlayResY'] = '288'
    subs.info['ScaledBorderAndShadow'] = 'no'
    for line in subs:
        line.text = convert(line.text, 'zh-cn')
    subs.save(output_file(file))
Exemple #12
0
def test_r_tag():
    text = "{\\i1}Hello, {\\r}world!"
    assert parse_tags(text) == [("", SSAStyle()),
                                ("Hello, ", SSAStyle(italic=True)),
                                ("world!", SSAStyle())]
Exemple #13
0
def test_no_tags():
    text = "Hello, world!"
    assert parse_tags(text) == [(text, SSAStyle())]
Exemple #14
0
def test_repr_italic():
    ev = SSAStyle(fontname="Calibri", fontsize=36, italic=True)
    ref = "<SSAStyle 36px italic 'Calibri'>"
    assert repr(ev) == ref
Exemple #15
0
def test_repr_plain():
    ev = SSAStyle(fontname="Calibri", fontsize=36)
    ref = "<SSAStyle 36px 'Calibri'>"
    assert repr(ev) == ref
Exemple #16
0
def renderVideo(video, rendering_screen):
    global render_current_progress, render_max_progress, render_message
    t0 = datetime.datetime.now()

    clips = video.clips
    colour1 = getColour(video.colour1)
    colour2 = getColour(video.colour2)
    music_type = video.audio_cat

    subprocess._cleanup = lambda: None
    credits = []
    streamers_in_cred = []

    render_current_progress = 0
    # see where render_current_progress += 1

    amount = 0
    for clip in clips:
        if clip.isUsed:
            amount += 1

    render_max_progress = amount * 3 + 1 + 1
    render_message = "Beginning Rendering"
    rendering_screen.render_progress.emit()

    current_date = datetime.datetime.today().strftime("%m-%d-%Y__%H-%M-%S")
    fClips = []
    start_duration = 0
    end_duration = 0

    # render progress 1
    for i, clip in enumerate(clips):
        if clip.isUsed:
            name = clip.streamer_name
            mp4 = clip.mp4
            subs = SSAFile()

            if name is not None and name not in streamers_in_cred and not clip.isUpload:
                credits.append(
                    f"Streamer: {clip.streamer_name} Channel: {clip.channel_url}"
                )
                streamers_in_cred.append(clip.streamer_name)

            if clip.start_cut is None:
                clip.start_cut = 0

            if clip.end_cut is None:
                clip.end_cut = 0

            start_trim = round(clip.start_cut / 1000, 1)
            end_trim = round(clip.end_cut / 1000, 1)

            final_duration = round(clip.vid_duration - end_trim - start_trim,
                                   1)
            audio = clip.audio

            if name is None:
                name = ""

            render_message = f"Adding text ({i + 1}/{len(clips)})"
            rendering_screen.render_progress.emit()
            subs.styles['vidText'] = SSAStyle(alignment=7,
                                              fontname='Gilroy-ExtraBold',
                                              fontsize=25,
                                              marginl=4,
                                              marginv=-2.5,
                                              marginr=0,
                                              outline=2,
                                              outlinecolor=colour2,
                                              primarycolor=colour1,
                                              shadow=0)
            if settings.includeStreamerName:
                subs.append(
                    SSAEvent(start=make_time(s=0),
                             end=make_time(s=60),
                             style='vidText',
                             text=f"{name}"))
            subs.save(f'subtitleFile.ass')
            render_current_progress += 1
            render_message = f"Done Adding text ({i + 1}/{len(clips)})"
            rendering_screen.render_progress.emit()

            print(f"Adding text ({i + 1}/{len(clips)}) to video: {mp4}.mp4")

            render_message = f"Adding text to video ({i + 1}/{len(clips)})"
            rendering_screen.render_progress.emit()
            print(
                f"Rendering video ({i + 1}/{len(clips)}) to \"{settings.vid_finishedvids}\"/{mp4}_finished.mp4"
            )

            mp4name = mp4
            mp4path = f"{mp4}.mp4"

            if len(mp4.split("/")) > 2:
                name = len(mp4.split("/"))
                mp4name = mp4.split("/")[name - 1].replace(".mp4", "")
                mp4path = mp4[1:]

            if not clip.isInterval and not clip.isIntro:
                print("%s duration %s" % (mp4name, final_duration))
                if end_trim == 0 and start_trim == 0:
                    print("%s no trim" % mp4name)
                    os.system(
                        f"ffmpeg -y -fflags genpts -i \"{mp4path}\" -vf \"ass=subtitleFile.ass, scale=1920:1080\" \"{settings.vid_finishedvids}/{mp4name}_finished.mp4\""
                    )
                elif end_trim > 0 and start_trim > 0:
                    print("%s start trim %s and end trim %s" %
                          (mp4name, start_trim, end_trim))
                    os.system(
                        f"ffmpeg -y -fflags genpts -i \"{mp4path}\" -ss {start_trim} -t {final_duration} -vf \"ass=subtitleFile.ass, scale=1920:1080\" \"{settings.vid_finishedvids}/{mp4name}_finished.mp4\""
                    )
                elif end_trim > 0 and start_trim == 0:
                    print("%s end trim %s" % (mp4name, end_trim))

                    os.system(
                        f"ffmpeg -y -fflags genpts -i \"{mp4path}\" -t {clip.vid_duration - end_trim} -vf \"ass=subtitleFile.ass, scale=1920:1080\" \"{settings.vid_finishedvids}/{mp4name}_finished.mp4\""
                    )
                elif end_trim == 0 and start_trim > 0:
                    print("%s start trim %s" % (mp4name, start_trim))
                    os.system(
                        f"ffmpeg -y -fflags genpts -i \"{mp4path}\" -ss {start_trim} -vf \"ass=subtitleFile.ass, scale=1920:1080\" \"{settings.vid_finishedvids}/{mp4name}_finished.mp4\""
                    )

            render_current_progress += 1
            render_message = f"Done Adding text to video ({i + 1}/{len(clips)})"
            rendering_screen.render_progress.emit()

            render_message = f"Adding clip to list ({i + 1}/{len(clips)})"
            rendering_screen.render_progress.emit()

            if not clip.isInterval and not clip.isIntro:
                finish = VideoFileClip(
                    f'{settings.vid_finishedvids}/{mp4name}_finished.mp4').fx(
                        afx.volumex, audio)
            else:
                finish = VideoFileClip(f'{mp4path}').fx(afx.volumex, audio)

            end_duration += finish.duration
            fClips.append(finish)

            render_current_progress += 1
            render_message = f"Done Adding clip to list ({i + 1}/{len(clips)})"
            rendering_screen.render_progress.emit()
            if i <= 2:
                start_duration += finish.duration

    musicFiles = getFileNames(f'{settings.asset_file_path}/Music')
    random.shuffle(musicFiles)

    print("done working out durations")
    final_concat = concatenate_videoclips(fClips)
    print("done combining clips")
    print(musicFiles)

    # render progress 2
    render_message = "Creating audio loop"
    rendering_screen.render_progress.emit()
    #audio = AudioFileClip(f'{settings.asset_file_path}/Music/{musicFiles[0]}.mp3').fx(afx.volumex, float(video.background_volume))

    print("Using music type %s" % music_type)
    musicFolders = (getFileNames("Assets/Music"))

    if not musicFolders:
        music_type = "None"
        print("No music folders, defaulting to no audio")

    if not music_type == "None":

        to_combine = []
        music_combined_duration = 0

        while music_combined_duration < end_duration:
            random_file = random.choice(
                os.listdir(f'{settings.asset_file_path}/Music/{music_type}'))
            sound1 = AudioSegment.from_wav(
                f"Assets/Music/{music_type}/{random_file}")
            music_combined_duration += sound1.duration_seconds
            to_combine.append(sound1)

        combined_sounds = sum(to_combine)
        combined_sounds.export(f"{settings.temp_path}/music-loop-uncut.wav",
                               format="wav")
        audio_loop_without_pause = AudioSegment.from_wav(
            "%s/music-loop-uncut.wav" % settings.temp_path)
        new_audio = AudioSegment.silent(
            duration=(start_duration * 1000)) + audio_loop_without_pause
        new_audio.export(
            f"{settings.temp_path}/music-loop-uncut_with_pause.mp3",
            format="mp3")

        music_loop = afx.audio_loop(AudioFileClip(
            f"{settings.temp_path}/music-loop-uncut_with_pause.mp3"),
                                    duration=end_duration).fx(
                                        afx.volumex,
                                        float(video.background_volume))
        #music_loop = afx.audio_loop(audio, duration=end_duration)
        music_loop.write_audiofile(f'{settings.temp_path}/music-loop.mp3')

    render_current_progress += 1
    render_message = "Done Creating audio loop"
    rendering_screen.render_progress.emit()
    # render progress 3
    render_message = "Writing final video"
    rendering_screen.render_progress.emit()

    if not music_type == "None":
        final_vid_with_music = final_concat.set_audio(
            CompositeAudioClip([
                final_concat.audio,
                AudioFileClip(f'{settings.temp_path}/music-loop.mp3')
            ]))
    else:
        final_vid_with_music = final_concat.set_audio(final_concat.audio)

    sleep(5)
    final_vid_with_music.write_videofile(
        f'{settings.final_video_path}/TwitchMoments_{current_date}.mp4',
        fps=settings.fps,
        threads=16)
    render_current_progress += 1
    t1 = datetime.datetime.now()
    total = t1 - t0
    render_message = "Done writing final video (%s)" % total
    rendering_screen.render_progress.emit()

    f = open(f"{settings.final_video_path}/TwitchMoments_{current_date}.txt",
             "w+")
    f.write("A special thanks to the following: \n\n")
    for cred in credits:
        f.write(cred + "\n")
    f.close()
    sleep(10)
Exemple #17
0
def merge(file1, file2, outfile):
    subs1 = pysubs2.load(file1, encoding=charset_detect(file1))
    subs2 = pysubs2.load(file2, encoding=charset_detect(file2))

    '''[V4+ Styles]
Format: Name,Fontname,Fontsize,PrimaryColour,SecondaryColour,OutlineColour,BackColour,Bold,Italic,Underline,StrikeOut,ScaleX,ScaleY,Spacing,Angle,BorderStyle,Outline,Shadow,Alignment,MarginL,MarginR,MarginV,Encoding
Style:  Default,Arial, 16,     &H00FFFFFF,   &H00FFFFFF,     &H00000000,   &H00000000,-1,  0,     0,        0        ,100   ,100   ,0      ,0    ,1          ,3      ,0     ,2        ,10     ,10     ,10     ,0
Style:  Top ,Arial   ,16      ,&H00F9FFFF   ,&H00FFFFFF     ,&H00000000   ,&H00000000,-1  ,0     ,0        ,0        ,100   ,100   ,0      ,0    ,1          ,3      ,0     ,8        ,10     ,10     ,10     ,0
Style:  Mid ,Arial   ,16      ,&H0000FFFF   ,&H00FFFFFF     ,&H00000000   ,&H00000000,-1  ,0     ,0        ,0        ,100   ,100   ,0      ,0    ,1          ,3      ,0     ,5        ,10     ,10     ,10     ,0
Style:  Bot ,Arial   ,16      ,&H00F9FFF9   ,&H00FFFFFF     ,&H00000000   ,&H00000000,-1  ,0     ,0        ,0        ,100   ,100   ,0      ,0    ,1          ,3      ,0     ,2        ,10     ,10     ,10     ,0
'''
    style_top = SSAStyle()
    style_bot = SSAStyle()
    style_top.primarycolor = Color(249, 255, 255)
    style_bot.primarycolor = Color(249, 255, 249)
    style_bot.secondarycolor = Color(255, 255, 255)
    style_top.secondarycolor = Color(255, 255, 255)
    style_top.outline = 1.0
    style_bot.outline = 1.0
    style_top.shadow = 0.0
    style_bot.shadow = 0.0
    style_top.alignment = 8
    style_bot.alignment = 2
    # style_top.encoding # не знаю что значит, по умолчанию 1, в примере 0, оставлю 1
    subs2.styles['bot'] = style_bot
    subs2.styles['top'] = style_top

    for line in subs2:
        line.style = 'bot'

    for line in subs1:
        line.style = 'top'
        subs2.append(line)

    subs2.styles["Default"].fontsize = 14.0
    subs2.styles["Default"].shadow = 0.5
    subs2.styles["Default"].outline = 1.0
    subs2.save(outfile)
Exemple #18
0
def test_i_tag():
    text = "Hello, {\\i1}world{\\i0}!"
    assert parse_tags(text) == [("Hello, ", SSAStyle()),
                                ("world", SSAStyle(italic=True)),
                                ("!", SSAStyle())]
Exemple #19
0
def test_repr_floatsize():
    ev = SSAStyle(fontname="Calibri", fontsize=36.499)
    ref = "<SSAStyle 36.499px 'Calibri'>"
    assert repr(ev) == ref
def add_styles(subs, style_list=None):
    """
    Add styles to the subtitle file based on the style strings in each individual subtitle
    """
    if style_list is None:
        style_list = []
    for style in style_list:
        new_style = SSAStyle()
        # Number for position refers to the number on a keypad
        if 'top_left' in style:
            new_style.alignment = 7
        elif 'top_right' in style:
            new_style.alignment = 9
        elif 'bottom_left' in style:
            new_style.alignment = 1
        elif 'bottom_right' in style:
            new_style.alignment = 3
        elif 'left' in style:
            new_style.alignment = 4
        elif 'right' in style:
            new_style.alignment = 6
        elif 'top' in style:
            new_style.alignment = 8
        elif 'bottom' in style:
            new_style.alignment = 2
        # Setting the RGB values for the text
        if 'pred' in style:
            new_style.primarycolor = Color(255, 0, 0, 0)
        elif 'pblue' in style:
            new_style.primarycolor = Color(0, 0, 255, 0)
        elif 'pgreen' in style:
            new_style.primarycolor = Color(0, 255, 0, 0)
        elif 'pwhite' in style:
            new_style.primarycolor = Color(255, 255, 255, 0)
        # Setting the RGB values for the text's background
        if 'bred' in style:
            new_style.backcolor = Color(255, 0, 0, 0)
        elif 'bblue' in style:
            new_style.backcolor = Color(0, 0, 255, 0)
        elif 'bgreen' in style:
            new_style.backcolor = Color(0, 255, 0, 0)
        elif 'bwhite' in style:
            new_style.backcolor = Color(255, 255, 255, 0)
        # Setting different font types
        if 'bold' in style:
            new_style.bold = True
        if 'italic' in style:
            new_style.italic = True
        subs.styles[style] = new_style
    return subs