mpv-config icon indicating copy to clipboard operation
mpv-config copied to clipboard

[Feature Request] seek-to.lua - Paste a frame number and seek to it

Open KonoVitoDa opened this issue 2 years ago • 1 comments

KonoVitoDa avatar Dec 17 '22 19:12 KonoVitoDa

I've been testing locally, but it's pretty unreliable so far (i.e. it's always off by 1 frame). The first issue is, mpv only accepts seeking by seconds, timestamps or percentage. So in order to seek by frame number, I must first convert it into one of those. I can either convert the frame number to percentage using pasted_frame_number / estimated-frame-count * 100 OR convert it into seconds using pasted_frame_number * container-fps. However, as noted by the mpv manual, all of these properties are inaccurate and only an estimation.

To quote from the mpv docs:

estimated-frame-count Total number of frames in current file.

Note This is only an estimate. (It's computed from two unreliable quantities: fps and stream length.)

estimated-frame-number Number of current frame in current stream.

Note This is only an estimate. (It's computed from two unreliable quantities: fps and possibly rounded timestamps.)

container-fps Container FPS. This can easily contain bogus values. For videos that use modern container formats or video codecs, this will often be incorrect. (Renamed from fps.)

Is there any reasons you want to seek by frame number instead of seconds, the latter which is more accurate? FYI, I normally use SmartCopyPaste to copy the seconds and seek.

If you insist, this is what I have so far:
diff --git a/scripts/seek-to.lua b/scripts/seek-to.lua
index 28516a5..5762fc1 100644
--- a/scripts/seek-to.lua
+++ b/scripts/seek-to.lua
@@ -183,5 +183,37 @@ function paste_timestamp()
     end
 end
 
+function paste_frame_number()
+    -- get clipboard data
+    local clipboard = utils.subprocess({
+        args = { "powershell", "-Command", "Get-Clipboard", "-Raw" },
+        playback_only = false,
+        capture_stdout = true,
+        capture_stderr = true
+    })
+
+    -- error handling
+    if not clipboard.error then
+        timestamp = clipboard.stdout
+    else
+        msg.error("Error getting data from clipboard:")
+        msg.error("  stderr: " .. clipboard.stderr)
+        msg.error("  stdout: " .. clipboard.stdout)
+        return
+    end
+
+    -- find timestamp from clipboard
+    match = timestamp:match("%d+")
+
+    -- paste and seek to timestamp
+    if match ~= nil then
+        mp.osd_message("Timestamp pasted: " .. match)
+        percent = match / mp.get_property_number("estimated-frame-count") * 100
+        print(percent)
+        mp.commandv("osd-bar", "seek", percent, "absolute-percent+exact")
+    end
+end
+
 mp.add_key_binding(nil, "toggle-seeker", function() if active then set_inactive() else set_active() end end)
 mp.add_key_binding("ctrl+alt+v", "paste-timestamp", paste_timestamp)
+mp.add_key_binding("ctrl+alt+V", "paste-framenum", paste_frame_number)

dexeonify avatar Dec 18 '22 10:12 dexeonify