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.
Files changed (237) hide show
  1. subtitld/__init__.py +19 -0
  2. subtitld/__main__.py +240 -0
  3. subtitld/ftfy/char_classes.dat +0 -0
  4. subtitld/graphics/Montserrat-Black.ttf +0 -0
  5. subtitld/graphics/Montserrat-BlackItalic.ttf +0 -0
  6. subtitld/graphics/Montserrat-Bold.ttf +0 -0
  7. subtitld/graphics/Montserrat-BoldItalic.ttf +0 -0
  8. subtitld/graphics/Montserrat-ExtraBold.ttf +0 -0
  9. subtitld/graphics/Montserrat-ExtraBoldItalic.ttf +0 -0
  10. subtitld/graphics/Montserrat-ExtraLight.ttf +0 -0
  11. subtitld/graphics/Montserrat-ExtraLightItalic.ttf +0 -0
  12. subtitld/graphics/Montserrat-Italic.ttf +0 -0
  13. subtitld/graphics/Montserrat-Light.ttf +0 -0
  14. subtitld/graphics/Montserrat-LightItalic.ttf +0 -0
  15. subtitld/graphics/Montserrat-Medium.ttf +0 -0
  16. subtitld/graphics/Montserrat-MediumItalic.ttf +0 -0
  17. subtitld/graphics/Montserrat-Regular.ttf +0 -0
  18. subtitld/graphics/Montserrat-SemiBold.ttf +0 -0
  19. subtitld/graphics/Montserrat-SemiBoldItalic.ttf +0 -0
  20. subtitld/graphics/Montserrat-Thin.ttf +0 -0
  21. subtitld/graphics/Montserrat-ThinItalic.ttf +0 -0
  22. subtitld/graphics/Ubuntu-B.ttf +0 -0
  23. subtitld/graphics/Ubuntu-BI.ttf +0 -0
  24. subtitld/graphics/Ubuntu-C.ttf +0 -0
  25. subtitld/graphics/Ubuntu-L.ttf +0 -0
  26. subtitld/graphics/Ubuntu-LI.ttf +0 -0
  27. subtitld/graphics/Ubuntu-M.ttf +0 -0
  28. subtitld/graphics/Ubuntu-MI.ttf +0 -0
  29. subtitld/graphics/Ubuntu-R.ttf +0 -0
  30. subtitld/graphics/Ubuntu-RI.ttf +0 -0
  31. subtitld/graphics/Ubuntu-Th.ttf +0 -0
  32. subtitld/graphics/UbuntuMono-B.ttf +0 -0
  33. subtitld/graphics/UbuntuMono-BI.ttf +0 -0
  34. subtitld/graphics/UbuntuMono-R.ttf +0 -0
  35. subtitld/graphics/UbuntuMono-RI.ttf +0 -0
  36. subtitld/graphics/add_and_play.svg +4 -0
  37. subtitld/graphics/add_from_last.svg +4 -0
  38. subtitld/graphics/add_from_last_checked.svg +4 -0
  39. subtitld/graphics/add_subtitle_icon.svg +4 -0
  40. subtitld/graphics/add_subtitle_to_next_start.svg +4 -0
  41. subtitld/graphics/add_subtitle_to_next_start_checked.svg +4 -0
  42. subtitld/graphics/background_watermark.svg +9 -0
  43. subtitld/graphics/character_count_icon.svg +1 -0
  44. subtitld/graphics/checkbox_checked.svg +8 -0
  45. subtitld/graphics/checkbox_checked_hover.svg +8 -0
  46. subtitld/graphics/checkbox_disabled.svg +4 -0
  47. subtitld/graphics/checkbox_unchecked.svg +5 -0
  48. subtitld/graphics/checkbox_unchecked_hover.svg +5 -0
  49. subtitld/graphics/combobox_down_arrow.svg +4 -0
  50. subtitld/graphics/cps_icon.svg +1 -0
  51. subtitld/graphics/dialog_close_icon.svg +4 -0
  52. subtitld/graphics/dialog_close_icon_hover.svg +4 -0
  53. subtitld/graphics/dubbing_container_collapse_icon.svg +8 -0
  54. subtitld/graphics/dubbing_container_expand_icon.svg +4 -0
  55. subtitld/graphics/file.svg +4 -0
  56. subtitld/graphics/gap_add_icon.svg +4 -0
  57. subtitld/graphics/gap_remove_icon.svg +4 -0
  58. subtitld/graphics/grid_frames_icon.svg +4 -0
  59. subtitld/graphics/grid_frames_icon_checked.svg +4 -0
  60. subtitld/graphics/grid_frames_icon_disabled.svg +4 -0
  61. subtitld/graphics/grid_scenes_icon.svg +4 -0
  62. subtitld/graphics/grid_scenes_icon_checked.svg +4 -0
  63. subtitld/graphics/grid_scenes_icon_disabled.svg +4 -0
  64. subtitld/graphics/grid_seconds_icon.svg +4 -0
  65. subtitld/graphics/grid_seconds_icon_checked.svg +4 -0
  66. subtitld/graphics/grid_seconds_icon_disabled.svg +4 -0
  67. subtitld/graphics/last_end_to_current_position_icon.svg +4 -0
  68. subtitld/graphics/last_start_last_end_to_current_position_button.svg +9 -0
  69. subtitld/graphics/last_start_to_current_position_icon.svg +4 -0
  70. subtitld/graphics/left_panel_autosave.svg +4 -0
  71. subtitld/graphics/left_panel_dubbing.svg +4 -0
  72. subtitld/graphics/left_panel_export.svg +4 -0
  73. subtitld/graphics/left_panel_global.svg +4 -0
  74. subtitld/graphics/left_panel_import.svg +4 -0
  75. subtitld/graphics/left_panel_interface.svg +4 -0
  76. subtitld/graphics/left_panel_keyboard.svg +4 -0
  77. subtitld/graphics/left_panel_metadata.svg +4 -0
  78. subtitld/graphics/left_panel_navigation_background.svg +11 -0
  79. subtitld/graphics/left_panel_qualitycheck.svg +4 -0
  80. subtitld/graphics/left_panel_speakers.svg +4 -0
  81. subtitld/graphics/left_panel_subtitles.svg +1 -0
  82. subtitld/graphics/left_panel_transcription.svg +4 -0
  83. subtitld/graphics/left_panel_translation.svg +4 -0
  84. subtitld/graphics/merge_back_selected_subtitle_icon.svg +4 -0
  85. subtitld/graphics/merge_next_selected_subtitle_icon.svg +4 -0
  86. subtitld/graphics/move_backward_subtitle.svg +4 -0
  87. subtitld/graphics/move_end_back_subtitle.svg +4 -0
  88. subtitld/graphics/move_end_forward_subtitle.svg +4 -0
  89. subtitld/graphics/move_forward_subtitle.svg +4 -0
  90. subtitld/graphics/move_start_back_subtitle.svg +4 -0
  91. subtitld/graphics/move_start_forward_subtitle.svg +4 -0
  92. subtitld/graphics/music_voice_separation_music_icon.svg +4 -0
  93. subtitld/graphics/music_voice_separation_music_icon_disabled.svg +4 -0
  94. subtitld/graphics/music_voice_separation_voice_icon.svg +4 -0
  95. subtitld/graphics/music_voice_separation_voice_icon_disabled.svg +4 -0
  96. subtitld/graphics/new_line_icon.svg +1 -0
  97. subtitld/graphics/next_end_to_current_position_icon.svg +4 -0
  98. subtitld/graphics/next_start_next_end_to_current_position_button.svg +4 -0
  99. subtitld/graphics/next_start_to_current_position_icon.svg +4 -0
  100. subtitld/graphics/pause_icon.svg +12 -0
  101. subtitld/graphics/play_from_last_start_icon.svg +5 -0
  102. subtitld/graphics/play_from_next_start_icon.svg +7 -0
  103. subtitld/graphics/play_icon.svg +12 -0
  104. subtitld/graphics/play_icon_hover.svg +12 -0
  105. subtitld/graphics/play_icon_pressed.svg +12 -0
  106. subtitld/graphics/playback_repeat.svg +4 -0
  107. subtitld/graphics/playback_speed.svg +6 -0
  108. subtitld/graphics/playbackspeed_border.svg +5 -0
  109. subtitld/graphics/playbackspeed_border_checked.svg +5 -0
  110. subtitld/graphics/playbackspeed_border_hover.svg +5 -0
  111. subtitld/graphics/playercontrols_button_first.svg +5 -0
  112. subtitld/graphics/playercontrols_button_first_hover.svg +6 -0
  113. subtitld/graphics/playercontrols_button_first_pressed.svg +6 -0
  114. subtitld/graphics/playercontrols_button_last.svg +6 -0
  115. subtitld/graphics/playercontrols_button_last_hover.svg +6 -0
  116. subtitld/graphics/playercontrols_button_last_pressed.svg +6 -0
  117. subtitld/graphics/playercontrols_widget_center_bottom_line.svg +13 -0
  118. subtitld/graphics/playercontrols_widget_center_top_line.svg +17 -0
  119. subtitld/graphics/plus_icon.svg +4 -0
  120. subtitld/graphics/record_icon.svg +8 -0
  121. subtitld/graphics/record_icon_pressed.svg +5 -0
  122. subtitld/graphics/remove_selected_subtitle_icon.svg +6 -0
  123. subtitld/graphics/repeat_playback_border.svg +5 -0
  124. subtitld/graphics/repeat_playback_border_checked.svg +5 -0
  125. subtitld/graphics/repeat_playback_border_hover.svg +5 -0
  126. subtitld/graphics/save.svg +4 -0
  127. subtitld/graphics/send_text_to_last_subtitle_and_slice_button.svg +8 -0
  128. subtitld/graphics/send_text_to_last_subtitle_icon.svg +8 -0
  129. subtitld/graphics/send_text_to_next_subtitle_and_slice_button.svg +8 -0
  130. subtitld/graphics/send_text_to_next_subtitle_icon.svg +8 -0
  131. subtitld/graphics/slice_selected_subtitle_icon.svg +4 -0
  132. subtitld/graphics/snap_grid_icon.svg +4 -0
  133. subtitld/graphics/snap_grid_icon_checked.svg +4 -0
  134. subtitld/graphics/snap_grid_icon_disabled.svg +4 -0
  135. subtitld/graphics/snap_limits_icon.svg +4 -0
  136. subtitld/graphics/snap_limits_icon_checked.svg +4 -0
  137. subtitld/graphics/snap_limits_icon_disabled.svg +4 -0
  138. subtitld/graphics/snap_move_next.svg +4 -0
  139. subtitld/graphics/snap_move_next_checked.svg +4 -0
  140. subtitld/graphics/snap_move_next_disabled.svg +4 -0
  141. subtitld/graphics/snap_moving_icon.svg +4 -0
  142. subtitld/graphics/snap_moving_icon_checked.svg +4 -0
  143. subtitld/graphics/snap_moving_icon_disabled.svg +4 -0
  144. subtitld/graphics/speaker_list_item_change_color_icon.svg +4 -0
  145. subtitld/graphics/speaker_list_item_change_color_icon_hover.svg +4 -0
  146. subtitld/graphics/speaker_list_item_change_image_icon.svg +4 -0
  147. subtitld/graphics/speaker_list_item_change_image_icon_hover.svg +4 -0
  148. subtitld/graphics/speaker_list_item_export_icon.svg +4 -0
  149. subtitld/graphics/speaker_list_item_export_icon_hover.svg +4 -0
  150. subtitld/graphics/speaker_list_item_remove_icon.svg +4 -0
  151. subtitld/graphics/speaker_list_item_remove_icon_hover.svg +4 -0
  152. subtitld/graphics/speaker_list_item_rename_icon.svg +4 -0
  153. subtitld/graphics/speaker_list_item_rename_icon_hover.svg +4 -0
  154. subtitld/graphics/spinbox_arrow_down.svg +4 -0
  155. subtitld/graphics/spinbox_arrow_up.svg +4 -0
  156. subtitld/graphics/start_screen_top_shadow.svg +23 -0
  157. subtitld/graphics/stop_icon.svg +6 -0
  158. subtitld/graphics/stop_icon_hover.svg +6 -0
  159. subtitld/graphics/stop_icon_pressed.svg +6 -0
  160. subtitld/graphics/stylesheet.qss +1838 -0
  161. subtitld/graphics/subtitld.ico +0 -0
  162. subtitld/graphics/subtitld.png +0 -0
  163. subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_closed_icon.svg +4 -0
  164. subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_open_icon.svg +4 -0
  165. subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_open_icon_hover.svg +4 -0
  166. subtitld/graphics/timeline_bottom_controls_background.svg +25 -0
  167. subtitld/graphics/timeline_cursor_back_frame.svg +4 -0
  168. subtitld/graphics/timeline_cursor_back_frame_hover.svg +4 -0
  169. subtitld/graphics/timeline_cursor_next_frame.svg +4 -0
  170. subtitld/graphics/timeline_cursor_next_frame_hover.svg +4 -0
  171. subtitld/graphics/timeline_show_speaker_color.svg +5 -0
  172. subtitld/graphics/timeline_show_speaker_color_checked.svg +5 -0
  173. subtitld/graphics/timeline_show_speaker_in_tracks.svg +4 -0
  174. subtitld/graphics/timeline_show_speaker_in_tracks_checked.svg +4 -0
  175. subtitld/graphics/timelinescrolling_follow_icon.svg +4 -0
  176. subtitld/graphics/timelinescrolling_follow_icon_checked.svg +4 -0
  177. subtitld/graphics/timelinescrolling_none_icon.svg +6 -0
  178. subtitld/graphics/timelinescrolling_none_icon_checked.svg +6 -0
  179. subtitld/graphics/timelinescrolling_page_icon.svg +4 -0
  180. subtitld/graphics/timelinescrolling_page_icon_checked.svg +4 -0
  181. subtitld/graphics/titleBar_left_container_border.svg +113 -0
  182. subtitld/graphics/unknown_speaker.svg +5 -0
  183. subtitld/graphics/vosk_transcription_download_model_icon.svg +4 -0
  184. subtitld/graphics/vosk_transcription_update_model_icon.svg +4 -0
  185. subtitld/graphics/word_count_icon.svg +1 -0
  186. subtitld/graphics/wpm_icon.svg +1 -0
  187. subtitld/graphics/zoom_in_icon.svg +4 -0
  188. subtitld/graphics/zoom_in_icon_disabled.svg +4 -0
  189. subtitld/graphics/zoom_out_icon.svg +4 -0
  190. subtitld/graphics/zoom_out_icon_disabled.svg +4 -0
  191. subtitld/interface/__init__.py +0 -0
  192. subtitld/interface/actionmanager.py +18 -0
  193. subtitld/interface/bottom_panel.py +43 -0
  194. subtitld/interface/left_panel.py +144 -0
  195. subtitld/interface/left_panel_autosave.py +149 -0
  196. subtitld/interface/left_panel_dubbing.py +469 -0
  197. subtitld/interface/left_panel_export.py +755 -0
  198. subtitld/interface/left_panel_global.py +358 -0
  199. subtitld/interface/left_panel_import.py +82 -0
  200. subtitld/interface/left_panel_interface.py +616 -0
  201. subtitld/interface/left_panel_keyboard.py +261 -0
  202. subtitld/interface/left_panel_metadata.py +74 -0
  203. subtitld/interface/left_panel_qualitycheck.py +262 -0
  204. subtitld/interface/left_panel_speakers.py +737 -0
  205. subtitld/interface/left_panel_subtitleslist.py +791 -0
  206. subtitld/interface/left_panel_transcription.py +763 -0
  207. subtitld/interface/left_panel_translation.py +294 -0
  208. subtitld/interface/playercontrols.py +2348 -0
  209. subtitld/interface/preview_panel.py +407 -0
  210. subtitld/interface/productionscreen.py +65 -0
  211. subtitld/interface/startscreen.py +273 -0
  212. subtitld/interface/timeline.py +1308 -0
  213. subtitld/interface/top_bar.py +329 -0
  214. subtitld/interface/translation.py +68 -0
  215. subtitld/interface/utils.py +286 -0
  216. subtitld/locale/en_US.json +301 -0
  217. subtitld/locale/pt_BR.json +269 -0
  218. subtitld/modules/__init__.py +0 -0
  219. subtitld/modules/audioengine.py +606 -0
  220. subtitld/modules/bounce.py +229 -0
  221. subtitld/modules/config.py +84 -0
  222. subtitld/modules/file_io.py +870 -0
  223. subtitld/modules/history.py +31 -0
  224. subtitld/modules/quality_check.py +53 -0
  225. subtitld/modules/session.py +270 -0
  226. subtitld/modules/shortcuts.py +84 -0
  227. subtitld/modules/subtitles.py +413 -0
  228. subtitld/modules/timecode.py +496 -0
  229. subtitld/modules/usf.py +366 -0
  230. subtitld/modules/utils.py +79 -0
  231. subtitld/modules/waveform.py +53 -0
  232. subtitld-0.0.0.dev0.dist-info/METADATA +97 -0
  233. subtitld-0.0.0.dev0.dist-info/RECORD +237 -0
  234. subtitld-0.0.0.dev0.dist-info/WHEEL +5 -0
  235. subtitld-0.0.0.dev0.dist-info/entry_points.txt +2 -0
  236. subtitld-0.0.0.dev0.dist-info/licenses/LICENSE +674 -0
  237. 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