1414
1515from pymediainfo import MediaInfo
1616
17- VERSION = "0.2.0"
17+ from src .model import VideoSequenceModel , VideoModel
18+
19+ VERSION = "0.3.0"
1820
1921
2022class FileDropTarget (wx .FileDropTarget ):
@@ -41,7 +43,8 @@ def __init__(self, parent=None):
4143 self .list_ctrl .SetDropTarget (FileDropTarget (self ))
4244
4345 self .first_selected_index = 0
44- self .item_list : list [dict ] = [] # 列表是控件上的映射,列表的物品顺序就是控件上物品的顺序
46+ # self.item_list: list[dict] = [] # 列表是控件上的映射,列表的物品顺序就是控件上物品的顺序
47+ self .video_sequence : VideoSequenceModel = VideoSequenceModel ()
4548
4649 # list_ctrl 控件添加列
4750 self .list_ctrl .InsertColumn (0 , "序号" , width = 40 )
@@ -50,6 +53,9 @@ def __init__(self, parent=None):
5053 self .list_ctrl .InsertColumn (3 , "结束时间" , width = 65 )
5154 self .list_ctrl .InsertColumn (4 , "文件路径" , width = 238 )
5255
56+ # 标记版本
57+ self .VersionText .SetLabelText (f"Simple Cut Py 版本号\n { VERSION } " )
58+
5359 # Handlers for MainFrame events.
5460
5561 # TODO: 参数初始化
@@ -64,25 +70,6 @@ def format_time(time_string: str) -> str:
6470 time_string = str .replace (time_string , ":" , ":" )
6571 return time_string
6672
67- def ApplyTimeButtonOnClick (self , event ):
68- apply_time_item_index = self .first_selected_index
69-
70- # 从控件上读取时间
71- start_time = self .StartTimeCtrl .GetValue ()
72- end_time = self .EndTimeCtrl .GetValue ()
73-
74- start_time = self .format_time (start_time )
75- end_time = self .format_time (end_time )
76-
77- # 设置物品列表的参数,如果为空就不更改
78- if not start_time == '' :
79- self .item_list [apply_time_item_index ]["start_time" ] = start_time
80- if not end_time == '' :
81- self .item_list [apply_time_item_index ]["end_time" ] = end_time
82-
83- # 更新界面
84- self .list_load_item (self .item_list [apply_time_item_index ], apply_time_item_index )
85-
8673 def AddFileBtnOnClick (self , event ):
8774 # 文件选择对话框
8875 file_dlg = wx .FileDialog (self , u"选择导入的文件" , "" , "" , "*.mp4" , wx .FD_OPEN )
@@ -115,53 +102,71 @@ def list_ctrl_on_drop_files(self, event):
115102
116103 def RemoveBtnOnClick (self , event ):
117104 # 删除列表中的项
118- delete_index = self .first_selected_index
119- self .item_list .pop (delete_index )
105+ index = self .first_selected_index
106+
107+ if index <= - 1 :
108+ return # 如果没有选中
109+
110+ if index >= len (self .video_sequence ):
111+ return # 如果超出范围
112+
113+ self .video_sequence .pop_video (index )
120114
121115 # 删除界面中的项
122116
123- self .list_ctrl .DeleteItem (delete_index )
117+ self .list_ctrl .DeleteItem (index )
124118
125119 # 删除以后进行序号重排
126- for i in range (len (self .item_list )):
127- if i < delete_index :
120+ for i in range (len (self .video_sequence )):
121+ if i < index :
128122 continue
129123
130- # 从删除项以后的每一个项的序号都要 -1
131- self .item_list [i ]["no" ] -= 1
132-
133124 # 从删除项开始后面的每一个物品都重新加载
134- self .list_load_item (self .item_list [i ], i )
125+ self .update_video_model_item (i )
126+
127+ # 选中 index
128+ self .list_ctrl .Select (index )
135129
136130 def MovUpBtnOnClick (self , event ):
137- if self .first_selected_index == - 1 :
131+ value = self .first_selected_index
132+
133+ if value == - 1 :
138134 return # 如果没有选中
139135
140- if self . first_selected_index == 0 :
136+ if value == 0 :
141137 wx .MessageBox ("选中素材已置顶。" , "错误" , style = wx .YES_DEFAULT | wx .ICON_QUESTION )
142138 return # 如果是第一个物品
143139
144- self .item_swap (self .first_selected_index , self .first_selected_index - 1 )
140+ self .video_sequence .swap_item (value , value - 1 )
141+
142+ self .update_video_model_item (value )
143+ self .update_video_model_item (value - 1 )
145144
146145 self .list_ctrl .Select (self .first_selected_index , on = 0 ) # 取消原来的选中
147146 self .list_ctrl .Select (self .first_selected_index - 1 )
148147
149148 def MovDownBtnOnClick (self , event ):
150- if self .first_selected_index == - 1 :
149+ value = self .first_selected_index
150+
151+ if value == - 1 :
151152 return # 如果没有选中
152153
153- if self . first_selected_index == self .list_ctrl .GetItemCount () - 1 :
154+ if value == self .list_ctrl .GetItemCount () - 1 :
154155 wx .MessageBox ("选中素材在最末端。" , "错误" , style = wx .YES_DEFAULT | wx .ICON_QUESTION )
155156 return # 如果是最后一个
156157
157- self .item_swap (self .first_selected_index , self .first_selected_index + 1 )
158+ self .video_sequence .swap_item (self .first_selected_index , self .first_selected_index + 1 )
159+
160+ self .update_video_model_item (value )
161+ self .update_video_model_item (value + 1 )
158162
159163 # 选中转移
160164 self .list_ctrl .Select (self .first_selected_index , on = 0 ) # 取消原来的选中
161165 self .list_ctrl .Select (self .first_selected_index + 1 )
162166
163167 def ExportBtnOnClick (self , event ):
164168 # TODO: 加了码率设置的功能,别忘了测试
169+ # TODO: item list 重写
165170
166171 # 从界面读取导出文件名、路径、码率
167172 export_name = self .ExportNameCtrl .GetValue ()
@@ -183,7 +188,7 @@ def ExportBtnOnClick(self, event):
183188 export_name = export_path + '/' + export_name
184189 else :
185190 # 默认使用第一个文件的目录
186- path = os .path .dirname (self .item_list [0 ][ " path" ] )
191+ path = os .path .dirname (self .video_sequence [0 ]. path )
187192 export_name = path + '/' + export_name
188193
189194 threading .Thread (target = self .export_video_file , args = (export_amix , export_mbps , export_name )).start ()
@@ -192,28 +197,23 @@ def ExportBtnOnClick(self, event):
192197 return
193198
194199 def export_video_file (self , export_amix , export_mbps , export_name ):
200+ # TODO: item list 重写
195201 # 导出命令
196202 console_command = 'ffmpeg '
197203 filter_complex_string = '-filter_complex '
198204 filter_complex_filters : list [str ] = []
199205 concat_inputs : list [str ] = []
200- for item in self .item_list :
201- no = item ["no" ]
202- start_time = item ["start_time" ]
203- end_time = item ["end_time" ]
204- item_path = item ["path" ]
205-
206- # 防止一些奇怪的东西
207- if start_time == '' :
208- start_time = "开头"
209- if end_time == '' :
210- end_time = "结尾"
206+ for index , item in enumerate (self .video_sequence ):
207+ no = index
208+ start_time = item .start_time
209+ end_time = item .end_time
210+ item_path = item .path
211211
212212 # 开始、结束时间以及路径的命令行参数生成
213213 time_param = []
214- if start_time != "开头 " :
214+ if start_time != "" :
215215 time_param .append (f'-ss { start_time } ' )
216- if end_time != "结尾 " :
216+ if end_time != "" :
217217 time_param .append (f'-to { end_time } ' )
218218 time_param .append (f'-i "{ item_path } "' )
219219 time_string = " " .join (time_param )
@@ -268,106 +268,78 @@ def add_files(self, item_no, filename, path):
268268 :return: 空
269269 """
270270 # 构建物品字典
271- item_dict = {"no" : item_no ,
272- "filename" : filename ,
273- "start_time" : "开头" ,
274- "end_time" : "结尾" ,
275- "path" : path
276- }
271+ item = VideoModel (path , filename )
277272
278273 # 加到物品表
279- self .item_list . append ( item_dict )
274+ self .video_sequence . append_video ( item )
280275
281276 # 显示数据在界面
282- index = self .list_ctrl .InsertItem (item_dict ["no" ], item_dict ["no" ])
283- self .list_load_item (item_dict , index )
284-
285- pass
277+ index = self .list_ctrl .InsertItem (item_no , item_no )
278+ self .update_video_model_item (index )
286279
287280 def append_files (self , filename , path ):
288281 item_no = self .list_ctrl .GetItemCount ()
289282 self .add_files (item_no , filename , path )
290283
291284 def OnStartTimeCtrlText (self , event ):
292285 """修改开始时间输入框的时候修改itemlist的start_time"""
293- first_selected_index = self .first_selected_index
286+ index = self .first_selected_index
294287 value = self .StartTimeCtrl .GetValue ()
295288
296- if value == '' :
297- value = "开头"
298- self .item_list [first_selected_index ]["start_time" ] = value
299- else :
300- self .item_list [first_selected_index ]["start_time" ] = self .format_time (value )
289+ self .video_sequence [index ].start_time = value
301290
302- self .list_load_item ( self . item_list [ first_selected_index ], first_selected_index )
291+ self .update_video_model_item ( index )
303292
304293 def OnEndTimeCtrlText (self , event ):
305294 """修改结束时间输入框的时候修改itemlist的end_time"""
306- first_selected_index = self .first_selected_index
295+ index = self .first_selected_index
307296 value = self .EndTimeCtrl .GetValue ()
308297
309- if value == '' :
310- value = "结尾"
311- self .item_list [first_selected_index ]["end_time" ] = value
312- else :
313- self .item_list [first_selected_index ]["end_time" ] = self .format_time (value )
298+ self .video_sequence [index ].end_time = value
314299
315- self .list_load_item ( self . item_list [ first_selected_index ], first_selected_index )
300+ self .update_video_model_item ( index )
316301
317302 def list_ctrl_on_selected (self , event ):
318- first_selected_index = self .list_ctrl .GetFirstSelected ()
319- self .first_selected_index = first_selected_index
303+ index = self .list_ctrl .GetFirstSelected ()
304+ self .first_selected_index = index
320305
321306 # 获取选中的物品时间,同步到输入框
322- self .StartTimeCtrl .SetValue (self .item_list [ first_selected_index ][ " start_time" ] )
323- self .EndTimeCtrl .SetValue (self .item_list [ first_selected_index ][ " end_time" ] )
307+ self .StartTimeCtrl .SetValue (self .video_sequence [ index ]. start_time )
308+ self .EndTimeCtrl .SetValue (self .video_sequence [ index ]. end_time )
324309
325310 logging .debug (
326- f"Selected Item Index: { self . first_selected_index } , \
327- Selected Item no: { self .item_list [ self . first_selected_index ]} " )
311+ f"Selected Item Index: { index } , \
312+ Selected Item no: { self .video_sequence [ index ]} " )
328313
329- def item_swap (self , item1_index , item2_index ):
330- """
331- 交换物品函数。会交换物品在列表的序号,位置,并更新控件上的位置
332- :param item1_index: 交换的物品 1
333- :param item2_index: 交换的物品 2
334- :return:
335- """
314+ def update_video_model_item (self , no ):
315+ self .load_video_model_item (self .video_sequence [no ], no )
336316
337- # 更新物品列表的序号
338- temp = self .item_list [item1_index ]["no" ]
339- self .item_list [item1_index ]["no" ] = self .item_list [item2_index ]["no" ]
340- self .item_list [item2_index ]["no" ] = temp
317+ def update_sequence_model (self ):
318+ self .load_sequence_model (self .video_sequence )
341319
342- # 更新物品列表的位置
343- temp = self .item_list [item1_index ]
344- self .item_list [item1_index ] = self .item_list [item2_index ]
345- self .item_list [item2_index ] = temp
346-
347- # 交换用户界面上的显示
348- self .list_load_item (self .item_list [item1_index ], self .item_list [item1_index ]["no" ])
349- self .list_load_item (self .item_list [item2_index ], self .item_list [item2_index ]["no" ])
350-
351- def list_load_item (self , load_item , list_ctrl_index ):
320+ def load_video_model_item (self , load_item : VideoModel , list_ctrl_index : int ):
352321 """
353- 把物品列表上的物品载入到用户界面的控件上
322+ 将 VideoModel 载入到 列表item上
354323 :param load_item: 载入的物品
355324 :param list_ctrl_index: 载入在控件的行数
356325 :return: 无
357326 """
358- self .list_ctrl .SetItem (list_ctrl_index , 0 , str (load_item ["no" ]))
359- self .list_ctrl .SetItem (list_ctrl_index , 1 , load_item ["filename" ])
360- self .list_ctrl .SetItem (list_ctrl_index , 2 , load_item ["start_time" ])
361- self .list_ctrl .SetItem (list_ctrl_index , 3 , load_item ["end_time" ])
362- self .list_ctrl .SetItem (list_ctrl_index , 4 , load_item ["path" ])
327+ self .list_ctrl .SetItem (list_ctrl_index , 0 , str (list_ctrl_index ))
328+ self .list_ctrl .SetItem (list_ctrl_index , 1 , load_item .filename )
329+
330+ start_time = "开头" if load_item .start_time == "" else load_item .start_time
331+ end_time = "结尾" if load_item .end_time == "" else load_item .end_time
332+ self .list_ctrl .SetItem (list_ctrl_index , 2 , start_time )
333+ self .list_ctrl .SetItem (list_ctrl_index , 3 , end_time )
334+ self .list_ctrl .SetItem (list_ctrl_index , 4 , load_item .path )
363335
364- def list_load_all_item (self ):
336+ def load_sequence_model (self , sequence : VideoSequenceModel ):
365337 """
366338 把物品列表上的所有物品载入到用户界面的控件上
367339 :return:
368340 """
369- for item in self . item_list :
370- self .list_load_item (item , item [ "no" ] )
341+ for index , item in enumerate ( sequence ) :
342+ self .load_video_model_item (item , index )
371343
372344 def on_export_done (self , msg : ExportMessage ):
373345 logging .debug (f"Export Done: { msg } " )
0 commit comments