-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSimpleCutMainFrame.py
More file actions
385 lines (296 loc) · 12.6 KB
/
SimpleCutMainFrame.py
File metadata and controls
385 lines (296 loc) · 12.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# TODO: 文件路径其实没有把文件名显示出来
"""Subclass of MainFrame, which is generated by wxFormBuilder."""
from export.model import VideoFile
import export
from controller.core import CoreController
import logging
import os
import webbrowser
import wx
import meta
import SimpleCutPy
from message import ExportMessage, WorkStateEnum
class FileDropTarget(wx.FileDropTarget):
def __init__(self, target: "SimpleCutPyMainFrame"):
wx.FileDropTarget.__init__(self)
self.target = target
def OnDropFiles(self, x, y, filenames):
logging.debug(f"FileDropTarget 拖拽文件:{filenames}")
for file in filenames:
filepath, filename = os.path.split(file)
logging.debug(f"解析文件:{file} -> 路径: {filepath}, 文件名: {filename}")
self.target.core_controller.add_file(filename, filepath)
self.target.update_video_sequence_view()
return True
# Implementing MainFrame
class SimpleCutPyMainFrame(SimpleCutPy.MainFrame):
def __init__(self, parent=None):
SimpleCutPy.MainFrame.__init__(self, parent)
# 设置标题
self.SetTitle(f"Simple Cut Py {meta.VERSION}")
# 设置拖拽文件
self.list_ctrl.SetDropTarget(FileDropTarget(self))
self.first_selected_index = 0
# list_ctrl 控件添加列
self.list_ctrl.InsertColumn(0, "序号", width=40)
self.list_ctrl.InsertColumn(1, "文件名", width=280)
self.list_ctrl.InsertColumn(2, "开始时间", width=65)
self.list_ctrl.InsertColumn(3, "结束时间", width=65)
self.list_ctrl.InsertColumn(4, "文件路径", width=238)
# 标记版本
self.VersionText.SetLabelText(f"Simple Cut Py 版本号\n{meta.VERSION}")
self.core_controller = CoreController(self)
self.on_size_control_mode_change(None)
def _bind_event(self):
pass
def on_add_file_button_click(self, event):
# 文件选择对话框
file_dlg = wx.FileDialog(self, "选择导入的文件", "", "", "*.mp4", wx.FD_OPEN)
if file_dlg.ShowModal() == wx.ID_OK:
# 导入文件
filepath = file_dlg.GetPath()
for filename in file_dlg.GetFilenames():
self.core_controller.add_file(filename, filepath)
logging.debug("导入文件:{}, {}".format(filename, filepath))
self.update_video_sequence_view()
file_dlg.Destroy()
def on_remove_file_button_click(self, event):
# 删除列表中的项
target_idx = self.core_controller.first_select_index
if target_idx <= -1:
return # 如果没有选中
if target_idx >= self.core_controller.sequence_length():
return # 如果超出范围
self.core_controller.remove_file(target_idx)
self.update_video_sequence_view()
# 选中 index
if target_idx < self.core_controller.sequence_length():
self.list_ctrl.Select(target_idx)
elif self.core_controller.sequence_length() > 0:
self.list_ctrl.Select(self.core_controller.sequence_length() - 1)
def on_move_up_file_button_click(self, event):
logging.debug(
f"on_move_up_file_button_click: {self.core_controller.first_select_index}"
)
idx = self.core_controller.first_select_index
if idx == -1:
return # 如果没有选中
if idx == 0:
wx.MessageBox(
"选中素材已置顶。", "错误", style=wx.YES_DEFAULT | wx.ICON_QUESTION
)
return # 如果是第一个物品
self.core_controller.swap_file(idx, idx - 1)
self.update_video_sequence_view()
self.list_ctrl.Select(idx, on=0) # 取消原来的选中
self.list_ctrl.Select(idx - 1)
def on_move_down_file_button_click(self, event):
logging.debug(
f"on_move_down_file_button_click: {self.core_controller.first_select_index}"
)
idx = self.core_controller.first_select_index
if idx == -1:
return # 如果没有选中
if idx == self.list_ctrl.GetItemCount() - 1:
wx.MessageBox(
"选中素材在最末端。", "错误", style=wx.YES_DEFAULT | wx.ICON_QUESTION
)
return # 如果是最后一个
self.core_controller.swap_file(idx, idx + 1)
self.update_video_sequence_view()
# 选中转移
self.list_ctrl.Select(idx, on=0) # 取消原来的选中
self.list_ctrl.Select(idx + 1)
def on_export_button_click(self, event):
# 获取文件名路径
self.core_controller.task.export_file_name = self.ExportNameCtrl.GetValue()
self.core_controller.task.export_file_path = self.ExportPathCtrl.GetValue()
# 读取配置
self.get_export_config()
# 导出
self.core_controller.export_sequence()
self.ExportBtn.Disable()
return
def on_open_project_website_button_click(self, event):
webbrowser.open("https://github.com/FishCat233/SimpleCutPy")
def on_clear_all_button_click(self, event):
self.core_controller.clear_all_files()
logging.debug(
f"clear all video: {self.core_controller.task.video_sequence.get_video_list()}"
)
self.update_video_sequence_view()
def on_start_time_ctrl_text(self, event):
"""修改开始时间输入框的时候修改itemlist的start_time"""
index = self.core_controller.first_select_index
value = self.StartTimeCtrl.GetValue()
# 尝试更新数据
videofile = self.core_controller.get_file(index)
videofile.start_time = self.core_controller.format_time(value)
self.update_video_file_view(index, videofile)
def on_end_time_ctrl_text(self, event):
"""修改结束时间输入框的时候修改itemlist的end_time"""
index = self.core_controller.first_select_index
value = self.EndTimeCtrl.GetValue()
# 尝试更新数据
videofile = self.core_controller.get_file(index)
videofile.end_time = self.core_controller.format_time(value)
self.update_video_file_view(index, videofile)
def on_list_item_selected(self, event):
index = self.list_ctrl.GetFirstSelected()
self.core_controller.first_select_index = index
# 获取选中的物品时间,同步到输入框
self.StartTimeCtrl.SetValue(self.core_controller.get_file(index).start_time)
self.EndTimeCtrl.SetValue(self.core_controller.get_file(index).end_time)
logging.debug(
f"Selected Item Index: {index}, \
Selected Item no: {self.core_controller.get_file(index)}"
)
def on_export_done(self, msg: ExportMessage):
logging.debug(f"Export Done: {msg}")
if msg.state == WorkStateEnum.SUCCESS:
wx.MessageBox("导出成功", "提示", wx.OK | wx.ICON_INFORMATION)
elif msg.state == WorkStateEnum.FAIL:
logging.error(f"Export Error: {msg.message}")
wx.MessageBox("导出失败", "提示", wx.OK | wx.ICON_INFORMATION)
if len(self.core_controller.working_thread) == 0:
self.ExportBtn.Enable()
return
def on_size_control_mode_change(self, event):
size_control_mode = "none"
match self.SizeControlMode.GetSelection():
case 0:
size_control_mode = "x264"
case 1:
size_control_mode = "mbps"
case _:
size_control_mode = "none"
logging.debug(f"SizeControlMode: {size_control_mode}")
# 如果不是 mbps 则隐藏,否则显示
if size_control_mode == "mbps":
self.MbpsCtrl.Enable()
else:
self.MbpsCtrl.Disable()
return
def update_video_file_view(self, index: int, file: VideoFile):
"""将 VideoFile 载入到 列表item上
Args:
index (int): 列表项索引
file (VideoFile): 要载入的视频文件
"""
logging.debug(f"update_video_file_view: {file}, index: {index}")
# 确保列表控件中有足够的项
while index >= self.list_ctrl.GetItemCount():
self.list_ctrl.InsertItem(self.list_ctrl.GetItemCount(), "")
self.list_ctrl.SetItem(index, 0, str(index + 1))
self.list_ctrl.SetItem(index, 1, file.file_name)
self.list_ctrl.SetItem(index, 2, file.start_time)
self.list_ctrl.SetItem(index, 3, file.end_time)
self.list_ctrl.SetItem(index, 4, file.file_path)
def update_video_sequence_view(self, index=-1) -> None:
"""更新视频序列视图
Args:
index (int, optional): 要更新的视频序列索引. 默认-1表示更新所有.
"""
sequence = self.core_controller.task.video_sequence.get_video_list()
logging.debug(f"update_video_sequence_view: {index}, sequence: {sequence}")
if index == -1:
# 清空列表,然后重新添加所有条目,避免空白条目
self.list_ctrl.DeleteAllItems()
for i, item in enumerate(sequence):
# 直接添加到列表末尾
self.list_ctrl.InsertItem(i, str(i + 1))
self.list_ctrl.SetItem(i, 1, item.file_name)
self.list_ctrl.SetItem(i, 2, item.start_time)
self.list_ctrl.SetItem(i, 3, item.end_time)
self.list_ctrl.SetItem(i, 4, item.file_path)
return
# 只更新单个条目
if index < len(sequence):
self.update_video_file_view(index, sequence[index])
def update_export_config_view(self) -> None:
"""更新导出配置视图"""
export_config = self.core_controller.task.export_config
match export_config.size_control:
case export.model.X264Config():
self.SizeControlMode.SetSelection(0)
case export.model.MbpsConfig():
self.SizeControlMode.SetSelection(1)
self.MbpsCtrl.SetValue(str(export_config.size_control.mbps))
case None:
self.SizeControlMode.SetSelection(2)
case _:
self.SizeControlMode.SetSelection(0)
match export_config.multi_track_mode:
case "first":
self.MultiTrackMode.SetSelection(0)
case "amix":
self.MultiTrackMode.SetSelection(1)
case "export_both":
self.MultiTrackMode.SetSelection(2)
case _:
self.MultiTrackMode.SetSelection(0)
def get_export_config(self) -> None:
"""
获取导出配置到模型
"""
size_control_mode = self.size_control_idx_to_enum(
self.SizeControlMode.GetSelection()
)
match size_control_mode:
case "x264":
size_control = export.model.X264Config()
case "mbps":
size_control = export.model.MbpsConfig(
mbps=float(self.MbpsCtrl.GetValue())
)
case "none":
size_control = None
case _:
size_control = None
multi_track_mode = self.multi_track_select_idx_to_enum(
self.MultiTrackMode.GetSelection()
)
export_config = export.model.ExportConfig(
size_control=size_control,
multi_track_mode=multi_track_mode,
)
self.core_controller.setup_export_config(export_config)
@staticmethod
def size_control_idx_to_enum(idx: int):
"""将大小控制模式选择框索引转换为枚举值
Args:
idx (int): 大小控制模式选择框索引
Returns:
SizeControlMode: 大小控制模式枚举值
"""
match idx:
case 0:
return "x264"
case 1:
return "mbps"
case 2:
return "none"
case _:
return "none"
@staticmethod
def multi_track_select_idx_to_enum(idx: int):
"""将多轨道模式选择框索引转换为枚举值
Args:
idx (int): 多轨道模式选择框索引
Returns:
MultiTrackMode: 多轨道模式枚举值
"""
match idx:
case 0:
return "first"
case 1:
return "amix"
case 2:
return "export_both"
case _:
return "first"
if __name__ == "__main__":
App = wx.App()
mainFrame = SimpleCutPyMainFrame(None)
mainFrame.Show(True)
App.MainLoop()