Skip to content

Instantly share code, notes, and snippets.

Created June 22, 2017 01:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/715b352069d08efb57402cc6f6cf72c3 to your computer and use it in GitHub Desktop.
Save anonymous/715b352069d08efb57402cc6f6cf72c3 to your computer and use it in GitHub Desktop.
local msg = require "mp.msg"
local utils = require "mp.utils"
local options = require "mp.options"
local cut_pos = nil
local copy_audio = true
local o = {
target_dir = utils.getcwd(),
vcodec = "libx264",
acodec = "libfdk_aac -async 1",
prevf = "",
postvf = "",
opts = "",
ext = ".mp4",
command_template = [[
ffmpeg -loglevel warning
-ss $shift -i '$in' -t $duration
-c:v $vcodec -c:a $acodec $audio
$opts '$out$ext'
]],
}
options.read_options(o)
function timestamp(duration)
local hours = duration / 3600
local minutes = duration % 3600 / 60
local seconds = duration % 60
return string.format("%02d:%02d:%02.03f", hours, minutes, seconds)
end
function osd(str)
return mp.osd_message(str, 3)
end
function log(str)
local logpath = string.format("%s/%s",
o.target_dir:gsub("~", os.getenv("HOME")),
"mpv_slicing.log")
f = io.open(logpath, "a")
f:write(string.format("# %s\n%s\n",
os.date("%Y-%m-%d %H:%M:%S"),
str))
f:close()
end
function escape(str)
return str:gsub("'", "'\\''")
end
function trim(str)
return str:gsub("^%s+", ""):gsub("%s+$", "")
end
function get_csp()
local csp = mp.get_property("colormatrix")
if csp == "bt.601" then return "bt601"
elseif csp == "bt.709" then return "bt709"
elseif csp == "smpte-240m" then return "smpte240m"
else
local err = "Unknown colorspace: " .. csp
osd(err)
error(err)
end
end
function get_outname(shift, endpos)
local name = mp.get_property("filename")
local dotidx = name:reverse():find(".", 1, true)
if dotidx then name = name:sub(1, -dotidx-1) end
-- name = name:gsub(" ", "_")
name = name .. string.format(".%s-%s", timestamp(shift), timestamp(endpos))
return name .. "_OUT"
end
function GetFileExtension(filen)
return filen:match("^.+(%..+)$")
end
function cut(shift, endpos)
local cmd = trim(o.command_template:gsub("%s+", " "))
local inpath = escape(utils.join_path(
utils.getcwd(),
mp.get_property("stream-path")))
-- TODO: Windows?
local outpath = escape(string.format("%s/%s",
o.target_dir:gsub("~", os.getenv("HOME")),
get_outname(shift, endpos)))
cmd = cmd:gsub("$shift", shift)
cmd = cmd:gsub("$duration", endpos - shift)
cmd = cmd:gsub("$vcodec", o.vcodec)
cmd = cmd:gsub("$acodec", o.acodec)
cmd = cmd:gsub("$audio", copy_audio and "" or "-an")
cmd = cmd:gsub("$matrix", get_csp())
cmd = cmd:gsub("$opts", o.opts)
-- Beware that input/out filename may contain replacing patterns.
-- cmd = cmd:gsub("$ext", GetFileExtension(mp.get_property("filename")))
cmd = cmd:gsub("$ext", o.ext)
cmd = cmd:gsub("$out", outpath)
cmd = cmd:gsub("$in", inpath, 1)
msg.info(cmd)
log(cmd)
os.execute(cmd)
end
function toggle_mark()
local pos = mp.get_property_number("time-pos")
if cut_pos then
local shift, endpos = cut_pos, pos
if shift > endpos then
shift, endpos = endpos, shift
end
if shift == endpos then
osd("Cut fragment is empty")
else
cut_pos = nil
osd(string.format("Cut fragment: %s - %s",
timestamp(shift),
timestamp(endpos)))
cut(shift, endpos)
end
else
cut_pos = pos
osd(string.format("Marked %s as start position", timestamp(pos)))
end
end
function toggle_audio()
copy_audio = not copy_audio
osd("Audio capturing is " .. (copy_audio and "enabled" or "disabled"))
end
mp.add_key_binding("c", "slicing_mark", toggle_mark)
mp.add_key_binding("a", "slicing_audio", toggle_audio)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment