This commit is contained in:
Morgan 2024-02-05 02:04:41 +09:00
parent 1d5f8e1f65
commit 853ad895cc
No known key found for this signature in database
2 changed files with 140 additions and 12 deletions

81
restack.py Normal file
View File

@ -0,0 +1,81 @@
import re
from datetime import timedelta
VTT_TIMECODE_PATTERN = r"((?:\d{2}:)?\d{2}:\d{2}\.\d{3}) --> ((?:\d{2}:)?\d{2}:\d{2}\.\d{3})"
VTT_LINE_NUMBER_PATTERN = r"^\d+$"
def parse_vtt(vtt_string):
parts = re.split(r'\n\n+', vtt_string.strip())
if parts[0].startswith('WEBVTT'):
parts.pop(0)
subtitles = []
for part in parts:
lines = part.split('\n')
match = re.match(VTT_TIMECODE_PATTERN, lines[0])
if not match:
if re.match(VTT_LINE_NUMBER_PATTERN, lines[0]):
lines.pop(0)
match = re.match(VTT_TIMECODE_PATTERN, lines[0])
if not match:
continue
start, end = match.groups()
content = '\n'.join(lines[1:])
subtitles.append({
'start': start,
'end': end,
'content': content
})
return subtitles
def to_vtt(subtitles):
vtt_content = "WEBVTT\n\n"
for idx, subtitle in enumerate(subtitles):
# print(subtitle, idx)
start = subtitle['start']
end = subtitle['end']
content = subtitle['content']
vtt_content += f"{start} --> {end}\n{content}\n\n"
return vtt_content.strip()
with open("example.vtt", "r") as f:
vtt_content = f.read()
parsed_vtt = parse_vtt(vtt_content)
#print(len(parsed_vtt))
buffer = []
linebuf = []
for line in parsed_vtt:
# print(line["content"].strip())
content = line["content"].strip()
if "".join([i["content"] for i in linebuf]).count(".") < 4 or len(linebuf) < 5:
linebuf.append(line)
else:
linebuf.append(line)
buffer.append(linebuf)
linebuf = []
# print(buffer)
sub = []
for section in buffer:
strbuf = ""
for scene in section:
strbuf += scene["content"]
# if scene["content"][-1] == ".":
strbuf += "\n"
# else:
# strbuf += " "
scene["content"] = strbuf
sub.append(scene)
# print(buffer[0])
print(to_vtt(sub))

View File

