Improve thumbnailing process
This commit is contained in:
parent
4985de9ca8
commit
0972dbd238
3 changed files with 35 additions and 19 deletions
lazy_player
|
@ -8,6 +8,8 @@ from typing import Optional, overload
|
|||
|
||||
from gi.repository import Gio, GObject
|
||||
|
||||
from .thumbnailer import Thumbnailer
|
||||
|
||||
|
||||
class FileType(Enum):
|
||||
DIRECTORY = auto()
|
||||
|
@ -18,6 +20,8 @@ class FileItem(GObject.Object):
|
|||
file_type: FileType
|
||||
full_path: Path
|
||||
thumbnail: bytes
|
||||
attempted_thumbnail: bool
|
||||
|
||||
_has_thumbnail: bool
|
||||
|
||||
__gtype_name__ = "FileItem"
|
||||
|
@ -28,6 +32,7 @@ class FileItem(GObject.Object):
|
|||
self.file_type = file_type
|
||||
self.full_path = full_path
|
||||
self.thumbnail = b""
|
||||
self.attempted_thumbnail = False
|
||||
self._has_thumbnail = False
|
||||
|
||||
@GObject.Property(type=GObject.TYPE_UINT64)
|
||||
|
@ -75,6 +80,13 @@ class FileItem(GObject.Object):
|
|||
self._has_thumbnail = value
|
||||
self.notify("has-thumbnail")
|
||||
|
||||
def ensure_thumbnail(self, thumbnailer: Thumbnailer):
|
||||
if self.thumbnail or self.attempted_thumbnail:
|
||||
return
|
||||
|
||||
if not self.attempted_thumbnail:
|
||||
thumbnailer.generate_thumbnail(self)
|
||||
|
||||
@overload
|
||||
def _load_attribute(self, name: str, dfl: str) -> str: ...
|
||||
|
||||
|
|
|
@ -246,21 +246,20 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
item.connect("notify::saved-duration", update_icon)
|
||||
update_icon()
|
||||
|
||||
def _refresh(self):
|
||||
self._populate_file_list()
|
||||
|
||||
pos = self.selection_history.get(str(os.getcwd()), 0)
|
||||
def _restore_selection(self):
|
||||
pos = self.selection_history.get(os.getcwd(), 0)
|
||||
self.selection_model.set_selected(pos)
|
||||
self.list_view.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, None)
|
||||
|
||||
def _refresh(self):
|
||||
self._populate_file_list()
|
||||
self._restore_selection()
|
||||
|
||||
def _navigate_to(self, path: Path):
|
||||
self.directory_history.append(Path(os.getcwd()))
|
||||
os.chdir(path)
|
||||
self._populate_file_list()
|
||||
|
||||
pos = self.selection_history.get(str(path), 0)
|
||||
self.selection_model.set_selected(pos)
|
||||
self.list_view.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, None)
|
||||
self._restore_selection()
|
||||
|
||||
def _navigate_back(self):
|
||||
if not self.directory_history:
|
||||
|
@ -269,10 +268,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
prev_dir = self.directory_history.pop()
|
||||
os.chdir(prev_dir)
|
||||
self._populate_file_list()
|
||||
|
||||
pos = self.selection_history.get(str(prev_dir), 0)
|
||||
self.selection_model.set_selected(pos)
|
||||
self.list_view.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, None)
|
||||
self._restore_selection()
|
||||
|
||||
def _on_selection_changed(
|
||||
self,
|
||||
|
@ -287,8 +283,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
|
||||
self.selection_history[os.getcwd()] = position
|
||||
|
||||
file_item = self.selection
|
||||
if file_item is not None:
|
||||
if file_item := self.selection:
|
||||
# Update thumbnail if available
|
||||
if file_item.thumbnail:
|
||||
gbytes = GLib.Bytes.new(cast(Any, file_item.thumbnail))
|
||||
|
@ -475,9 +470,9 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
self.last_position_save = frame_time
|
||||
|
||||
# Update thumbnail if available
|
||||
file_item = self.selection
|
||||
if file_item := self.selection:
|
||||
file_item.ensure_thumbnail(self.thumbnailer)
|
||||
|
||||
if file_item is not None:
|
||||
if file_item.thumbnail and not self.thumbnail_image.get_paintable():
|
||||
gbytes = GLib.Bytes.new(cast(Any, file_item.thumbnail))
|
||||
texture = Gdk.Texture.new_from_bytes(gbytes)
|
||||
|
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||
import threading
|
||||
from queue import Empty, Queue
|
||||
|
||||
from gi.repository import Gst
|
||||
from gi.repository import GLib, Gst
|
||||
|
||||
from .file_model import FileItem
|
||||
|
||||
|
@ -28,6 +28,7 @@ class Thumbnailer(threading.Thread):
|
|||
self.queue.get_nowait()
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
self.queue.put_nowait(file_item)
|
||||
|
||||
def stop(self):
|
||||
|
@ -51,6 +52,7 @@ class Thumbnailer(threading.Thread):
|
|||
if file_item is None:
|
||||
break
|
||||
|
||||
file_item.attempted_thumbnail = True
|
||||
self._generate_thumbnail(file_item)
|
||||
|
||||
def _generate_thumbnail(self, file_item: FileItem):
|
||||
|
@ -105,11 +107,18 @@ class Thumbnailer(threading.Thread):
|
|||
return
|
||||
|
||||
try:
|
||||
file_item.thumbnail = bytes(map_info.data)
|
||||
file_item.has_thumbnail = True
|
||||
thumbnail = bytes(map_info.data)
|
||||
finally:
|
||||
buffer.unmap(map_info)
|
||||
|
||||
def set_thumbnail():
|
||||
file_item.thumbnail = thumbnail
|
||||
file_item.has_thumbnail = True
|
||||
|
||||
GLib.idle_add(set_thumbnail)
|
||||
|
||||
except Exception as err:
|
||||
print("Failed:", file_item.full_path, err)
|
||||
|
||||
finally:
|
||||
pipeline.set_state(Gst.State.NULL)
|
||||
|
|
Loading…
Reference in a new issue