aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/sound/Player.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/sound/Player.qml')
-rw-r--r--desktop/modules/sound/Player.qml37
1 files changed, 35 insertions, 2 deletions
diff --git a/desktop/modules/sound/Player.qml b/desktop/modules/sound/Player.qml
index e32a1b9..7522d80 100644
--- a/desktop/modules/sound/Player.qml
+++ b/desktop/modules/sound/Player.qml
@@ -12,6 +12,7 @@
pragma Singleton
import Quickshell
+import Quickshell.Io
import Quickshell.Services.Mpris
import QtQuick
@@ -59,6 +60,38 @@ Singleton {
// per track, so the path can repeat while the image behind it changes.
// The cache buster makes Image reload instead of showing the last cover.
readonly property string artUrl:
- (current?.trackArtUrl ?? "") === "" ? ""
- : current.trackArtUrl + "#" + encodeURIComponent(title)
+ (current?.trackArtUrl ?? "") !== ""
+ ? current.trackArtUrl + "#" + encodeURIComponent(title)
+ : (videoUrl !== "" && thumbFor === videoUrl)
+ ? "file://" + thumbPath + "#" + encodeURIComponent(videoUrl) : ""
+
+ // Haruna clears mpris:artUrl for every video on purpose (so the task
+ // manager shows the live window), so a local video with no cover gets a
+ // frame grabbed by ffmpeg instead. One file, overwritten per video; the
+ // URL fragment above makes Image reload it.
+ readonly property string videoUrl: {
+ const url = String(current?.metadata?.["xesam:url"] ?? "");
+ return (current?.trackArtUrl ?? "") === "" && url.startsWith("file://")
+ && /\.(mp4|m4v|mkv|webm|avi|mov|wmv|flv|mpe?g|ts|ogv)$/i.test(url) ? url : "";
+ }
+ readonly property string thumbPath: (Quickshell.env("XDG_RUNTIME_DIR") || "/tmp") + "/qs-video-thumb.jpg"
+ property string thumbFor: ""
+
+ onVideoUrlChanged: grab()
+ Component.onCompleted: grab()
+
+ function grab() {
+ if (videoUrl === "") return;
+ thumb.running = false;
+ thumb.url = videoUrl;
+ thumb.command = ["ffmpeg", "-y", "-v", "error", "-i", decodeURIComponent(videoUrl.slice(7)),
+ "-vf", "thumbnail,scale=480:-2", "-frames:v", "1", thumbPath];
+ thumb.running = true;
+ }
+
+ Process {
+ id: thumb
+ property string url: ""
+ onExited: code => { if (code === 0) root.thumbFor = url; }
+ }
}