feat: cache waveform data to disk, skip ffmpeg on reload
Waveform peaks are saved as .npy files keyed by MD5 of the video path. Subsequent loads of the same video read from cache instead of re-running ffmpeg extraction. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1368,8 +1368,14 @@ class ScanResultsPanel(QWidget):
|
|||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
|
|
||||||
|
_WAVEFORM_CACHE_DIR = os.path.join(
|
||||||
|
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||||
|
"cache", "waveforms",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class WaveformWorker(QThread):
|
class WaveformWorker(QThread):
|
||||||
"""Extract a low-res waveform envelope in the background."""
|
"""Extract a low-res waveform envelope in the background (with disk cache)."""
|
||||||
done = pyqtSignal(object) # emits numpy array of peak values
|
done = pyqtSignal(object) # emits numpy array of peak values
|
||||||
|
|
||||||
def __init__(self, video_path: str, n_bins: int = 2000):
|
def __init__(self, video_path: str, n_bins: int = 2000):
|
||||||
@@ -1377,9 +1383,22 @@ class WaveformWorker(QThread):
|
|||||||
self._path = video_path
|
self._path = video_path
|
||||||
self._n_bins = n_bins
|
self._n_bins = n_bins
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _cache_path(video_path: str) -> str:
|
||||||
|
import hashlib
|
||||||
|
h = hashlib.md5(video_path.encode()).hexdigest()
|
||||||
|
return os.path.join(_WAVEFORM_CACHE_DIR, f"{h}.npy")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
import numpy as np
|
import numpy as np
|
||||||
try:
|
try:
|
||||||
|
# Check cache first
|
||||||
|
cache = self._cache_path(self._path)
|
||||||
|
if os.path.exists(cache):
|
||||||
|
peaks = np.load(cache)
|
||||||
|
self.done.emit(peaks)
|
||||||
|
return
|
||||||
|
|
||||||
cmd = [
|
cmd = [
|
||||||
_bin("ffmpeg"), "-i", self._path,
|
_bin("ffmpeg"), "-i", self._path,
|
||||||
"-vn", "-ac", "1", "-ar", "8000",
|
"-vn", "-ac", "1", "-ar", "8000",
|
||||||
@@ -1399,6 +1418,9 @@ class WaveformWorker(QThread):
|
|||||||
mx = peaks.max()
|
mx = peaks.max()
|
||||||
if mx > 0:
|
if mx > 0:
|
||||||
peaks = peaks / mx
|
peaks = peaks / mx
|
||||||
|
# Save to cache
|
||||||
|
os.makedirs(_WAVEFORM_CACHE_DIR, exist_ok=True)
|
||||||
|
np.save(cache, peaks)
|
||||||
self.done.emit(peaks)
|
self.done.emit(peaks)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user