def OnFileOpen(self, evt): files = dialogs.file_dialog( self, message="Choose a file", wildcard="*.*", style=wx.FD_OPEN | wx.FD_MULTIPLE | wx.FD_FILE_MUST_EXIST) if files: TrackList.add(*files)
def OnPreviewVideo(self, evt): h = TrackList.background_size()['height'] max_height = 480 scale = min(1, max_height / (h or max_height)) wx.GetApp().RunInBackground(mix.preview_thread, TrackList.all_tracks(), **TrackList.background_size(), scale=scale)
def __init__(self, parent): super().__init__(parent) self.pinned_columns = set() self._setupList() # List dragging setup self.listDragger = draglist.ListDragger(self.m_listCtrl) self.m_listCtrl.Bind(draglist.EVT_BEGIN_DRAG, self.OnDragBegin) self.m_listCtrl.Bind(draglist.EVT_DRAGGING, self.OnDragging) self.m_listCtrl.Bind(draglist.EVT_END_DRAG, self.OnDragEnd) TrackList.subscribe(self, self._refreshList)
def OnAlign(self, evt): reference = wx.GetSingleChoice( "Select a reference track", self.m_alignBtn.GetLabel(), TrackList.track_names(), parent=self ) if reference: tracks = self.GetSelectedTrackNames() or TrackList.track_names() for path in tracks: TrackList.align_track(reference, path)
def _moveItems(self, delta): # In order to update the list in-place, we need to: # - iterate forwards if delta is negative # - iterate backwards if delta is positive order = list(enumerate(TrackList.track_names())) if delta > 0: order = reversed(order) with TrackList.transaction(): for i, f in order: if f in self.dragitems: TrackList.move(i, i + delta)
def _updateLayout(self, tracks, force=False): old_tracks = set(self.m_layoutPreview.GetTrackNames()) needs_layout = set(old_tracks) != set(t['path'] for t in tracks) # Update the layout preview self.m_layoutPreview.SetTracks(tracks) self.m_layoutPreview.SetBackgroundSize(**TrackList.background_size()) # New tracks means run the layout again if tracks and (needs_layout or force): layout = TrackList.as_layout(self.video_width / self.video_height, self.video_height) TrackList.update_from_layout(layout, self.video_width, self.video_height)
def OnExportShotcut(self, evt): file = dialogs.file_dialog(self, message="Save a file", wildcard="Shotcut Files (*.mlt)|.mlt", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if file: tracks = TrackList.as_mlt_tracks() # Folks usually include an image for the background, so add a blank track # to make that possible tracks.append({'blank_track': True}) # Shotcut puts the first track at the bottom, so reverse the order tracks.reverse() with open(file, 'w') as f: f.write(mlt.xml.write_file(tracks, **TrackList.background_size()))
def OnNormalize(self, evt): target = wx.GetNumberFromUser( "Enter the normalization target", "Target LUFS", self.m_normalizeBtn.GetLabel(), value=-23, min=-50, max=-6, parent=self ) if target != -1: tracks = self.GetSelectedTrackNames() or TrackList.track_names() for path in tracks: TrackList.normalize_track(path, target)
def OnFadeOut(self, evt): seconds = dialogs.GetFloatFromUser( "Enter the fade out duration in seconds", self.m_fadeOutBtn.GetLabel(), value=1.5, min=0, max=300, parent=self ) if seconds is not None: tracks = self.GetSelectedTrackNames() or TrackList.track_names() for path in tracks: if seconds == 0: TrackList.remove_filter(path, 'fade_out') else: TrackList.set_filter(path, 'fade_out', {'duration': seconds})
def _updateVideoSize(self): m = re.match(r'(\d+)\s*x\s*(\d+)', self.m_videoSize.GetValue().strip(), re.I) if m: self.video_width = int(m.group(1)) self.video_height = int(m.group(2)) self._updateLayout(TrackList.value(video=True), force=True) else: self.m_videoSize.SetValue( f"{self.video_width}x{self.video_height}")
def _dragDelta(self, evt): # Base delta delta = evt.index - self.dragidx # Constrain delta so that the first item doesn't end up negative, and the last # item doesn't end up off the list tracks = TrackList.track_names() for i, f in enumerate(tracks): if f in self.dragitems: if i + delta < 0: delta = -i elif i + delta >= len(tracks): delta = len(tracks) - i - 1 return delta
def OnDeleteTracks(self, evt): TrackList.remove(*self.GetSelectedTrackNames())
def DoDrag(self, evt): delta = self._dragDelta(evt) self._moveItems(delta) # reset the selection for i, f in enumerate(TrackList.track_names()): self.m_listCtrl.Select(i, f in self.dragitems)
def GetSelectedTrackNames(self): """Returns a list of selected track filenames.""" return [name for i, name in enumerate(TrackList.track_names()) if self.m_listCtrl.IsSelected(i)]
def OnPreviewAudio(self, evt): wx.GetApp().RunInBackground(mix.preview_thread, TrackList.all_tracks(), **TrackList.background_size(), audio_only=True)
def GetSelectedTracks(self): """Returns a list of selected tracks.""" return [t for i, t in enumerate(TrackList.all_tracks()) if self.m_listCtrl.IsSelected(i)]
def __init__(self, parent): super().__init__(parent) TrackList.subscribe(self, self._updateLayout, video=True) self.video_width = 1280 self.video_height = 720 self._updateVideoSize()