diff --git a/lazy_player/thumbnailer.py b/lazy_player/thumbnailer.py index a446468..f30966f 100644 --- a/lazy_player/thumbnailer.py +++ b/lazy_player/thumbnailer.py @@ -1,9 +1,11 @@ from __future__ import annotations import multiprocessing +import os import sys from concurrent.futures import ThreadPoolExecutor -from typing import TYPE_CHECKING +from queue import LifoQueue +from typing import TYPE_CHECKING, Any, cast from gi.repository import GLib, Gst @@ -32,8 +34,10 @@ class Thumbnailer(ThreadPoolExecutor): max_workers=MAX_WORKERS, ) + self._work_queue = cast(Any, LifoQueue()) + def generate_thumbnail(self, file_item: FileItem): - """Schedule thumbnail generation""" + """Schedule thumbnail generation.""" if not file_item.full_path.is_file(): return @@ -41,39 +45,41 @@ class Thumbnailer(ThreadPoolExecutor): if file_item.attempted_thumbnail: return - if self._work_queue.qsize() >= MAX_WORKERS: - # print("[thumbnail] Ignoring:", file_item.full_path.name) - return - - self.submit(generate_thumbnail_sync, file_item) + self.submit(generate_thumbnail_sync_nicely, file_item) file_item.attempted_thumbnail = True +def generate_thumbnail_sync_nicely(file_item: FileItem): + os.nice(19) + return generate_thumbnail_sync(file_item) + + def generate_thumbnail_sync(file_item: FileItem): """Generate thumbnail for a single file""" # print("[thumbnailer] Generate:", file_item.full_path.name) pipeline_str = ( - "uridecodebin name=uridecodebin ! " + "uridecodebin name=uridecodebin force-sw-decoders=true ! " "videoconvert ! " "jpegenc quality=85 ! " "appsink sync=false name=sink" ) - pipeline = Gst.parse_launch(pipeline_str) - assert isinstance(pipeline, Gst.Pipeline) - - sink = pipeline.get_by_name("sink") - assert isinstance(sink, Gst.Element) - - uridecodebin = pipeline.get_by_name("uridecodebin") - assert isinstance(uridecodebin, Gst.Element) - - # Set file URI - uridecodebin.set_property("uri", Gst.filename_to_uri(str(file_item.full_path))) + pipeline: Gst.Pipeline | None = None try: + pipeline = cast(Gst.Pipeline, Gst.parse_launch(pipeline_str)) + + sink = pipeline.get_by_name("sink") + assert isinstance(sink, Gst.Element) + + uridecodebin = pipeline.get_by_name("uridecodebin") + assert isinstance(uridecodebin, Gst.Element) + + # Set file URI + uridecodebin.set_property("uri", Gst.filename_to_uri(str(file_item.full_path))) + # Set pipeline to PAUSED to get duration pipeline.set_state(Gst.State.PAUSED) pipeline.get_state(Gst.CLOCK_TIME_NONE) @@ -119,4 +125,5 @@ def generate_thumbnail_sync(file_item: FileItem): print("[thumbnailer]", err, file=sys.stderr) finally: - pipeline.set_state(Gst.State.NULL) + if pipeline: + pipeline.set_state(Gst.State.NULL)