Найти - Пользователи
Полная версия: Замена английского текста на русский перевод в субтитрах
Начало » Python для новичков » Замена английского текста на русский перевод в субтитрах
1
Imarden
Добрый день!
Пытаюсь написать скрипт для замены английского текста на русский перевод в субтитрах.
Сначала был набросок, но потом с помощью волшебных пенделей и гугля, скрипт стал обретать черты.
Есть файл субтитров srt:
1
00:00:12,753 –> 00:00:14,762
Agreed.
What's your point?
2
00:00:14,950 –> 00:00:18,140
There's no point, I just think
it's a good idea for a T-shirt.

И файл перевода:
Agreed.
Согласен.
What's your point?
А в чем смысл?
There's no point, I just think it's a good idea for a T-shirt.
Нет смысла, я всего лишь подумал, это хорошая идея для футболки.

Результат:

1
00:00:12,753 –> 00:00:14,762
Согласе
смысл?
2
00:00:14,950 –> 00:00:18,140
Нет смысла, я всего лишь
подумал, это хорошая идея для

Ну и сам скрипт.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import textwrap
# Создаем словать
en2rus = {}
# Открываем файл c переводами
with open("txt") as f:
    # Если открывается
    try:
        # Обрабаываем в цикле
        while True:
            # Первая строка
            FirstLine = next(f)
# Вторая строка
            SecondLine = next(f)
# Заносим первую строку как ключ в словарь, а вторую строку как значение в
# словарь
            # можно заодно любую длину сюда закинуть
            en2rus[FirstLine] = SecondLine
            # print(en2rus)
# Обрабатываем ошибку
    except StopIteration:
        pass  # файл кончился
# Открываем файл c переводами
with open("srt") as b, open("srt-out", "w") as out:
    # Если открывается
    try:
        # Обрабаываем в цикле
        while True:
            # Первая строка
            FirstLine = next(b)
            # Номер блока субтитров. Просто записываем
            out.write(FirstLine)
            # Вторая строка. Время субтитра. Просто записываем
            SecondLine = next(b)
            out.write(SecondLine)
            # Третья строка
            ThirdLine = next(b)
            # Убираем знак завершения строки
            SrtLine = ThirdLine.rstrip('\r\n')
            # Перебираем все ключи словаря
            for key in en2rus:
                # Проверяем входит ли строка в ключи словаря - ключи словаря английский текст
                if SrtLine in key:
                    # Определяем длину ключа
                    Lenkey = len(key)
                    # Определяем длину строки
                    LenSrtLine = len(SrtLine)
                    # Определяем длину переведенной строки, от которой нужно отрезать текст
                    y = textwrap.wrap(en2rus[key], width=LenSrtLine)
                    # Заменяем английский текст на перевод
                    ReplaceLine = ThirdLine.replace(SrtLine, y[0])
                    # Записываем замененный текст
                    out.write(ReplaceLine)
            # Четвертая строка
            FourthLine = next(b)
            # Убираем знак завершения строки
            SrtLine = FourthLine.rstrip('\r\n')
            # Если длина строки = 2, тогда просто записываем
            if len(SrtLine) == 2:
                out.write(FourthLine)
            else:
                # Иначе:
                # Перебираем все ключи словаря
                for key in en2rus:
                    # Проверяем входит ли строка в ключи словаря - ключи словаря английский текст
                    if SrtLine in key:
                        # Определяем длину ключа
                        Lenkey = len(key)
                        # Определяем длину строки
                        LenFourthLine = len(SrtLine)
                        # Определяем длину переведенной строки, от которой нужно отрезать текст
                        y = textwrap.wrap(en2rus[key], width=LenSrtLine)
                        # Заменяем английский текст на перевод
                        ReplaceLine = FourthLine.replace(SrtLine, y[1])
                        # Записываем замененный текст
                        out.write(ReplaceLine)
# Обрабатываем ошибку
    except StopIteration:
        pass  # файл кончился

Я понимаю что тут много быдлокода, но я еще учусь. Как лучше написать скрипт для замены английского текста на русский перевод в субтитрах?
py.user.next
Imarden
Как лучше написать скрипт для замены английского текста на русский перевод в субтитрах?
Вообще, начинать нужно с поиска модуля. Я вчера вот переводил теги к mp3-файлам из одной кодировки в другую, там нашёл себе модуль, который эти теги структурирует в дерево объектов. И эти объекты сразу дают доступ к тексту, минуя формат. Так что для субтитров нужно тоже что-то такое искать.

