summaryrefslogtreecommitdiff
path: root/ar
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-06-04 00:56:31 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-06-04 00:56:31 +0900
commit998cbc36e2917a270315f110087881bdb1e63a52 (patch)
treeab31949059b2c4d13cdbcecdfbbc5cb328dd8f50 /ar
parent9b8cda63dd0ec81458a0e52cb18df00630daa236 (diff)
modified mpv/input.conf, created scripts/slicing.lua
Diffstat (limited to 'ar')
-rw-r--r--ar/.config/mpv/input.conf2
-rw-r--r--ar/.config/mpv/scripts/slicing.lua111
2 files changed, 113 insertions, 0 deletions
diff --git a/ar/.config/mpv/input.conf b/ar/.config/mpv/input.conf
index de78dcc..ef86749 100644
--- a/ar/.config/mpv/input.conf
+++ b/ar/.config/mpv/input.conf
@@ -41,6 +41,8 @@ alt+shift+e add audio-delay 1.000
space cycle pause # Toggle pause/playback mode
s cycle pause # Toggle pause/playback mode
ctrl+PRINT script-binding crop-screenshot # Crop screenshot
+o script-binding slicing/set-start # Set lossless cut start point
+O script-binding slicing/set-end # Set lossless cut end point and export
ctrl+l script-message-to misc cycle-known-tracks audio # Loop auidio
shift+l no-osd seek 30 exact; script-message-to misc show-position # Seek exactly 1 second forward
shift+h no-osd seek -30 exact; script-message-to misc show-position # Seek exactly 1 second backward
diff --git a/ar/.config/mpv/scripts/slicing.lua b/ar/.config/mpv/scripts/slicing.lua
new file mode 100644
index 0000000..2653ce8
--- /dev/null
+++ b/ar/.config/mpv/scripts/slicing.lua
@@ -0,0 +1,111 @@
+-- slicing.lua — lossless video trimming via ffmpeg stream copy
+--
+-- Press the "set start" key once to mark A, then the "set end" key to mark B.
+-- The marked [A, B] range is cut losslessly (-c copy) into a new file next to
+-- the source, named "<name>_cut_<start>-<end>.<ext>". No re-encoding, so the
+-- cut snaps to the nearest preceding keyframe (fast, but not frame-exact).
+--
+-- Default bindings (set in input.conf):
+-- o script-binding slicing/set-start
+-- O script-binding slicing/set-end
+
+local mp = require "mp"
+local msg = require "mp.msg"
+local utils = require "mp.utils"
+
+local start_time = nil
+
+local function osd(text, dur)
+ mp.osd_message(text, dur or 3)
+ msg.info(text)
+end
+
+-- 12.345 -> "00:00:12.345" for filenames / logging
+local function fmt(t)
+ local h = math.floor(t / 3600)
+ local m = math.floor((t % 3600) / 60)
+ local s = t % 60
+ return string.format("%02d:%02d:%06.3f", h, m, s)
+end
+
+-- whole-seconds token for filenames: 12.345 -> "12"
+local function fmt_tag(t)
+ return string.format("%d", math.floor(t + 0.5))
+end
+
+local function set_start()
+ start_time = mp.get_property_number("time-pos")
+ if not start_time then return end
+ osd(("Cut start: %s"):format(fmt(start_time)))
+end
+
+local function set_end()
+ local end_time = mp.get_property_number("time-pos")
+ if not end_time then return end
+
+ if not start_time then
+ osd("Set the start point first (o)")
+ return
+ end
+ if end_time <= start_time then
+ osd("End point must be after the start point")
+ return
+ end
+
+ local path = mp.get_property("path")
+ if not path then
+ osd("No file is playing")
+ return
+ end
+ -- only local files can be stream-copied this way
+ if path:find("^%a[%w+.-]*://") then
+ osd("Cannot cut a stream (local files only)")
+ return
+ end
+
+ local dir, name = utils.split_path(path)
+ local stem, ext = name:match("^(.*)%.([^.]+)$")
+ if not stem then
+ stem, ext = name, "mkv"
+ end
+
+ local out = utils.join_path(dir, string.format(
+ "%s_cut_%s-%s.%s", stem, fmt_tag(start_time), fmt_tag(end_time), ext))
+
+ local duration = end_time - start_time
+
+ local args = {
+ "ffmpeg", "-y",
+ "-ss", string.format("%.3f", start_time),
+ "-i", path,
+ "-t", string.format("%.3f", duration),
+ "-map", "0",
+ "-c", "copy",
+ "-avoid_negative_ts", "make_zero",
+ out,
+ }
+
+ osd(("Cutting… %s → %s"):format(fmt(start_time), fmt(end_time)))
+ msg.info("ffmpeg: " .. table.concat(args, " "))
+
+ mp.command_native_async({
+ name = "subprocess",
+ args = args,
+ playback_only = false,
+ capture_stdout = true,
+ capture_stderr = true,
+ }, function(success, res, err)
+ if success and res and res.status == 0 then
+ local _, fname = utils.split_path(out)
+ osd(("Saved: %s"):format(fname))
+ start_time = nil
+ else
+ local detail = (res and res.stderr) or err or "unknown error"
+ osd("Cut failed (check console log)")
+ msg.error("ffmpeg failed: " .. tostring(detail))
+ end
+ end)
+end
+
+mp.add_key_binding(nil, "set-start", set_start)
+mp.add_key_binding(nil, "set-end", set_end)