Как преобразовать файл субтитров, чтобы в каждом субтитре было только одно предложение?Python

Программы на Python
Ответить
Anonymous
 Как преобразовать файл субтитров, чтобы в каждом субтитре было только одно предложение?

Сообщение Anonymous »

Я пытаюсь запрограммировать метод преобразования файлов субтитров, чтобы каждый субтитр всегда содержал только одно предложение.
Моя идея заключается в следующем:
  • Для каждого субтитра:
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)):

subtitle_text = sub.text
subtitle_duration = (datetime.combine(date.min, sub.duration.to_time()) - datetime.min).total_seconds()

# 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

dict_times_word_subtitle[str(running_variable)] = [word, time]
running_variable += 1

### ----------------------------------------------------------------------
### Store Each Sentence and the Average Time to Say it in a Dictionary
### ----------------------------------------------------------------------

total_number_of_words = len(dict_times_word_subtitle.keys())

# 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]

dict_times_sentences_subtitle[str(i+1)] = [remaining_string, remaining_string_time]

### ----------------------------------------------------------------------
### 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())):

sentence = dict_times_sentences_subtitle[str(i)][0]
print(sentence)
time_sentence = dict_times_sentences_subtitle[str(i)][1]
print(time_sentence)
item = pysrt.SubRipItem(
index=i,
start=pysrt.SubRipTime(seconds=start_time),
end=pysrt.SubRipTime(seconds=start_time+time_sentence),
text=sentence)

new_srt.append(item)

## Update Start Time
start_time += time_sentence

new_srt.save(file_name)

Проблема:
Сообщений об ошибках нет, но когда я применяю это к реальным файлам субтитров и затем смотрю видео, субтитры начинаются правильно , но по мере продвижения видео (прогрессирование ошибок) субтитры все меньше и меньше соответствуют тому, что на самом деле говорится.
Пример: говорящий закончил свое выступление, но субтитры продолжают появляться.< /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

Больше видео, которые стоит попробовать
Здесь вы можете скачать больше видео и соответствующие файлы субтитров: https://filebin.net/kwygjffdlfi62pjs
Изменить 3
4
00:00:18,856 --> 00:00:25,904
Je rappelle la définition de ce qu'est un produit scalaire, dot product
dans Ⅎ.

5
00:00:24,855 --> 00:00:30,431
Donc je prends deux vecteurs dans Ⅎ et je définis cette opération-là, linéaire, u


Подробнее здесь: https://stackoverflow.com/questions/561 ... r-subtitle
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»