better structure
This commit is contained in:
191
config/mpv/scripts/mpv-gif.lua
Normal file
191
config/mpv/scripts/mpv-gif.lua
Normal file
@@ -0,0 +1,191 @@
|
||||
-- Original by Ruin0x11
|
||||
-- Ported to Windows by Scheliux, Dragoner7
|
||||
|
||||
-- Create animated GIFs with mpv
|
||||
-- Requires ffmpeg.
|
||||
-- Adapted from http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
|
||||
-- Usage: "b" to set start frame, "B" to set end frame, "Ctrl+b" to create.
|
||||
|
||||
require 'mp.options'
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
local options = {
|
||||
dir = "C:/Program Files/mpv/gifs",
|
||||
rez = 600,
|
||||
fps = 15,
|
||||
}
|
||||
|
||||
read_options(options, "gif")
|
||||
|
||||
|
||||
local fps
|
||||
|
||||
-- Check for invalid fps values
|
||||
-- Can you believe Lua doesn't have a proper ternary operator in the year of our lord 2020?
|
||||
if options.fps ~= nil and options.fps >= 1 and options.fps < 30 then
|
||||
fps = options.fps
|
||||
else
|
||||
fps = 15
|
||||
end
|
||||
|
||||
-- Set this to the filters to pass into ffmpeg's -vf option.
|
||||
-- filters="fps=24,scale=320:-1:flags=spline"
|
||||
filters=string.format("fps=%s,scale='trunc(ih*dar/2)*2:trunc(ih/2)*2',setsar=1/1,scale=%s:-1:flags=spline", fps, options.rez) --change spline to lanczos depending on preference
|
||||
|
||||
-- Setup output directory
|
||||
output_directory=string.gsub(options.dir, '\"', '')
|
||||
|
||||
start_time = -1
|
||||
end_time = -1
|
||||
palette="%TEMP%palette.png"
|
||||
|
||||
-- The roundabout way has to be used due to a some weird
|
||||
-- behavior with %TEMP% on the subtitles= parameter in ffmpeg
|
||||
-- on Windows–it needs to be quadruple backslashed
|
||||
subs = "C:/Users/%USERNAME%/AppData/Local/Temp/subs.srt"
|
||||
|
||||
function make_gif_with_subtitles()
|
||||
make_gif_internal(true)
|
||||
end
|
||||
|
||||
function make_gif()
|
||||
make_gif_internal(false)
|
||||
end
|
||||
|
||||
function table_length(t)
|
||||
local count = 0
|
||||
for _ in pairs(t) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
|
||||
function make_gif_internal(burn_subtitles)
|
||||
local start_time_l = start_time
|
||||
local end_time_l = end_time
|
||||
if start_time_l == -1 or end_time_l == -1 or start_time_l >= end_time_l then
|
||||
mp.osd_message("Invalid start/end time.")
|
||||
return
|
||||
end
|
||||
|
||||
mp.osd_message("Creating GIF.")
|
||||
|
||||
-- shell escape
|
||||
function esc(s)
|
||||
return string.gsub(s, '"', '"\\""')
|
||||
end
|
||||
|
||||
function esc_for_sub(s)
|
||||
s = string.gsub(s, [[\]], [[/]])
|
||||
s = string.gsub(s, '"', '"\\""')
|
||||
s = string.gsub(s, ":", [[\\:]])
|
||||
s = string.gsub(s, "'", [[\\']])
|
||||
return s
|
||||
end
|
||||
|
||||
local pathname = mp.get_property("path", "")
|
||||
local trim_filters = esc(filters)
|
||||
|
||||
local position = start_time_l
|
||||
local duration = end_time_l - start_time_l
|
||||
|
||||
if burn_subtitles then
|
||||
-- Determine currently active sub track
|
||||
|
||||
local i = 0
|
||||
local tracks_count = mp.get_property_number("track-list/count")
|
||||
local subs_array = {}
|
||||
|
||||
-- check for subtitle tracks
|
||||
|
||||
while i < tracks_count do
|
||||
local type = mp.get_property(string.format("track-list/%d/type", i))
|
||||
local selected = mp.get_property(string.format("track-list/%d/selected", i))
|
||||
|
||||
-- if it's a sub track, save it
|
||||
|
||||
if type == "sub" then
|
||||
local length = table_length(subs_array)
|
||||
subs_array[length] = selected == "yes"
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if table_length(subs_array) > 0 then
|
||||
|
||||
local correct_track = 0
|
||||
|
||||
-- iterate through saved subtitle tracks until the correct one is found
|
||||
|
||||
for index, is_selected in pairs(subs_array) do
|
||||
if (is_selected) then
|
||||
correct_track = index
|
||||
end
|
||||
end
|
||||
|
||||
trim_filters = trim_filters .. string.format(",subtitles=%s:si=%s", esc_for_sub(pathname), correct_track)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- first, create the palette
|
||||
args = string.format('ffmpeg -v warning -ss %s -t %s -i "%s" -vf "%s,palettegen" -y "%s"', position, duration, esc(pathname), esc(trim_filters), esc(palette))
|
||||
msg.debug(args)
|
||||
os.execute(args)
|
||||
|
||||
-- then, make the gif
|
||||
local filename = mp.get_property("filename/no-ext")
|
||||
local file_path = output_directory .. "/" .. filename
|
||||
|
||||
-- increment filename
|
||||
for i=0,999 do
|
||||
local fn = string.format('%s_%03d.gif',file_path,i)
|
||||
if not file_exists(fn) then
|
||||
gifname = fn
|
||||
break
|
||||
end
|
||||
end
|
||||
if not gifname then
|
||||
mp.osd_message('No available filenames!')
|
||||
return
|
||||
end
|
||||
|
||||
local copyts = ""
|
||||
|
||||
if burn_subtitles then
|
||||
copyts = "-copyts"
|
||||
end
|
||||
|
||||
args = string.format('ffmpeg -v warning -ss %s %s -t %s -i "%s" -i "%s" -lavfi "%s [x]; [x][1:v] paletteuse" -y "%s"', position, copyts, duration, esc(pathname), esc(palette), esc(trim_filters), esc(gifname))
|
||||
os.execute(args)
|
||||
|
||||
local ok, err, code = os.rename(gifname, gifname)
|
||||
if ok then
|
||||
msg.info("GIF created: " .. gifname)
|
||||
mp.osd_message("GIF created: " .. gifname)
|
||||
else
|
||||
mp.osd_message("Error creating file, check CLI for more info.")
|
||||
end
|
||||
end
|
||||
|
||||
function set_gif_start()
|
||||
start_time = mp.get_property_number("time-pos", -1)
|
||||
mp.osd_message("GIF Start: " .. start_time)
|
||||
end
|
||||
|
||||
function set_gif_end()
|
||||
end_time = mp.get_property_number("time-pos", -1)
|
||||
mp.osd_message("GIF End: " .. end_time)
|
||||
end
|
||||
|
||||
function file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
|
||||
-- all keybindings here are set to nil on purpose 'cause I modified the keybindings (in input.conf)
|
||||
mp.add_key_binding(nil, "set_gif_start", set_gif_start)
|
||||
mp.add_key_binding(nil, "set_gif_end", set_gif_end)
|
||||
mp.add_key_binding(nil, "make_gif", make_gif)
|
||||
mp.add_key_binding(nil, "make_gif_with_subtitles", make_gif_with_subtitles) -- making GIFs with subtitles doesn't seem to work
|
||||
Reference in New Issue
Block a user