scrub optimization
This commit is contained in:
@@ -51,6 +51,8 @@ class MonitorWidget(Gtk.Box):
|
||||
self._live_loaded = False
|
||||
|
||||
self._review_player = None
|
||||
self._scrub_offset = 0.0 # global offset of the loaded scrub source
|
||||
self._scrub_active = False # True when scrub source is loaded
|
||||
|
||||
self._stack = Gtk.Stack()
|
||||
self._stack.set_hexpand(True)
|
||||
@@ -87,6 +89,21 @@ class MonitorWidget(Gtk.Box):
|
||||
self._recording_path = path
|
||||
log.info("Recording path: %s", path)
|
||||
|
||||
def set_scrub_source(self, proxy_path, global_offset=0.0):
|
||||
"""Load a proxy file for frame-accurate scrubbing."""
|
||||
self._recording_path = proxy_path
|
||||
self._scrub_offset = global_offset
|
||||
self._scrub_active = True
|
||||
if self._review_player:
|
||||
self._review_player.load_at(proxy_path, 0, pause=True, hr_seek=True)
|
||||
self._stack.set_visible_child_name("review")
|
||||
log.info("Scrub source: %s (offset %.1fs)", proxy_path, global_offset)
|
||||
|
||||
def scrub_to(self, seconds):
|
||||
"""Seek the review player to an exact frame (for scrub bar dragging)."""
|
||||
if self._review_player:
|
||||
self._review_player.show_frame_at(seconds)
|
||||
|
||||
def get_live_position(self):
|
||||
"""Return the live player's current time_pos, or None."""
|
||||
if self._live_player:
|
||||
@@ -105,6 +122,8 @@ class MonitorWidget(Gtk.Box):
|
||||
self._live_source_url = None
|
||||
self._recording_path = None
|
||||
self._live_loaded = False
|
||||
self._scrub_active = False
|
||||
self._scrub_offset = 0.0
|
||||
if self._live_player:
|
||||
self._live_player.command("stop")
|
||||
if self._review_player:
|
||||
@@ -180,6 +199,7 @@ class MonitorWidget(Gtk.Box):
|
||||
current = self._stack.get_visible_child_name()
|
||||
|
||||
if s.live:
|
||||
self._scrub_active = False
|
||||
# Ensure live player is loaded and playing
|
||||
if self._live_player and not self._live_loaded and self._live_source_url:
|
||||
self._live_player.load_live(self._live_source_url)
|
||||
@@ -190,17 +210,22 @@ class MonitorWidget(Gtk.Box):
|
||||
if current != "live":
|
||||
self._stack.set_visible_child_name("live")
|
||||
else:
|
||||
# Scrub mode
|
||||
if current == "live":
|
||||
# Scrub / review mode
|
||||
if self._scrub_active:
|
||||
# Scrub mode: driven directly by scrub_to(), not by timeline
|
||||
if current != "review":
|
||||
self._stack.set_visible_child_name("review")
|
||||
return
|
||||
elif current == "live":
|
||||
# Transitioning from live: load MKV at cursor position atomically
|
||||
pos = s.cursor # already set by toggle_live()
|
||||
pos = s.cursor
|
||||
if self._review_player and self._recording_path:
|
||||
self._review_player.load_at(self._recording_path, pos, pause=s.paused)
|
||||
if not s.paused:
|
||||
self._review_player.play()
|
||||
self._stack.set_visible_child_name("review")
|
||||
else:
|
||||
# Already in review: seek if cursor moved, then apply pause/play
|
||||
# Already in review (non-scrub): seek if cursor moved
|
||||
if self._review_player:
|
||||
player_pos = self._review_player.time_pos or 0
|
||||
if abs(s.cursor - player_pos) > 1.0:
|
||||
@@ -212,9 +237,12 @@ class MonitorWidget(Gtk.Box):
|
||||
|
||||
def _sync_cursor_from_player(self):
|
||||
s = self._timeline.state
|
||||
if self._scrub_active:
|
||||
# Scrub mode: don't sync cursor from player — scrub bar drives cursor
|
||||
return True
|
||||
if not s.live and not s.paused and self._review_player:
|
||||
pos = self._review_player.time_pos
|
||||
if pos is not None and pos > 0:
|
||||
self._timeline.set_cursor(pos)
|
||||
# Live mode: cursor driven by tick_live() in window.py
|
||||
# Live mode: cursor driven by tick_live()
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user