Я пытаюсь запрограммировать метод преобразования файлов субтитров, чтобы каждый субтитр всегда содержал только одно предложение.
Моя идея заключается в следующем:
Для каждого субтитра:
1.1 -> Я получаю продолжительность субтитров< /p>
1.2 -> Рассчитать символов_пер_секунды
1.3 -> Используйте это для хранения (внутри dict_times_word_subtitle) времени, необходимого для произнесения слова i
Я извлекаю предложения из всего текста
Для каждого предложения:
3.1 Я сохраняю (внутри dict_sentences_subtitle) время, необходимое для произнесения предложения с конкретными словами (из которого я могу получить продолжительность их произнесения)
Я создаю новый файл srt (файл субтитров), который начинается в то же время, что и исходный файл srt, и затем время субтитров может быть взято из продолжительности, необходимой для речи тот предложения.
На данный момент я написал следующий код:
#---------------------------------------------------------
import pysrt
import re
from datetime import datetime, date, time, timedelta
#---------------------------------------------------------
def convert_subtitle_one_sentence(file_name):
sub = pysrt.open(file_name)
### ----------------------------------------------------------------------
### Store Each Word and the Average Time it Takes to Say it in a dictionary
### ----------------------------------------------------------------------
dict_times_word_subtitle = {}
running_variable = 0
for i in range(len(sub)):
# Compute characters per second
characters_per_second = len(subtitle_text)/subtitle_duration
# Store Each Word and the Average Time (seconds) it Takes to Say in a Dictionary
for j,word in enumerate(subtitle_text.split()):
if j == len(subtitle_text.split())-1:
time = len(word)/characters_per_second
else:
time = len(word+" ")/characters_per_second
### ----------------------------------------------------------------------
### Store Each Sentence and the Average Time to Say it in a Dictionary
### ----------------------------------------------------------------------
# Get the entire text
entire_text = ""
for i in range(total_number_of_words):
entire_text += dict_times_word_subtitle[str(i)][0] +" "
# Initialize the dictionary
dict_times_sentences_subtitle = {}
# Loop through all found sentences
last_number_of_words = 0
for i,sentence in enumerate(re.findall(r'([A-Z][^\.!?]*[\.!?])', entire_text)):
number_of_words = len(sentence.split())
# Compute the time it takes to speak the sentence
time_sentence = 0
for j in range(last_number_of_words, last_number_of_words + number_of_words):
time_sentence += dict_times_word_subtitle[str(j)][1]
# Store the sentence together with the time it takes to say the sentence
dict_times_sentences_subtitle[str(i)] = [sentence, round(time_sentence,3)]
## Update last number_of_words
last_number_of_words += number_of_words
# Check if there is a non-sentence remaining at the end
if j < total_number_of_words:
remaining_string = ""
remaining_string_time = 0
for k in range(j+1, total_number_of_words):
remaining_string += dict_times_word_subtitle[str(k)][0] + " "
remaining_string_time += dict_times_word_subtitle[str(k)][1]
### ----------------------------------------------------------------------
### Create a new Subtitle file with only 1 sentence at a time
### ----------------------------------------------------------------------
# Initalize new srt file
new_srt = pysrt.SubRipFile()
# Loop through all sentence
# get initial start time (seconds)
# https://stackoverflow.com/questions/448 ... to-seconds
start_time = (datetime.combine(date.min, sub[0].start.to_time()) - datetime.min).total_seconds()
for i in range(len(dict_times_sentences_subtitle.keys())):
Проблема:
Сообщений об ошибках нет, но когда я применяю это к реальным файлам субтитров и затем смотрю видео, субтитры начинаются правильно , но по мере продвижения видео (прогрессирование ошибок) субтитры все меньше и меньше соответствуют тому, что на самом деле говорится.
Пример: говорящий закончил свое выступление, но субтитры продолжают появляться.< /p>
Простой пример для проверки
srt = """
1
00:00:13,100 --> 00:00:14,750
Dr. Martin Luther King, Jr.,
2
00:00:14,750 --> 00:00:18,636
in a 1968 speech where he reflects
upon the Civil Rights Movement,
3
00:00:18,636 --> 00:00:21,330
states, "In the end,
4
00:00:21,330 --> 00:00:24,413
we will remember not the words of our enemies
5
00:00:24,413 --> 00:00:27,280
but the silence of our friends."
6
00:00:27,280 --> 00:00:29,800
As a teacher, I've internalized this message.
"""
with open('test.srt', "w") as file:
file.write(srt)
convert_subtitle_one_sentence("test.srt")
Вывод выглядит следующим образом (да, над распознаванием предложений еще предстоит поработать (т. е. Dr. )):
0
00:00:13,100 --> 00:00:13,336
Dr.
1
00:00:13,336 --> 00:00:14,750
Martin Luther King, Jr.
2
00:00:14,750 --> 00:00:23,514
Civil Rights Movement, states, "In the end, we will remember not the words of our enemies but the silence of our friends.
3
00:00:23,514 --> 00:00:26,175
As a teacher, I've internalized this message.
4
00:00:26,175 --> 00:00:29,859
our friends." As a teacher, I've internalized this message.
Как вы можете видеть, исходная последняя отметка времени — 00:00:29,800, тогда как в выходном файле — 00:00:29,859 . Поначалу это может показаться не таким уж большим, но по мере того, как видео становится длиннее, разница увеличивается.
Полный образец видео можно скачать здесь: https://ufile.io/19nuvqb3
Полный файл субтитров: https://ufile.io/qracb7ai
Внимание: файл субтитров будет переопределен, поэтому вы можете захотеть сохранить копию под другим именем, чтобы иметь возможность сравнить.
Способ устранения:
Известно точное время появления слов, начинающихся или заканчивающихся в исходном субтитре. Это можно использовать для перекрестной проверки и соответствующей корректировки времени.
Изменить
Вот код для создания словаря, в котором хранятся символы,character_duration( среднее значение по субтитрам), а также начальную или конечную метку исходного времени, если она существует для этого символа.
sub = pysrt.open('video.srt')
running_variable = 0
dict_subtitle = {}
for i in range(len(sub)):
# Extract Start Time Stamb
timestamb_start = sub.start
# Extract Text
text =sub.text
# Extract End Time Stamb
timestamb_end = sub.end
# Extract Characters per Second
characters_per_second = sub.characters_per_second
# Fill Dictionary
for j,character in enumerate(" ".join(text.split())):
character_duration = len(character)*characters_per_second
dict_subtitle[str(running_variable)] = [character,character_duration,False, False]
if j == 0: dict_subtitle[str(running_variable)] = [character, character_duration, timestamb_start, False]
if j == len(text)-1 : dict_subtitle[str(running_variable)] = [character, character_duration, False, timestamb_end]
running_variable += 1
Я пытаюсь запрограммировать метод преобразования файлов субтитров, чтобы каждый субтитр всегда содержал только [b]одно предложение[/b]. Моя идея заключается в следующем: [list] [*]Для каждого субтитра: [/list] 1.1 -> Я получаю продолжительность субтитров< /p> 1.2 -> Рассчитать символов_пер_секунды 1.3 -> Используйте это для хранения (внутри dict_times_word_subtitle) времени, необходимого для произнесения слова i [list] [*]Я извлекаю предложения из всего текста
[*] Для каждого предложения:
[/list] 3.1 Я сохраняю (внутри dict_sentences_subtitle) время, необходимое для произнесения предложения с конкретными словами (из которого я могу получить продолжительность их произнесения) [list] [*]Я создаю новый файл srt (файл субтитров), который начинается в то же время, что и исходный файл srt, и затем время субтитров может быть взято из продолжительности, необходимой для речи тот предложения. [/list] На данный момент я написал следующий код: #--------------------------------------------------------- import pysrt import re from datetime import datetime, date, time, timedelta #---------------------------------------------------------
def convert_subtitle_one_sentence(file_name):
sub = pysrt.open(file_name)
### ---------------------------------------------------------------------- ### Store Each Word and the Average Time it Takes to Say it in a dictionary ### ----------------------------------------------------------------------
dict_times_word_subtitle = {} running_variable = 0 for i in range(len(sub)):
# Compute characters per second characters_per_second = len(subtitle_text)/subtitle_duration
# Store Each Word and the Average Time (seconds) it Takes to Say in a Dictionary
for j,word in enumerate(subtitle_text.split()): if j == len(subtitle_text.split())-1: time = len(word)/characters_per_second else: time = len(word+" ")/characters_per_second
### ---------------------------------------------------------------------- ### Store Each Sentence and the Average Time to Say it in a Dictionary ### ----------------------------------------------------------------------
# Get the entire text entire_text = "" for i in range(total_number_of_words): entire_text += dict_times_word_subtitle[str(i)][0] +" "
# Initialize the dictionary dict_times_sentences_subtitle = {}
# Loop through all found sentences last_number_of_words = 0 for i,sentence in enumerate(re.findall(r'([A-Z][^\.!?]*[\.!?])', entire_text)):
number_of_words = len(sentence.split())
# Compute the time it takes to speak the sentence time_sentence = 0 for j in range(last_number_of_words, last_number_of_words + number_of_words): time_sentence += dict_times_word_subtitle[str(j)][1]
# Store the sentence together with the time it takes to say the sentence dict_times_sentences_subtitle[str(i)] = [sentence, round(time_sentence,3)]
## Update last number_of_words last_number_of_words += number_of_words
# Check if there is a non-sentence remaining at the end if j < total_number_of_words: remaining_string = "" remaining_string_time = 0 for k in range(j+1, total_number_of_words): remaining_string += dict_times_word_subtitle[str(k)][0] + " " remaining_string_time += dict_times_word_subtitle[str(k)][1]
### ---------------------------------------------------------------------- ### Create a new Subtitle file with only 1 sentence at a time ### ----------------------------------------------------------------------
# Initalize new srt file new_srt = pysrt.SubRipFile()
# Loop through all sentence # get initial start time (seconds) # https://stackoverflow.com/questions/44823073/convert-datetime-time-to-seconds start_time = (datetime.combine(date.min, sub[0].start.to_time()) - datetime.min).total_seconds()
for i in range(len(dict_times_sentences_subtitle.keys())):
Проблема: Сообщений об ошибках нет, но когда я применяю это к реальным файлам субтитров и затем смотрю видео, субтитры начинаются правильно , но по мере продвижения видео (прогрессирование ошибок) субтитры все меньше и меньше соответствуют тому, что на самом деле говорится. Пример: говорящий закончил свое выступление, но субтитры продолжают появляться.< /p> [i] Простой пример для проверки srt = """ 1 00:00:13,100 --> 00:00:14,750 Dr. Martin Luther King, Jr.,
2 00:00:14,750 --> 00:00:18,636 in a 1968 speech where he reflects upon the Civil Rights Movement,
3 00:00:18,636 --> 00:00:21,330 states, "In the end,
4 00:00:21,330 --> 00:00:24,413 we will remember not the words of our enemies
5 00:00:24,413 --> 00:00:27,280 but the silence of our friends."
6 00:00:27,280 --> 00:00:29,800 As a teacher, I've internalized this message.
"""
with open('test.srt', "w") as file: file.write(srt)
convert_subtitle_one_sentence("test.srt")
Вывод выглядит следующим образом (да, над распознаванием предложений еще предстоит поработать (т. е. Dr. )): 0 00:00:13,100 --> 00:00:13,336 Dr.
1 00:00:13,336 --> 00:00:14,750 Martin Luther King, Jr.
2 00:00:14,750 --> 00:00:23,514 Civil Rights Movement, states, "In the end, we will remember not the words of our enemies but the silence of our friends.
3 00:00:23,514 --> 00:00:26,175 As a teacher, I've internalized this message.
4 00:00:26,175 --> 00:00:29,859 our friends." As a teacher, I've internalized this message.
Как вы можете видеть, исходная последняя отметка времени — 00:00:29,800, тогда как в выходном файле — 00:00:29,859 . Поначалу это может показаться не таким уж большим, но по мере того, как видео становится длиннее, разница увеличивается. Полный образец видео можно скачать здесь: https://ufile.io/19nuvqb3 Полный файл субтитров: https://ufile.io/qracb7ai Внимание: файл субтитров будет переопределен, поэтому вы можете захотеть сохранить копию под другим именем, чтобы иметь возможность сравнить. Способ устранения: Известно точное время появления слов, начинающихся или заканчивающихся в исходном субтитре. Это можно использовать для перекрестной проверки и соответствующей корректировки времени. Изменить Вот код для создания словаря, в котором хранятся символы,character_duration( среднее значение по субтитрам), а также начальную или конечную метку исходного времени, если она существует для этого символа. sub = pysrt.open('video.srt')
running_variable = 0 dict_subtitle = {}
for i in range(len(sub)):
# Extract Start Time Stamb timestamb_start = sub[i].start
# Extract Text text =sub[i].text
# Extract End Time Stamb timestamb_end = sub[i].end
# Extract Characters per Second characters_per_second = sub[i].characters_per_second
# Fill Dictionary for j,character in enumerate(" ".join(text.split())): character_duration = len(character)*characters_per_second dict_subtitle[str(running_variable)] = [character,character_duration,False, False] if j == 0: dict_subtitle[str(running_variable)] = [character, character_duration, timestamb_start, False] if j == len(text)-1 : dict_subtitle[str(running_variable)] = [character, character_duration, False, timestamb_end] running_variable += 1