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