Imarden
Я понимаю что тут много быдлокода
Да, StopIteration никогда не отлавливается вручную. У next() есть необязательный второй параметр, который возвращается, если там возникло StopIteration.
>>> next((1 for _ in ()), 'x')
'x'
>>> 

Imarden
но я еще учусь
Задание алгоритмическое. Даже зная питон, его ещё нужно постараться сделать, чтобы получилось без ошибок. Строк-то там языковых может быть много, а интервал растягиваться надолго. Поэтому нужно делать исполнитель, который будет таким “умным” субтитром, который знает, где у него номер, где интервал, а где текст, и потом применять перевод к тексту.

class Subtitle:
 
    def set_id(self, n):
        pass
 
    def get_id(self):
        pass
 
    def set_interval(self, start, end):
        pass
 
    def get_interval(self):
        pass
 
    def set_text(self, s):
        pass
 
    def get_text(self):
        pass
Вот потом в такой субтитр читаешь из файла, потом у него переводишь текст, а потом из него сохраняешь в файл.
А зачем надо так делать, просто может что-нибудь внезапно обнаружиться, потребуются какие-то изменения. Вместо переделывания всей программы, ты просто ищешь часть, которая отвечает за область изменений, и меняешь только её.
Imarden
py.user.next
Спасибо. буду искать в модулях Python
sander
я бы нарезал файл с переводом в словарь {english: рус}, потом читал построчно оригинальный файл и проверял наличие строки в словаре, если нет перевода - пишем без изменений, если есть - пишем перевод
py.user.next
sander
потом читал построчно оригинальный файл и проверял наличие строки в словаре
Если по-быстрому, то это через re.sub() делается. Но контроля ошибок нет, поэтому положиться на это нельзя. Переведёшь так много файлов, а потом окажется, что там ошибка.
Imarden
py.user.next
Спасибо за наводку. То что нужно не нашел. Самое ближкое это subtitle_translator и pysrttranslator

Но они переводят с помощью стороних сервисов.
Все дело в том что перевод у меня есть.
Класс class Subtitle главную задачу пока не решает.

Пробую заменить ключ и значение в словаре. Новый ключ и новое значение - это срез старого ключа и значения. Отрезаю от ключа найденную строку, от значений - переведенную строку. Но почему то выдает ошибку:

    global en2rus[NewKey] = NewValue
                 ^
SyntaxError: invalid syntax

                # Проверяем входит ли строка в ключи словаря - ключи словаря
                # английский текст
                if SrtLine in key:
                    print(SrtLine,"SrtLine")
                    # Определяем длину ключа
                    Lenkey = len(key)
                    # Определяем длину строки
                    LenSrtLine = len(SrtLine)
                    # Определяем длину переведенной строки, от которой нужно
                    # отрезать текст
                    y = textwrap.wrap(en2rus[key], width=LenSrtLine)
                    # Заменяем английский текст на перевод
                    ReplaceLine = ThirdLine.replace(SrtLine, y[0])
                    print(ReplaceLine, "- ReplaceLine")                    
                    # Узнаем длину замененного текста
                    LenReplaceLine = len(ReplaceLine)                    
                    # Записываем замененный текст
                    # print(key, "key")
                    NewKey = key[LenSrtLine:]
                    print(NewKey, "- NewKey")
                    # print(en2rus[key], "en2rus[key]")
                    NewValue = en2rus[key][LenReplaceLine:]
                    print(NewValue, "- NewValue")
                    global en2rus[NewKey] = NewValue
                    out.write(ReplaceLine)

Часть вывода:

to you by Digium The Asterisk company.
- NewKey
Asterisk от Digium, компании создавшей Asterisk.
- NewValue
NewKey - новый ключ, NewValue - новое значение ключа в словаре.
sander
по запросу в гугле “subtitles parser python” по первой ссылке может подойдет?
Imarden
Этот модуль я видел. Он может помочь определить начало блока - это где в начала порядковый номер и время. Это уже реализовать в коде.

Скажите что не так в этой ошибке:

global en2rus = NewValue
^
SyntaxError: invalid syntax
sander
инвалидный синтаксис
global en2rus 
en2rus  = <value>
Imarden
Спасибо. Уже понял.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB