subtitld 0.0.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- subtitld/__init__.py +19 -0
- subtitld/__main__.py +240 -0
- subtitld/ftfy/char_classes.dat +0 -0
- subtitld/graphics/Montserrat-Black.ttf +0 -0
- subtitld/graphics/Montserrat-BlackItalic.ttf +0 -0
- subtitld/graphics/Montserrat-Bold.ttf +0 -0
- subtitld/graphics/Montserrat-BoldItalic.ttf +0 -0
- subtitld/graphics/Montserrat-ExtraBold.ttf +0 -0
- subtitld/graphics/Montserrat-ExtraBoldItalic.ttf +0 -0
- subtitld/graphics/Montserrat-ExtraLight.ttf +0 -0
- subtitld/graphics/Montserrat-ExtraLightItalic.ttf +0 -0
- subtitld/graphics/Montserrat-Italic.ttf +0 -0
- subtitld/graphics/Montserrat-Light.ttf +0 -0
- subtitld/graphics/Montserrat-LightItalic.ttf +0 -0
- subtitld/graphics/Montserrat-Medium.ttf +0 -0
- subtitld/graphics/Montserrat-MediumItalic.ttf +0 -0
- subtitld/graphics/Montserrat-Regular.ttf +0 -0
- subtitld/graphics/Montserrat-SemiBold.ttf +0 -0
- subtitld/graphics/Montserrat-SemiBoldItalic.ttf +0 -0
- subtitld/graphics/Montserrat-Thin.ttf +0 -0
- subtitld/graphics/Montserrat-ThinItalic.ttf +0 -0
- subtitld/graphics/Ubuntu-B.ttf +0 -0
- subtitld/graphics/Ubuntu-BI.ttf +0 -0
- subtitld/graphics/Ubuntu-C.ttf +0 -0
- subtitld/graphics/Ubuntu-L.ttf +0 -0
- subtitld/graphics/Ubuntu-LI.ttf +0 -0
- subtitld/graphics/Ubuntu-M.ttf +0 -0
- subtitld/graphics/Ubuntu-MI.ttf +0 -0
- subtitld/graphics/Ubuntu-R.ttf +0 -0
- subtitld/graphics/Ubuntu-RI.ttf +0 -0
- subtitld/graphics/Ubuntu-Th.ttf +0 -0
- subtitld/graphics/UbuntuMono-B.ttf +0 -0
- subtitld/graphics/UbuntuMono-BI.ttf +0 -0
- subtitld/graphics/UbuntuMono-R.ttf +0 -0
- subtitld/graphics/UbuntuMono-RI.ttf +0 -0
- subtitld/graphics/add_and_play.svg +4 -0
- subtitld/graphics/add_from_last.svg +4 -0
- subtitld/graphics/add_from_last_checked.svg +4 -0
- subtitld/graphics/add_subtitle_icon.svg +4 -0
- subtitld/graphics/add_subtitle_to_next_start.svg +4 -0
- subtitld/graphics/add_subtitle_to_next_start_checked.svg +4 -0
- subtitld/graphics/background_watermark.svg +9 -0
- subtitld/graphics/character_count_icon.svg +1 -0
- subtitld/graphics/checkbox_checked.svg +8 -0
- subtitld/graphics/checkbox_checked_hover.svg +8 -0
- subtitld/graphics/checkbox_disabled.svg +4 -0
- subtitld/graphics/checkbox_unchecked.svg +5 -0
- subtitld/graphics/checkbox_unchecked_hover.svg +5 -0
- subtitld/graphics/combobox_down_arrow.svg +4 -0
- subtitld/graphics/cps_icon.svg +1 -0
- subtitld/graphics/dialog_close_icon.svg +4 -0
- subtitld/graphics/dialog_close_icon_hover.svg +4 -0
- subtitld/graphics/dubbing_container_collapse_icon.svg +8 -0
- subtitld/graphics/dubbing_container_expand_icon.svg +4 -0
- subtitld/graphics/file.svg +4 -0
- subtitld/graphics/gap_add_icon.svg +4 -0
- subtitld/graphics/gap_remove_icon.svg +4 -0
- subtitld/graphics/grid_frames_icon.svg +4 -0
- subtitld/graphics/grid_frames_icon_checked.svg +4 -0
- subtitld/graphics/grid_frames_icon_disabled.svg +4 -0
- subtitld/graphics/grid_scenes_icon.svg +4 -0
- subtitld/graphics/grid_scenes_icon_checked.svg +4 -0
- subtitld/graphics/grid_scenes_icon_disabled.svg +4 -0
- subtitld/graphics/grid_seconds_icon.svg +4 -0
- subtitld/graphics/grid_seconds_icon_checked.svg +4 -0
- subtitld/graphics/grid_seconds_icon_disabled.svg +4 -0
- subtitld/graphics/last_end_to_current_position_icon.svg +4 -0
- subtitld/graphics/last_start_last_end_to_current_position_button.svg +9 -0
- subtitld/graphics/last_start_to_current_position_icon.svg +4 -0
- subtitld/graphics/left_panel_autosave.svg +4 -0
- subtitld/graphics/left_panel_dubbing.svg +4 -0
- subtitld/graphics/left_panel_export.svg +4 -0
- subtitld/graphics/left_panel_global.svg +4 -0
- subtitld/graphics/left_panel_import.svg +4 -0
- subtitld/graphics/left_panel_interface.svg +4 -0
- subtitld/graphics/left_panel_keyboard.svg +4 -0
- subtitld/graphics/left_panel_metadata.svg +4 -0
- subtitld/graphics/left_panel_navigation_background.svg +11 -0
- subtitld/graphics/left_panel_qualitycheck.svg +4 -0
- subtitld/graphics/left_panel_speakers.svg +4 -0
- subtitld/graphics/left_panel_subtitles.svg +1 -0
- subtitld/graphics/left_panel_transcription.svg +4 -0
- subtitld/graphics/left_panel_translation.svg +4 -0
- subtitld/graphics/merge_back_selected_subtitle_icon.svg +4 -0
- subtitld/graphics/merge_next_selected_subtitle_icon.svg +4 -0
- subtitld/graphics/move_backward_subtitle.svg +4 -0
- subtitld/graphics/move_end_back_subtitle.svg +4 -0
- subtitld/graphics/move_end_forward_subtitle.svg +4 -0
- subtitld/graphics/move_forward_subtitle.svg +4 -0
- subtitld/graphics/move_start_back_subtitle.svg +4 -0
- subtitld/graphics/move_start_forward_subtitle.svg +4 -0
- subtitld/graphics/music_voice_separation_music_icon.svg +4 -0
- subtitld/graphics/music_voice_separation_music_icon_disabled.svg +4 -0
- subtitld/graphics/music_voice_separation_voice_icon.svg +4 -0
- subtitld/graphics/music_voice_separation_voice_icon_disabled.svg +4 -0
- subtitld/graphics/new_line_icon.svg +1 -0
- subtitld/graphics/next_end_to_current_position_icon.svg +4 -0
- subtitld/graphics/next_start_next_end_to_current_position_button.svg +4 -0
- subtitld/graphics/next_start_to_current_position_icon.svg +4 -0
- subtitld/graphics/pause_icon.svg +12 -0
- subtitld/graphics/play_from_last_start_icon.svg +5 -0
- subtitld/graphics/play_from_next_start_icon.svg +7 -0
- subtitld/graphics/play_icon.svg +12 -0
- subtitld/graphics/play_icon_hover.svg +12 -0
- subtitld/graphics/play_icon_pressed.svg +12 -0
- subtitld/graphics/playback_repeat.svg +4 -0
- subtitld/graphics/playback_speed.svg +6 -0
- subtitld/graphics/playbackspeed_border.svg +5 -0
- subtitld/graphics/playbackspeed_border_checked.svg +5 -0
- subtitld/graphics/playbackspeed_border_hover.svg +5 -0
- subtitld/graphics/playercontrols_button_first.svg +5 -0
- subtitld/graphics/playercontrols_button_first_hover.svg +6 -0
- subtitld/graphics/playercontrols_button_first_pressed.svg +6 -0
- subtitld/graphics/playercontrols_button_last.svg +6 -0
- subtitld/graphics/playercontrols_button_last_hover.svg +6 -0
- subtitld/graphics/playercontrols_button_last_pressed.svg +6 -0
- subtitld/graphics/playercontrols_widget_center_bottom_line.svg +13 -0
- subtitld/graphics/playercontrols_widget_center_top_line.svg +17 -0
- subtitld/graphics/plus_icon.svg +4 -0
- subtitld/graphics/record_icon.svg +8 -0
- subtitld/graphics/record_icon_pressed.svg +5 -0
- subtitld/graphics/remove_selected_subtitle_icon.svg +6 -0
- subtitld/graphics/repeat_playback_border.svg +5 -0
- subtitld/graphics/repeat_playback_border_checked.svg +5 -0
- subtitld/graphics/repeat_playback_border_hover.svg +5 -0
- subtitld/graphics/save.svg +4 -0
- subtitld/graphics/send_text_to_last_subtitle_and_slice_button.svg +8 -0
- subtitld/graphics/send_text_to_last_subtitle_icon.svg +8 -0
- subtitld/graphics/send_text_to_next_subtitle_and_slice_button.svg +8 -0
- subtitld/graphics/send_text_to_next_subtitle_icon.svg +8 -0
- subtitld/graphics/slice_selected_subtitle_icon.svg +4 -0
- subtitld/graphics/snap_grid_icon.svg +4 -0
- subtitld/graphics/snap_grid_icon_checked.svg +4 -0
- subtitld/graphics/snap_grid_icon_disabled.svg +4 -0
- subtitld/graphics/snap_limits_icon.svg +4 -0
- subtitld/graphics/snap_limits_icon_checked.svg +4 -0
- subtitld/graphics/snap_limits_icon_disabled.svg +4 -0
- subtitld/graphics/snap_move_next.svg +4 -0
- subtitld/graphics/snap_move_next_checked.svg +4 -0
- subtitld/graphics/snap_move_next_disabled.svg +4 -0
- subtitld/graphics/snap_moving_icon.svg +4 -0
- subtitld/graphics/snap_moving_icon_checked.svg +4 -0
- subtitld/graphics/snap_moving_icon_disabled.svg +4 -0
- subtitld/graphics/speaker_list_item_change_color_icon.svg +4 -0
- subtitld/graphics/speaker_list_item_change_color_icon_hover.svg +4 -0
- subtitld/graphics/speaker_list_item_change_image_icon.svg +4 -0
- subtitld/graphics/speaker_list_item_change_image_icon_hover.svg +4 -0
- subtitld/graphics/speaker_list_item_export_icon.svg +4 -0
- subtitld/graphics/speaker_list_item_export_icon_hover.svg +4 -0
- subtitld/graphics/speaker_list_item_remove_icon.svg +4 -0
- subtitld/graphics/speaker_list_item_remove_icon_hover.svg +4 -0
- subtitld/graphics/speaker_list_item_rename_icon.svg +4 -0
- subtitld/graphics/speaker_list_item_rename_icon_hover.svg +4 -0
- subtitld/graphics/spinbox_arrow_down.svg +4 -0
- subtitld/graphics/spinbox_arrow_up.svg +4 -0
- subtitld/graphics/start_screen_top_shadow.svg +23 -0
- subtitld/graphics/stop_icon.svg +6 -0
- subtitld/graphics/stop_icon_hover.svg +6 -0
- subtitld/graphics/stop_icon_pressed.svg +6 -0
- subtitld/graphics/stylesheet.qss +1838 -0
- subtitld/graphics/subtitld.ico +0 -0
- subtitld/graphics/subtitld.png +0 -0
- subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_closed_icon.svg +4 -0
- subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_open_icon.svg +4 -0
- subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_open_icon_hover.svg +4 -0
- subtitld/graphics/timeline_bottom_controls_background.svg +25 -0
- subtitld/graphics/timeline_cursor_back_frame.svg +4 -0
- subtitld/graphics/timeline_cursor_back_frame_hover.svg +4 -0
- subtitld/graphics/timeline_cursor_next_frame.svg +4 -0
- subtitld/graphics/timeline_cursor_next_frame_hover.svg +4 -0
- subtitld/graphics/timeline_show_speaker_color.svg +5 -0
- subtitld/graphics/timeline_show_speaker_color_checked.svg +5 -0
- subtitld/graphics/timeline_show_speaker_in_tracks.svg +4 -0
- subtitld/graphics/timeline_show_speaker_in_tracks_checked.svg +4 -0
- subtitld/graphics/timelinescrolling_follow_icon.svg +4 -0
- subtitld/graphics/timelinescrolling_follow_icon_checked.svg +4 -0
- subtitld/graphics/timelinescrolling_none_icon.svg +6 -0
- subtitld/graphics/timelinescrolling_none_icon_checked.svg +6 -0
- subtitld/graphics/timelinescrolling_page_icon.svg +4 -0
- subtitld/graphics/timelinescrolling_page_icon_checked.svg +4 -0
- subtitld/graphics/titleBar_left_container_border.svg +113 -0
- subtitld/graphics/unknown_speaker.svg +5 -0
- subtitld/graphics/vosk_transcription_download_model_icon.svg +4 -0
- subtitld/graphics/vosk_transcription_update_model_icon.svg +4 -0
- subtitld/graphics/word_count_icon.svg +1 -0
- subtitld/graphics/wpm_icon.svg +1 -0
- subtitld/graphics/zoom_in_icon.svg +4 -0
- subtitld/graphics/zoom_in_icon_disabled.svg +4 -0
- subtitld/graphics/zoom_out_icon.svg +4 -0
- subtitld/graphics/zoom_out_icon_disabled.svg +4 -0
- subtitld/interface/__init__.py +0 -0
- subtitld/interface/actionmanager.py +18 -0
- subtitld/interface/bottom_panel.py +43 -0
- subtitld/interface/left_panel.py +144 -0
- subtitld/interface/left_panel_autosave.py +149 -0
- subtitld/interface/left_panel_dubbing.py +469 -0
- subtitld/interface/left_panel_export.py +755 -0
- subtitld/interface/left_panel_global.py +358 -0
- subtitld/interface/left_panel_import.py +82 -0
- subtitld/interface/left_panel_interface.py +616 -0
- subtitld/interface/left_panel_keyboard.py +261 -0
- subtitld/interface/left_panel_metadata.py +74 -0
- subtitld/interface/left_panel_qualitycheck.py +262 -0
- subtitld/interface/left_panel_speakers.py +737 -0
- subtitld/interface/left_panel_subtitleslist.py +791 -0
- subtitld/interface/left_panel_transcription.py +763 -0
- subtitld/interface/left_panel_translation.py +294 -0
- subtitld/interface/playercontrols.py +2348 -0
- subtitld/interface/preview_panel.py +407 -0
- subtitld/interface/productionscreen.py +65 -0
- subtitld/interface/startscreen.py +273 -0
- subtitld/interface/timeline.py +1308 -0
- subtitld/interface/top_bar.py +329 -0
- subtitld/interface/translation.py +68 -0
- subtitld/interface/utils.py +286 -0
- subtitld/locale/en_US.json +301 -0
- subtitld/locale/pt_BR.json +269 -0
- subtitld/modules/__init__.py +0 -0
- subtitld/modules/audioengine.py +606 -0
- subtitld/modules/bounce.py +229 -0
- subtitld/modules/config.py +84 -0
- subtitld/modules/file_io.py +870 -0
- subtitld/modules/history.py +31 -0
- subtitld/modules/quality_check.py +53 -0
- subtitld/modules/session.py +270 -0
- subtitld/modules/shortcuts.py +84 -0
- subtitld/modules/subtitles.py +413 -0
- subtitld/modules/timecode.py +496 -0
- subtitld/modules/usf.py +366 -0
- subtitld/modules/utils.py +79 -0
- subtitld/modules/waveform.py +53 -0
- subtitld-0.0.0.dev0.dist-info/METADATA +97 -0
- subtitld-0.0.0.dev0.dist-info/RECORD +237 -0
- subtitld-0.0.0.dev0.dist-info/WHEEL +5 -0
- subtitld-0.0.0.dev0.dist-info/entry_points.txt +2 -0
- subtitld-0.0.0.dev0.dist-info/licenses/LICENSE +674 -0
- subtitld-0.0.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
"""Module to handle subtitles
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from bisect import bisect
|
|
6
|
+
from subtitld.modules import history, session
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def add_subtitle(position=0.0, duration=3.0, text='', from_last_subtitle=False):
|
|
10
|
+
"""Function to add a subtitle to the main subtitle list"""
|
|
11
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
12
|
+
|
|
13
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
14
|
+
index = bisect(subt, position)
|
|
15
|
+
|
|
16
|
+
if index:
|
|
17
|
+
if session.SUBTITLE['segments'][index - 1]['end'] > position:
|
|
18
|
+
session.SUBTITLE['segments'][index - 1]['end'] -= (session.SUBTITLE['segments'][index - 1]['end']) - position
|
|
19
|
+
elif from_last_subtitle:
|
|
20
|
+
position = (session.SUBTITLE['segments'][index - 1]['end']) + .001
|
|
21
|
+
|
|
22
|
+
if len(session.SUBTITLE['segments']) - 1 > index and session.SUBTITLE['segments'][index]['start'] - position < duration:
|
|
23
|
+
duration = session.SUBTITLE['segments'][index]['start'] - position
|
|
24
|
+
|
|
25
|
+
session.SUBTITLE['segments'].insert(index, {
|
|
26
|
+
'start': position,
|
|
27
|
+
'end': position + duration,
|
|
28
|
+
'text': text
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
# return session.SUBTITLE['segments'][session.SUBTITLE['segments'].index([position, duration, text])]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def remove_subtitle(selected_subtitle=False):
|
|
35
|
+
"""Function to add a subtitle to the main subtitle list"""
|
|
36
|
+
if selected_subtitle:
|
|
37
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
38
|
+
|
|
39
|
+
session.SUBTITLE['segments'].remove(selected_subtitle)
|
|
40
|
+
return session.SUBTITLE['segments']
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def slice_subtitle(selected_subtitle=False, position=0.0, last_text='', next_text='', strip_text=True):
|
|
44
|
+
"""Function to slice a subtitle in the main subtitle list"""
|
|
45
|
+
if selected_subtitle: # and position > selected_subtitle['start'] and position < selected_subtitle['end']:
|
|
46
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
47
|
+
|
|
48
|
+
index = session.SUBTITLE['segments'].index(selected_subtitle)
|
|
49
|
+
|
|
50
|
+
if position > session.SUBTITLE['segments'][index]['start'] and position < session.SUBTITLE['segments'][index]['end']:
|
|
51
|
+
position_to_cut = position
|
|
52
|
+
else:
|
|
53
|
+
position_to_cut = session.SUBTITLE['segments'][index]['start'] + ((session.SUBTITLE['segments'][index]['end'] - session.SUBTITLE['segments'][index]['start']) / 2)
|
|
54
|
+
|
|
55
|
+
new_duration = session.SUBTITLE['segments'][index]['end'] - position_to_cut
|
|
56
|
+
|
|
57
|
+
session.SUBTITLE['segments'][index]['end'] = position_to_cut - 0.001
|
|
58
|
+
session.SUBTITLE['segments'][index]['text'] = last_text
|
|
59
|
+
|
|
60
|
+
if strip_text:
|
|
61
|
+
session.SUBTITLE['segments'][index]['text'] = session.SUBTITLE['segments'][index]['text'].strip()
|
|
62
|
+
next_text = next_text.strip()
|
|
63
|
+
|
|
64
|
+
add_subtitle(position=position_to_cut, duration=new_duration, text=next_text)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def merge_back_subtitle(selected_subtitle=False):
|
|
68
|
+
"""Function to merge a subtitle to one subtitle back in the main subtitle list"""
|
|
69
|
+
if selected_subtitle and session.SUBTITLE['segments'].index(selected_subtitle):
|
|
70
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
71
|
+
|
|
72
|
+
subt = sorted([subtitle['end'] for subtitle in session.SUBTITLE['segments'] if subtitle['end'] <= selected_subtitle['start']])
|
|
73
|
+
nearest_subttile = [subtitle for subtitle in session.SUBTITLE['segments'] if subtitle['end'] == subt[-1]][0]
|
|
74
|
+
|
|
75
|
+
nearest_subttile['end'] = selected_subtitle['end']
|
|
76
|
+
nearest_subttile['text'] += ' ' + selected_subtitle['text']
|
|
77
|
+
|
|
78
|
+
if 'translations' in nearest_subttile and 'translations' in selected_subtitle:
|
|
79
|
+
for language in nearest_subttile['translations']:
|
|
80
|
+
if language in nearest_subttile['translations'] and language in selected_subtitle['translations']:
|
|
81
|
+
nearest_subttile['translations'][language] += ' ' + selected_subtitle['translations'][language]
|
|
82
|
+
else:
|
|
83
|
+
nearest_subttile['translations'][language] = selected_subtitle['translations'][language]
|
|
84
|
+
|
|
85
|
+
remove_subtitle(selected_subtitle=selected_subtitle)
|
|
86
|
+
|
|
87
|
+
return nearest_subttile
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def merge_next_subtitle(selected_subtitle=False):
|
|
91
|
+
"""Function to merge a subtitle to the next subtitle in the main subtitle list"""
|
|
92
|
+
if selected_subtitle and session.SUBTITLE['segments'].index(selected_subtitle) < len(session.SUBTITLE['segments']) - 1:
|
|
93
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
94
|
+
|
|
95
|
+
subt = sorted([item['start'] for item in session.SUBTITLE['segments'] if item['start'] >= selected_subtitle['end']])
|
|
96
|
+
nearest_subttile = [subtitle for subtitle in session.SUBTITLE['segments'] if subtitle['start'] == subt[0]][0]
|
|
97
|
+
|
|
98
|
+
selected_subtitle['end'] = nearest_subttile['end']
|
|
99
|
+
selected_subtitle['text'] += ' ' + nearest_subttile['text']
|
|
100
|
+
|
|
101
|
+
if 'translations' in selected_subtitle and 'translations' in nearest_subttile:
|
|
102
|
+
for language in selected_subtitle['translations']:
|
|
103
|
+
if language in selected_subtitle['translations']:
|
|
104
|
+
selected_subtitle['translations'][language] += ' ' + nearest_subttile['translations'][language]
|
|
105
|
+
else:
|
|
106
|
+
selected_subtitle['translations'][language] = nearest_subttile['translations'][language]
|
|
107
|
+
|
|
108
|
+
remove_subtitle(selected_subtitle=nearest_subttile)
|
|
109
|
+
|
|
110
|
+
return selected_subtitle
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def move_subtitle(selected_subtitle=False, amount=0.0, absolute_time=False):
|
|
114
|
+
"""Function to move a subtitle in the main subtitle list"""
|
|
115
|
+
if selected_subtitle:
|
|
116
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
117
|
+
if absolute_time:
|
|
118
|
+
duration = selected_subtitle['end'] - selected_subtitle['start']
|
|
119
|
+
selected_subtitle['start'] = absolute_time
|
|
120
|
+
selected_subtitle['end'] = absolute_time + duration
|
|
121
|
+
else:
|
|
122
|
+
selected_subtitle['start'] += amount
|
|
123
|
+
selected_subtitle['end'] += amount
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def move_start_subtitle(selected_subtitle=False, amount=0.0, absolute_time=False, move_nereast=False):
|
|
127
|
+
"""Function to move the start a subtitle in the main subtitle list"""
|
|
128
|
+
if selected_subtitle:
|
|
129
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
130
|
+
if move_nereast:
|
|
131
|
+
subt = [item['end'] for item in session.SUBTITLE['segments']]
|
|
132
|
+
nearest = bisect(subt, selected_subtitle['start']) - 1
|
|
133
|
+
if round(session.SUBTITLE['segments'][nearest]['end'], 3) == round(selected_subtitle['start'] - .001, 3):
|
|
134
|
+
if absolute_time:
|
|
135
|
+
session.SUBTITLE['segments'][nearest]['end'] = absolute_time - 0.001
|
|
136
|
+
else:
|
|
137
|
+
session.SUBTITLE['segments'][nearest]['end'] -= amount
|
|
138
|
+
if absolute_time:
|
|
139
|
+
selected_subtitle['start'] = absolute_time
|
|
140
|
+
else:
|
|
141
|
+
selected_subtitle['start'] += amount
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def move_end_subtitle(selected_subtitle=False, amount=0.0, absolute_time=False, move_nereast=False):
|
|
145
|
+
"""Function to move the end of a subtitle in the main subtitle list"""
|
|
146
|
+
if selected_subtitle:
|
|
147
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
148
|
+
if move_nereast:
|
|
149
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
150
|
+
nearest = bisect(subt, selected_subtitle['end'])
|
|
151
|
+
if round(session.SUBTITLE['segments'][nearest]['start'], 3) == round(selected_subtitle['end'] + .001, 3):
|
|
152
|
+
if absolute_time:
|
|
153
|
+
session.SUBTITLE['segments'][nearest]['start'] = absolute_time + 0.001
|
|
154
|
+
else:
|
|
155
|
+
session.SUBTITLE['segments'][nearest]['start'] += amount
|
|
156
|
+
if absolute_time:
|
|
157
|
+
selected_subtitle['end'] = absolute_time
|
|
158
|
+
else:
|
|
159
|
+
selected_subtitle['end'] += amount
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def next_start_to_current_position(position=0.0):
|
|
163
|
+
"""Function to set next start to position of a subtitle in the main subtitle list"""
|
|
164
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
165
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
166
|
+
index = bisect(subt, position)
|
|
167
|
+
if index < len(subt):
|
|
168
|
+
session.SUBTITLE['segments'][index]['start'] = position
|
|
169
|
+
# if index and session.SUBTITLE['segments'][index - 1]['end'] > position:
|
|
170
|
+
# last_end_to_current_position(position=position - 0.001)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def subtitle_start_to_current_position(position=0.0):
|
|
174
|
+
"""Function to set start to position of a subtitle in the main subtitle list"""
|
|
175
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
176
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
177
|
+
index = bisect(subt, position)
|
|
178
|
+
if index and position < (session.SUBTITLE['segments'][index - 1]['end']):
|
|
179
|
+
# end = session.SUBTITLE['segments'][index - 1]['end']
|
|
180
|
+
session.SUBTITLE['segments'][index - 1]['start'] = position
|
|
181
|
+
# session.SUBTITLE['segments'][index - 1]['end'] = end - position
|
|
182
|
+
# else:
|
|
183
|
+
# end = session.SUBTITLE['segments'][index]['end']
|
|
184
|
+
# session.SUBTITLE['segments'][index]['start'] = position
|
|
185
|
+
# session.SUBTITLE['segments'][index]['end'] = end - position
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def subtitle_end_to_current_position(position=0.0):
|
|
189
|
+
"""Function to set end to position of a subtitle in the main subtitle list"""
|
|
190
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
191
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
192
|
+
index = bisect(subt, position)
|
|
193
|
+
if index:
|
|
194
|
+
if position < (session.SUBTITLE['segments'][index - 1]['end']):
|
|
195
|
+
session.SUBTITLE['segments'][index - 1]['end'] = position # - session.SUBTITLE['segments'][index - 1]['start']
|
|
196
|
+
# else:
|
|
197
|
+
# session.SUBTITLE['segments'][index - 1]['end'] = position - session.SUBTITLE['segments'][index - 1]['start']
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def subtitle_under_current_position(position=False):
|
|
201
|
+
"""Function to return subtitle under position"""
|
|
202
|
+
if not position:
|
|
203
|
+
position = session.SUBTITLE.get('position', 0.0)
|
|
204
|
+
# current_subtitle = False
|
|
205
|
+
|
|
206
|
+
return next((item for item in session.SUBTITLE['segments'] if item['start'] <= position < item['end']), False)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
# subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
210
|
+
# index = bisect(subt, position)
|
|
211
|
+
# if index - 1 > -1 and position > session.SUBTITLE['segments'][index - 1]['start'] and position < (session.SUBTITLE['segments'][index - 1]['end']):
|
|
212
|
+
# current_subtitle = session.SUBTITLE['segments'][index - 1]
|
|
213
|
+
# return current_subtitle
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def get_adjacent_subtitles(position=False, subtitle=False):
|
|
217
|
+
if subtitle:
|
|
218
|
+
position = subtitle['start']
|
|
219
|
+
|
|
220
|
+
if not position:
|
|
221
|
+
position = session.SUBTITLE.get('position', 0.0)
|
|
222
|
+
|
|
223
|
+
# The most efficient way to get the adjacent subtitles is to use binary search
|
|
224
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
225
|
+
index = bisect(subt, position)
|
|
226
|
+
|
|
227
|
+
return session.SUBTITLE['segments'][index - 2] if index > 1 else False, session.SUBTITLE['segments'][index] if index < len(subt) else False
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def last_subtitle_current_position(position=0.0):
|
|
232
|
+
"""Function to return the last subtitle of position"""
|
|
233
|
+
last_subtitle = False
|
|
234
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
235
|
+
index = bisect(subt, position)
|
|
236
|
+
if index:
|
|
237
|
+
if position > (session.SUBTITLE['segments'][index - 1]['end']):
|
|
238
|
+
last_subtitle = session.SUBTITLE['segments'][index - 1]
|
|
239
|
+
return last_subtitle
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def next_subtitle_current_position(position=0.0):
|
|
243
|
+
"""Function to return the next subtitle of position"""
|
|
244
|
+
next_subtitle = False
|
|
245
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
246
|
+
index = bisect(subt, position)
|
|
247
|
+
if index < len(subt):
|
|
248
|
+
next_subtitle = session.SUBTITLE['segments'][index]
|
|
249
|
+
return next_subtitle
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def next_end_to_current_position(position=0.0):
|
|
253
|
+
"""Function set next end to position"""
|
|
254
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
255
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
256
|
+
index = bisect(subt, position)
|
|
257
|
+
if index:
|
|
258
|
+
end = session.SUBTITLE['segments'][index - 1]['end']
|
|
259
|
+
if end > position:
|
|
260
|
+
session.SUBTITLE['segments'][index - 1]['end'] = position # - session.SUBTITLE['segments'][index - 1]['start']
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def last_end_to_current_position(position=0.0):
|
|
264
|
+
"""Function set last end to position"""
|
|
265
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
266
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
267
|
+
index = bisect(subt, position)
|
|
268
|
+
|
|
269
|
+
if index - 1 < len(subt) - 1:
|
|
270
|
+
session.SUBTITLE['segments'][index - 1]['end'] = position # - session.SUBTITLE['segments'][index - 1]['start']
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def last_start_to_current_position(position=0.0):
|
|
274
|
+
"""Function set last start to position"""
|
|
275
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
276
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
277
|
+
index = bisect(subt, position)
|
|
278
|
+
if index and session.SUBTITLE['segments'][index - 1]['start'] < position and not (session.SUBTITLE['segments'][index - 1]['end']) < position:
|
|
279
|
+
# end = session.SUBTITLE['segments'][index - 1]['end']
|
|
280
|
+
session.SUBTITLE['segments'][index - 1]['start'] = position
|
|
281
|
+
# session.SUBTITLE['segments'][index - 1]['end'] = end - position
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def send_text_to_next_subtitle(selected_subtitle=False, last_text='', next_text=''):
|
|
285
|
+
"""Function send text to the next subtitle"""
|
|
286
|
+
if selected_subtitle and session.SUBTITLE['segments'].index(selected_subtitle) + 1 < len(session.SUBTITLE['segments']):
|
|
287
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
288
|
+
index = session.SUBTITLE['segments'].index(selected_subtitle)
|
|
289
|
+
session.SUBTITLE['segments'][index]['text'] = last_text
|
|
290
|
+
|
|
291
|
+
next_text = next_text.strip() + ' ' + session.SUBTITLE['segments'][index + 1]['text']
|
|
292
|
+
if session.CONFIG['quality_check'].get('break_text_when_sending_text_to_adjacent', False) and '\n' in next_text:
|
|
293
|
+
next_text = next_text.replace('\n', ' ')
|
|
294
|
+
mid = len(next_text) // 2
|
|
295
|
+
left = next_text.rfind(' ', 0, mid)
|
|
296
|
+
right = next_text.find(' ', mid)
|
|
297
|
+
if left == -1:
|
|
298
|
+
split = right
|
|
299
|
+
elif right == -1:
|
|
300
|
+
split = left
|
|
301
|
+
else:
|
|
302
|
+
split = left if (mid - left) < (right - mid) else right
|
|
303
|
+
next_text = next_text[:split] + '\n' + next_text[split+1:]
|
|
304
|
+
|
|
305
|
+
session.SUBTITLE['segments'][index + 1]['text'] = next_text
|
|
306
|
+
|
|
307
|
+
def send_translated_text_to_next_subtitle(selected_subtitle=False, last_text='', next_text=''):
|
|
308
|
+
"""Function send text to the last subtitle"""
|
|
309
|
+
if selected_subtitle and session.SUBTITLE['segments'].index(selected_subtitle):
|
|
310
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
311
|
+
index = session.SUBTITLE['segments'].index(selected_subtitle)
|
|
312
|
+
session.SUBTITLE['segments'][index]['translations'][session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us')] = last_text
|
|
313
|
+
|
|
314
|
+
next_text = next_text.strip() + ' ' + session.SUBTITLE['segments'][index + 1]['translations'][session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us')]
|
|
315
|
+
if session.CONFIG['quality_check'].get('break_text_when_sending_text_to_adjacent', False) and '\n' in next_text:
|
|
316
|
+
next_text = next_text.replace('\n', ' ')
|
|
317
|
+
mid = len(next_text) // 2
|
|
318
|
+
left = next_text.rfind(' ', 0, mid)
|
|
319
|
+
right = next_text.find(' ', mid)
|
|
320
|
+
if left == -1:
|
|
321
|
+
split = right
|
|
322
|
+
elif right == -1:
|
|
323
|
+
split = left
|
|
324
|
+
else:
|
|
325
|
+
split = left if (mid - left) < (right - mid) else right
|
|
326
|
+
next_text = next_text[:split] + '\n' + next_text[split+1:]
|
|
327
|
+
|
|
328
|
+
session.SUBTITLE['segments'][index + 1]['translations'][session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us')] = next_text
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def send_text_to_last_subtitle(selected_subtitle=False, last_text='', next_text=''):
|
|
332
|
+
"""Function send text to the last subtitle"""
|
|
333
|
+
if selected_subtitle and session.SUBTITLE['segments'].index(selected_subtitle):
|
|
334
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
335
|
+
index = session.SUBTITLE['segments'].index(selected_subtitle)
|
|
336
|
+
session.SUBTITLE['segments'][index]['text'] = next_text
|
|
337
|
+
|
|
338
|
+
last_text = session.SUBTITLE['segments'][index - 1]['text'] + ' ' + last_text
|
|
339
|
+
if session.CONFIG['quality_check'].get('break_text_when_sending_text_to_adjacent', False) and '\n' in last_text:
|
|
340
|
+
last_text = last_text.replace('\n', ' ')
|
|
341
|
+
mid = len(last_text) // 2
|
|
342
|
+
left = last_text.rfind(' ', 0, mid)
|
|
343
|
+
right = last_text.find(' ', mid)
|
|
344
|
+
if left == -1:
|
|
345
|
+
split = right
|
|
346
|
+
elif right == -1:
|
|
347
|
+
split = left
|
|
348
|
+
else:
|
|
349
|
+
split = left if (mid - left) < (right - mid) else right
|
|
350
|
+
last_text = last_text[:split] + '\n' + last_text[split+1:]
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
session.SUBTITLE['segments'][index - 1]['text'] = last_text
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def send_translated_text_to_last_subtitle(selected_subtitle=False, last_text='', next_text=''):
|
|
357
|
+
"""Function send text to the last subtitle"""
|
|
358
|
+
if selected_subtitle and session.SUBTITLE['segments'].index(selected_subtitle):
|
|
359
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
360
|
+
index = session.SUBTITLE['segments'].index(selected_subtitle)
|
|
361
|
+
session.SUBTITLE['segments'][index]['translations'][session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us')] = next_text
|
|
362
|
+
|
|
363
|
+
last_text = session.SUBTITLE['segments'][index - 1]['translations'][session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us')] + ' ' + last_text
|
|
364
|
+
if session.CONFIG['quality_check'].get('break_text_when_sending_text_to_adjacent', False) and '\n' in last_text:
|
|
365
|
+
last_text = last_text.replace('\n', ' ')
|
|
366
|
+
mid = len(last_text) // 2
|
|
367
|
+
left = last_text.rfind(' ', 0, mid)
|
|
368
|
+
right = last_text.find(' ', mid)
|
|
369
|
+
if left == -1:
|
|
370
|
+
split = right
|
|
371
|
+
elif right == -1:
|
|
372
|
+
split = left
|
|
373
|
+
else:
|
|
374
|
+
split = left if (mid - left) < (right - mid) else right
|
|
375
|
+
last_text = last_text[:split] + '\n' + last_text[split+1:]
|
|
376
|
+
|
|
377
|
+
session.SUBTITLE['segments'][index - 1]['translations'][session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us')] = last_text
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def set_gap(position=0.0, gap=0.0):
|
|
381
|
+
"""Function to set gap in subtitles"""
|
|
382
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
383
|
+
for subtitle in session.SUBTITLE['segments']:
|
|
384
|
+
if subtitle['start'] > position:
|
|
385
|
+
subtitle['start'] += gap
|
|
386
|
+
subtitle['end'] += gap
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def change_subtitle_text(selected_subtitle=False, text=''):
|
|
390
|
+
"""Function to change text of selected subtitle"""
|
|
391
|
+
if selected_subtitle:
|
|
392
|
+
history.history_append(session.SUBTITLE['segments'])
|
|
393
|
+
session.SUBTITLE['segments'][session.SUBTITLE['segments'].index(selected_subtitle)]['text'] = text
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def is_current_position_above_subtitle(position=0.0):
|
|
397
|
+
subt = [item['start'] for item in session.SUBTITLE['segments']]
|
|
398
|
+
index = bisect(subt, position)
|
|
399
|
+
|
|
400
|
+
if position < session.SUBTITLE['segments'][index - 1]['end']:
|
|
401
|
+
return True
|
|
402
|
+
|
|
403
|
+
return False
|
|
404
|
+
|
|
405
|
+
def get_speaker_intervals(speaker_name):
|
|
406
|
+
intervals = []
|
|
407
|
+
for subtitle in session.SUBTITLE['segments']:
|
|
408
|
+
speaker = subtitle.get('speaker', None)
|
|
409
|
+
if speaker == speaker_name:
|
|
410
|
+
start = subtitle['start']
|
|
411
|
+
end = subtitle['end']
|
|
412
|
+
intervals.append((start, end))
|
|
413
|
+
return intervals
|