feat: add heal cut editor action
This commit is contained in:
@@ -39,7 +39,7 @@ from core.ffmpeg import (
|
||||
build_ffmpeg_command, build_audio_extract_command, build_audio_clip_command,
|
||||
build_crossfade_merge_command,
|
||||
build_audio_delete_command, build_audio_silence_command,
|
||||
build_audio_reverse_command,
|
||||
build_audio_reverse_command, build_audio_heal_delete_command,
|
||||
audio_edit_filters, probe_duration, detect_hw_encoders,
|
||||
)
|
||||
from core.db import ProcessedDB
|
||||
@@ -4248,8 +4248,10 @@ class AudioEditorDialog(QDialog):
|
||||
self._last_saved = None # path of the last Save-as (for library)
|
||||
self._play_proc = None # ffplay audition process
|
||||
self._clip_dur = 0.0 # true duration of the current version
|
||||
self._join_preview: tuple[float, float] | None = None
|
||||
|
||||
self._wave = AudioWaveform()
|
||||
self._btn_heal_cut = QPushButton("Heal Cut")
|
||||
self._btn_delete = QPushButton("Delete")
|
||||
self._btn_silence = QPushButton("Silence")
|
||||
self._btn_reverse = QPushButton("Reverse")
|
||||
@@ -4260,7 +4262,8 @@ class AudioEditorDialog(QDialog):
|
||||
self._btn_play.setCheckable(True)
|
||||
self._btn_save_as = QPushButton("Save as…")
|
||||
self._btn_close = QPushButton("Close")
|
||||
for b, slot in ((self._btn_delete, self._on_delete),
|
||||
for b, slot in ((self._btn_heal_cut, self._on_heal_cut),
|
||||
(self._btn_delete, self._on_delete),
|
||||
(self._btn_silence, self._on_silence),
|
||||
(self._btn_reverse, self._on_reverse),
|
||||
(self._btn_trim, self._on_trim),
|
||||
@@ -4274,6 +4277,7 @@ class AudioEditorDialog(QDialog):
|
||||
outer = QVBoxLayout(self)
|
||||
outer.addWidget(self._wave)
|
||||
ops = QHBoxLayout()
|
||||
ops.addWidget(self._btn_heal_cut)
|
||||
for b in (self._btn_delete, self._btn_silence, self._btn_reverse,
|
||||
self._btn_trim):
|
||||
ops.addWidget(b)
|
||||
@@ -4326,7 +4330,8 @@ class AudioEditorDialog(QDialog):
|
||||
return None
|
||||
return (s, e)
|
||||
|
||||
def _apply_op(self, build_fn, whole_clip_ok: bool = True) -> None:
|
||||
def _apply_op(self, build_fn, whole_clip_ok: bool = True,
|
||||
after_success=None) -> None:
|
||||
se = self._selection_secs()
|
||||
if se is None:
|
||||
self._set_status("Select a region first")
|
||||
@@ -4354,6 +4359,8 @@ class AudioEditorDialog(QDialog):
|
||||
self._ver_idx += 1
|
||||
self._temps.add(tmp)
|
||||
self._reload()
|
||||
if after_success is not None:
|
||||
after_success(s)
|
||||
self._set_status("")
|
||||
else:
|
||||
try:
|
||||
@@ -4362,6 +4369,13 @@ class AudioEditorDialog(QDialog):
|
||||
pass
|
||||
self._set_status("Edit failed")
|
||||
|
||||
def _prepare_join_preview(self, seam_t: float) -> None:
|
||||
self._join_preview = (max(0.0, seam_t - 1.0), seam_t + 1.0)
|
||||
|
||||
def _on_heal_cut(self):
|
||||
self._apply_op(build_audio_heal_delete_command, whole_clip_ok=False,
|
||||
after_success=self._prepare_join_preview)
|
||||
|
||||
def _on_delete(self):
|
||||
self._apply_op(build_audio_delete_command, whole_clip_ok=False)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user