Skip to content

Commit b9bff24

Browse files
committed
3.07
1 parent c86e7a7 commit b9bff24

5 files changed

Lines changed: 192 additions & 53 deletions

File tree

ReaperScript.exe

11.5 MB
Binary file not shown.

ReaperScript.py

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
file_works,
66
path_choice,
77
get_fx_chains,
8-
get_path_to_files
8+
get_path_to_files,
99
)
1010
from multiprocessing import freeze_support
1111
from check_standalone import fix_checker
@@ -23,8 +23,12 @@
2323
on_closing,
2424
buttons_freeze,
2525
buttons_active,
26-
is_reaper_run
26+
is_reaper_run,
27+
show_help_window,
2728
)
29+
from help_texts import HELP_DICT
30+
from tkinter import ttk
31+
from tktooltip import ToolTip
2832
import multiprocessing as mp
2933
import tkinter.messagebox
3034
import pysubs2
@@ -424,6 +428,7 @@ def reaper_main(
424428
win32gui.ShowWindow(hwnd, 2)
425429
reapy.open_project(new_path, in_new_tab=True)
426430
project = reapy.Project()
431+
RPR.MoveEditCursor(- project.cursor_position, False)
427432
audio_select(audio)
428433
RPR.InsertMedia(video[0], 512 | 0)
429434
project.save(False)
@@ -489,9 +494,7 @@ def resource_path(path):
489494
y = (s_height - height) // 2
490495
master.geometry(f'{width}x{height}+{x}+{y - upper}')
491496
master.resizable(width=False, height=False)
492-
width = master.winfo_screenwidth()
493-
height = master.winfo_screenheight()
494-
master.title('REAPERSCRIPT')
497+
master.title('REAPERSCRIPT v3.07')
495498
img = Image.open(resource_path('background.png'))
496499
tk_img = ImageTk.PhotoImage(img)
497500
background_label = tkinter.Label(master, image=tk_img)
@@ -512,90 +515,92 @@ def resource_path(path):
512515
]
513516
config = get_config()
514517
checkboxes = {}
518+
checkbox_style = ttk.Style()
519+
checkbox_style.configure('TCheckbutton', background='#ffc0cb')
520+
button_style = ttk.Style()
521+
button_style.configure('TButton', background='#ffc0cb')
515522
for i, option in enumerate(OPTIONS):
516523
var = tkinter.BooleanVar()
517524
if option in config['OPTIONS']:
518525
var.set(config['OPTIONS'].getboolean(option))
519526
else:
520527
var.set(False)
521-
checkbox = tkinter.Checkbutton(
528+
checkbox = ttk.Checkbutton(
522529
master,
523530
text=option,
524531
variable=var,
525-
background='#ffc0cb',
526-
bd=3,
527-
pady=3,
528-
activebackground='#ffc0cb'
532+
padding=7,
529533
)
530534
checkbox.grid(
531535
row=i,
532536
column=0,
533537
sticky=tkinter.W
534538
)
539+
ToolTip(checkbox, HELP_DICT[option])
535540
checkboxes[option] = var
536541
BUTTONS = [
537542
'start',
538543
'template',
539544
'rfx',
540-
'fix_check',
545+
'fixcheck_standalone',
546+
'help',
541547
]
542-
start_bttn = tkinter.Button(
548+
start_bttn = ttk.Button(
543549
master,
544550
text='START',
545551
name='start',
546-
background='#9b93b3',
547-
activebackground='#9b93b3',
548552
command=lambda: on_save_click(checkboxes, master, BUTTONS)
549553
)
550554
start_bttn.place(relx=0.5, rely=1.0, anchor="s", y=-9)
551-
template = tkinter.Button(
555+
ToolTip(start_bttn, HELP_DICT['start'])
556+
template_btn = ttk.Button(
552557
master,
553558
text='TEMPLATE',
554559
name='template',
555-
background='#9b93b3',
556-
activebackground='#9b93b3',
557560
command=lambda: path_choice('project_path')
558561
)
559-
template.grid(
562+
template_btn.grid(
560563
row=(len(OPTIONS) + 2),
561564
column=0,
562565
sticky=tkinter.W,
563566
padx=6,
564567
pady=3
565-
)
566-
rfxchains = tkinter.Button(
568+
)
569+
ToolTip(template_btn, HELP_DICT['template'])
570+
rfxchains_btn = ttk.Button(
567571
master,
568572
text='RFXCHAINS',
569573
name='rfx',
570-
background='#9b93b3',
571-
activebackground='#9b93b3',
572574
command=lambda: path_choice('fx_chains_folder')
573575
)
574-
rfxchains.grid(
576+
rfxchains_btn.grid(
575577
row=(len(OPTIONS) + 3),
576578
column=0,
577579
sticky=tkinter.W,
578580
padx=6,
579581
pady=3
580-
)
581-
fix_check_button = tkinter.Button(
582+
)
583+
ToolTip(rfxchains_btn, HELP_DICT['rfx'])
584+
fix_check_btn = ttk.Button(
582585
master,
583586
text='FIXCHECK',
584-
name='fix_check',
585-
background='#9b93b3',
586-
activebackground='#9b93b3',
587+
name='fixcheck_standalone',
587588
command=lambda: on_fix_check_click(master, BUTTONS)
588589
)
589-
fix_check_button.place(relx=0.5, rely=1.0, anchor="s", x=150, y=-7)
590-
version = tkinter.Label(
590+
fix_check_btn.place(relx=0.5, rely=1.0, anchor="s", x=145, y=-9)
591+
ToolTip(fix_check_btn, HELP_DICT['fixcheck_standalone'])
592+
help_btn = ttk.Button(
591593
master,
592-
text='Version 3.04',
593-
background='#9b93b3',
594+
text='HELP',
595+
name='help',
596+
command=lambda: show_help_window(master),
594597
)
595-
version.place(relx=0.5, rely=1.0, anchor="s", x=150, y=-382)
598+
help_btn.place(relx=0.5, rely=1.0, anchor="s", x=145, y=-377)
599+
ToolTip(help_btn, HELP_DICT['help'])
596600

597601
# Чтобы Reaper API подгрузился, Reaper должен быть включен при запуске скрипта
598602
if __name__ == '__main__':
599603
freeze_support()
600604
is_reaper_run()
605+
master.focus_force()
601606
master.mainloop()

file_works.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
save_path,
1515
get_option,
1616
)
17-
18-
MANY_VIDEO = 'Оставьте в рабочей папке только нужный видеофайл'
19-
MANY_SUBS = 'Оставьте в рабочей папке только нужный файл субтитров'
20-
NO_VIDEO = 'В рабочей папке нет видеофайлов подходящего формата'
21-
NO_AUDIO = 'В рабочей папке нет аудиофайлов подходящего формата'
22-
NO_FOLDER = 'Рабочая папка не выбрана'
23-
IN_USE = 'Закройте приложения использующие рабочие файлы'
17+
from help_texts import (
18+
MANY_VIDEO,
19+
MANY_SUBS,
20+
NO_VIDEO,
21+
NO_AUDIO,
22+
NO_FOLDER,
23+
IN_USE,
24+
)
2425

2526

2627
def get_path_to_files(folder: str, extension: str) -> List[str]:
@@ -44,19 +45,12 @@ def get_fx_chains() -> Dict[str, str] or None:
4445

4546

4647
def path_choice(name: str) -> str or None:
47-
if name == 'reaper_path' or name == 'project_path':
48-
if name == 'reaper_path':
49-
defaultextension = 'exe'
50-
filetypes = [('.exe', 'reaper.exe')]
51-
initialdir = r'C:\Program Files\REAPER (x64)'
52-
initialfile = r'C:\Program Files\REAPER (x64)\reaper.exe'
53-
title = 'Выберите файл reaper.exe'
54-
elif name == 'project_path':
55-
defaultextension = 'rpp'
56-
filetypes = [('.rpp', '*.rpp')]
57-
initialdir = f'{os.getenv("APPDATA")}/REAPER/ProjectTemplates'
58-
initialfile = None
59-
title = 'Выберите файл шаблона проекта REAPER'
48+
if name == 'project_path':
49+
defaultextension = 'rpp'
50+
filetypes = [('.rpp', '*.rpp')]
51+
initialdir = f'{os.getenv("APPDATA")}/REAPER/ProjectTemplates'
52+
initialfile = None
53+
title = 'Выберите файл шаблона проекта REAPER'
6054
path = filedialog.askopenfilename(
6155
defaultextension=defaultextension,
6256
filetypes=filetypes,

help_texts.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
HOW_TO_USE = (
2+
'Создайте шаблон проекта, в нём должно быть только 2 трека:\n'
3+
'1) для видео\n'
4+
'2) трек "folder", в который будут складываться все дороги дабберов\n'
5+
'\n'
6+
'Добавьте необходимые посылы и эффекты на эти 2 трека.\n'
7+
'Если планируете использовать функцию рендера,\n'
8+
'нужно выполнить рендер из этого проекта с настройками,\n'
9+
'которые будут использоваться в дальнейшем.\n'
10+
'Обязательно выделите только 2-ой трек и воспльзуйтесь функцией\n'
11+
'REAPER\'а "Save project as template...".\n'
12+
'С помощью кнопки "TEMPLATE" выберите этот шаблон.\n'
13+
'\n'
14+
'Нажав на кнопку "RFXCHAINS" можно выбрать папку с цепями эффектов.\n'
15+
'Имена цепей должны соответствовать названиям дорог, без учёта регистра.\n'
16+
'Например:\n'
17+
'Если файл называется "что-то_там_озвучил ЧеловЕк_ПАук и_вот.wave",\n'
18+
'то на эту дорогу добавится цепь с именем "ЧеЛОвек_ПауК.RfxChain".\n'
19+
'\n'
20+
'Теперь REAPERSCRIPT запомнил пути к шаблону и цепям эффектов,\n'
21+
'при повторном запуске, нажимать на соответствующие кнопки,\n'
22+
'нужно только если изменились места хранения шаблона или цепей.\n'
23+
'\n'
24+
'Путь к рабочим файлам должен состоять минимум из 2 папок.\n'
25+
'Например:\n'
26+
'"A:/название тайтла/номер серии/<тут файлы>".\n'
27+
'\n'
28+
'После расстановки нужных чекбоксов, '
29+
'нажимаем на "START" и выбираем папку.\n'
30+
'Выбранные ранее чекбоксы, останутся такими при повторном запуске.\n'
31+
'\n'
32+
'Кнопка "FIXCHECK" проверяет проект в активной вкладке.\n'
33+
'Как и в случае с чекбоксом "fix_check",\n'
34+
'для корректной работы нужно использовать "split" на дорогах дабберов.\n'
35+
'\n'
36+
'REAPERSCRIPT принимает на вход:\n'
37+
'аудио в форматах ".flac" и ".wave"\n'
38+
'видео в форматах ".mkv" и ".mp4"\n'
39+
'субтитры в форматах ".ass", ".srt", "vtt"\n'
40+
'\n'
41+
'Нечитаемые расширения для аудио преобразуются в читаемые.\n'
42+
'Например:\n'
43+
'Файл с расширением ".flac420BPM" станет обычным ".flac".\n'
44+
'\n'
45+
'Если внутри видео с расширением ".mkv" есть субтитры,\n'
46+
'REAPERSCRIPT их достанет и добавит в проект.\n'
47+
'Сначала извлекаются русские субтитры, если их нет - то английские.\n'
48+
'В случае, когда нет ни того, ни другого - извлекаются первые доступные.\n'
49+
'\n'
50+
'Для использования функций нормализации нужно "SWS/S&M EXTENSION".\n'
51+
'\n'
52+
'Подробности об отдельных функциях можно узнать во всплывающем тексте.'
53+
)
54+
SPLIT = 'Использует последний пресет Dynamic split items'
55+
NORM = ('Использует SWS/BR: Normalize loudness of selected items to -23 LUFS '
56+
'для всех айтемов проекта')
57+
NORM_D = ('Использует SWS/BR: Normalize loudness of selected items to -23 '
58+
'LUFS для айтемов дабберов')
59+
NORM_V = ('Использует SWS/BR: Normalize loudness of selected items to -23 '
60+
'LUFS для видео айтема')
61+
VOLUME_UP = 'Поднимает громкость дабберов на 3.5 дБ'
62+
SUB_ITEM = 'Добавляет субтитры айтемы'
63+
SUB_REGION = 'Добавляет субтитры регионы'
64+
SUBS_CLEANER = 'Удаляет из субтитров надписи и песни'
65+
FIX_CHECK = ('Проверяет проект на наличие пропусков и даблов. '
66+
'Для корректной работы необходимо использовать "split"')
67+
RENDER_A = 'Рендерит звук, используя пресет рендера сохранённый в шаблоне'
68+
RENDER_V = ('Создаёт видео с исходным расширением и отрендеринным звуком, '
69+
'конвертируя его в ".aac"')
70+
START = 'Выбрать папку и начать работу'
71+
TEMPLATE = 'Выбрать шаблон проекта REAPER'
72+
RFXCHAINS = 'Выбрать папку с цепями эффектов'
73+
FIXCHECK_SRANDALONE = 'Проверить на фиксы активный проект'
74+
HELP = 'Помощь'
75+
HELP_DICT = {
76+
'split': SPLIT,
77+
'normalize': NORM,
78+
'normalize_dubbers': NORM_D,
79+
'normalize_video': NORM_V,
80+
'volume_up_dubbers': VOLUME_UP,
81+
'sub_item': SUB_ITEM,
82+
'sub_region': SUB_REGION,
83+
'subs_cleaner': SUBS_CLEANER,
84+
'fix_check': FIX_CHECK,
85+
'render_audio': RENDER_A,
86+
'render_video': RENDER_V,
87+
'start': START,
88+
'template': TEMPLATE,
89+
'rfx': RFXCHAINS,
90+
'fixcheck_standalone': FIXCHECK_SRANDALONE,
91+
'help': HELP,
92+
}
93+
MANY_VIDEO = 'Оставьте в рабочей папке только нужный видеофайл'
94+
MANY_SUBS = 'Оставьте в рабочей папке только нужный файл субтитров'
95+
NO_VIDEO = 'В рабочей папке нет видеофайлов подходящего формата'
96+
NO_AUDIO = 'В рабочей папке нет аудиофайлов подходящего формата'
97+
NO_FOLDER = 'Рабочая папка не выбрана'
98+
IN_USE = 'Закройте приложения использующие рабочие файлы'

window_utils.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import List
22
import tkinter
33
import win32gui
4+
from help_texts import HOW_TO_USE
45

56

67
def wait():
@@ -11,6 +12,14 @@ def on_closing():
1112
raise SystemExit
1213

1314

15+
def on_closing_help(
16+
master: tkinter.Tk,
17+
help_window: tkinter.Tk
18+
):
19+
master.nametowidget('help').config(state='normal')
20+
help_window.destroy()
21+
22+
1423
def buttons_freeze(master: tkinter.Tk, BUTTONS: List):
1524
for button in BUTTONS:
1625
master.nametowidget(button).config(state='disabled')
@@ -34,3 +43,36 @@ def is_reaper_run():
3443
'Сначала включите REAPER'
3544
)
3645
raise SystemExit
46+
47+
48+
def show_help_window(master: tkinter.Tk):
49+
master.nametowidget('help').config(state='disabled')
50+
master_geometry = master.geometry().split('+')[0].split('x')
51+
master_position = master.geometry().split('x')[1].split('+')[1:]
52+
x = int(master_position[0]) + int(master_geometry[0]) + 6
53+
y = master_position[1]
54+
help_window = tkinter.Tk()
55+
help_window.title('HOW TO USE')
56+
help_window.geometry(f'610x410+{x}+{y}')
57+
help_window.resizable(False, False)
58+
help_window.protocol(
59+
'WM_DELETE_WINDOW',
60+
lambda: on_closing_help(master, help_window)
61+
)
62+
text_field = tkinter.Text(help_window, background='#ffc0cb')
63+
text_field.insert('1.0', HOW_TO_USE)
64+
text_field.configure(state='disabled')
65+
scrollbar = tkinter.Scrollbar(
66+
help_window,
67+
orient='vertical',
68+
command=text_field.yview
69+
)
70+
text_field.configure(yscrollcommand=scrollbar.set)
71+
scrollbar.pack(side='right', fill='y')
72+
text_field.pack(side='left', fill='both', expand=True)
73+
help_window.focus_force()
74+
help_window.mainloop()
75+
76+
77+
if __name__ == '__main__':
78+
pass

0 commit comments

Comments
 (0)