@ -60,6 +60,8 @@ def mark_start():
print("Please load first..")
return
current_subtitle["content"] = current_subtitle.get("content","") + script_lines[line_index]
# current_subtitle["content"] = script_lines[line_index]
current_subtitle["index"] = line_index
update_display()
print(f"\n{timestamp} --> ", end="")
@ -94,8 +96,6 @@ def on_done_press(event = None):
return
if current_subtitle["start"] == None:
current_subtitle["content"] = ""
current_subtitle["start"] = None
load_next_line()
update_display()
return
timestamp = player.get_time() / 1000.0
@ -113,16 +113,20 @@ def on_back(event = None):
messagebox.showerror("Error", f"No subtitle to remove.")
return
if current_subtitle["start"]:
if not messagebox.askokcancel("Warning", f"\nDeleting \"{current_subtitle.get("content")}\" \n You need to go back and mark start again."):
if not messagebox.askokcancel("Warning", f"\nDeleting current #{current_subtitle.get("index")}.\n You need to go back and mark start again."):
return
if len(subtitles) > 2:
current_subtitle["content"] = subtitles[-2]["content"] + "\n"
current_subtitle["content"] = ""
if len(subtitles) > 1:
current_subtitle["content"] = subtitles[-1]["content"] + "\n"
current_subtitle["start"] = None
else:
if not messagebox.askokcancel("Warning", f"\nDeleting \"{subtitles[-1].get("content")}\" \n You need to go back and mark start again."):
if not messagebox.askokcancel("Warning", f"\nDeleting previous #{subtitles[-1].get("index")}.\n You need to go back and mark start again."):
return
del(subtitles[-1])
current_subtitle["content"] = ""
if len(subtitles) > 2:
current_subtitle["content"] = subtitles[-1]["content"] + "\n"
current_subtitle["start"] = None
print(f"\nCurrent: #{len(subtitles)+1} {current_subtitle}")
load_next_line(diff = -1)
@ -144,8 +148,12 @@ def to_time(seconds):
return f"{hours}:{minute:02}:{second:06.3f}"
def update_display():
listbox_scroll_pos = script_listbox.yview()
text_scroll_index = subtitle_text.index(tk.INSERT)
script_listbox.delete(0, tk.END)
script_listbox.selection_clear(0, tk.END)
subtitle_text.config(state=tk.NORMAL)
subtitle_text.delete("1.0", tk.END)
@ -172,6 +180,11 @@ def update_display():
if player.is_playing() or not audio_started:
script_listbox.see(min(line_index + 5, len(script_lines)))
subtitle_text.see(tk.END)
else:
script_listbox.yview_moveto(listbox_scroll_pos[0])
subtitle_text.see(text_scroll_index)
info_label.config(text="[ Current stack ]\n" + current_subtitle.get('content', ""))
subtitle_text.config(state=tk.DISABLED)
@ -396,6 +409,24 @@ def show_console_output_screen():
def on_prev_line():
load_next_line(diff=-1)
speedex = 1
def inc_playrate():
global speedex
speedex = round(speedex * 1.2, 2)
playrate()
def dec_playrate():
global speedex
speedex = round(speedex / 1.2, 2)
playrate()
def playrate():
speed_label.config(text=f"x{speedex:.2f}")
print(f"Playback rate x{speedex:.2f}")
player.set_rate(speedex)
root = tk.Tk()
root.title("Subtitle Timing Editor")
root.geometry('1000x800')
@ -441,6 +472,20 @@ timestamp_label = tk.Label(root, text="0.00s / 0.00s")
timestamp_label.pack(side=tk.BOTTOM, pady=5)
ctrl_frame = tk.Frame(root, borderwidth=0, relief="solid")
ctrl_frame.pack(side=tk.BOTTOM, padx=5)
one_button = tk.Button(ctrl_frame, text='-', borderwidth=0, command=dec_playrate)
one_button.pack(side=tk.LEFT, padx=(5,0), pady=5)
speed_label = tk.Label(ctrl_frame, text="x1")
speed_label.pack(side=tk.LEFT, padx=0, pady=5)
two_button = tk.Button(ctrl_frame, text='+', borderwidth=0, command=inc_playrate)
two_button.pack(side=tk.LEFT, padx=(0,5), pady=5)
btn_frame = tk.Frame(root, borderwidth=0, relief="solid")
btn_frame.pack(side=tk.BOTTOM, padx=5)
@ -504,12 +549,14 @@ skip_time_entry.insert(0, "0")
info_frame = tk.Frame(root, borderwidth=0, relief="solid", width=10, height=10, padx=10)
info_frame.pack(side=tk.TOP, expand=True, anchor="nw", padx=(5,15), pady=(10,15))
info_label = tk.Label(info_frame, text='' \
# 'VTT Maker by @morgan9e\n\n' \
'Usage:\n Mark <\'>\n Next <;>\n Done <Return>\n' \
'\n- Creates \"stacked\" subtitles easily.\n- Stacks subtitle from previous scene.' \
'\n- Load audio before restoring progress.\n- You can Edit, Merge, Delete script with left click.' \
, font=("monospace", 8), wraplength=140, justify=tk.LEFT)
info_label = tk.Label(info_frame, text='[ Current stack ]\n', width=20, font=("monospace", 8), anchor="nw", justify=tk.LEFT)
# info_label = tk.Label(info_frame, text='' \
# # 'VTT Maker by @morgan9e\n\n' \
# 'Usage:\n Mark <\'>\n Next <;>\n Done <Return>\n' \
# '\n- Creates \"stacked\" subtitles easily.\n- Stacks subtitle from previous scene.' \
# '\n- Load audio before restoring progress.\n- You can Edit, Merge, Delete script with left click.' \
# , font=("monospace", 8), wraplength=140, justify=tk.LEFT)
info_label.pack(side=tk.TOP, anchor="nw")