Created
April 5, 2020 18:42
-
-
Save SpaghettiBorgar/06fe8afd6e0a5fe3a3015780929ea828 to your computer and use it in GitHub Desktop.
mpv script to quickly create gifs, video clips, and sound clips
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Create animated GIFs with mpv | |
-- Requires ffmpeg, gifski, exiftool, and vorbis-tools. | |
-- Based on github.com/Scheliux/mpv-gif-generator | |
-- Usage: "g" to set start frame, "G" to set end frame, | |
-- "Ctrl+g" to create gif | |
-- "Ctrl+v" to create video clip | |
-- "Ctrl+a" to create audio clip | |
-- Metadata about the filename and timestamps will be written in the comment tag | |
local msg = require 'mp.msg' | |
home = os.getenv("HOME") | |
-- Quality Settings | |
gif_fps = 12 | |
gif_width = 540 | |
gif_quality = 90 | |
gif_folder = home.."/mpv/gifs/" | |
vid_crf = 20 | |
vid_width = -1 | |
vid_folder = home.."/mpv/vid/" | |
snd_bitrate = 128 | |
snd_folder = home.."/mpv/snd/" | |
gif_filters=string.format("fps=%s,scale=%s:-1:flags=lanczos", gif_fps, gif_width) | |
vid_filters=string.format("scale=%s:-1:flags=lanczos", vid_width) | |
start_time = -1 | |
end_time = -1 | |
mode = "gif" | |
function make() | |
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 | |
local type = "" | |
if mode=="gif" then | |
type = "GIF" | |
elseif mode=="vid" then | |
type = "Video Clip" | |
elseif mode=="snd" then | |
type = "Sound Clip" | |
end | |
mp.osd_message("Creating "..type) | |
function esc(s) | |
return s:gsub("'", "'\\''") | |
end | |
local position = start_time_l | |
local duration = end_time_l - start_time_l | |
local path = mp.get_property("path") | |
local directory = get_containing_path(path) | |
local filename = mp.get_property("filename/no-ext") | |
local extension = "" | |
local directory = "" | |
if mode=="gif" then | |
extension = "gif" | |
directory = gif_folder | |
elseif mode=="vid" then | |
extension = "mp4" | |
directory = vid_folder | |
elseif mode=="snd" then | |
extension = "ogg" | |
directory = snd_folder | |
end | |
os.execute("mkdir -p "..directory) | |
for i=0,999 do | |
local fn = string.format('%s_%03d.%s', directory..filename, i, extension) | |
if not file_exists(fn) then | |
outfile = fn | |
break | |
end | |
end | |
if not outfile then | |
mp.osd_message('No available filenames!') | |
return | |
end | |
if mode == "gif" then | |
framenames = "/tmp/mpv/%04d.png" | |
os.execute("mkdir -p /tmp/mpv && rm /tmp/mpv/*") | |
os.execute(string.format("ffmpeg -ss %s -t %s -i '%s' -lavfi '%s' -y '%s'", position, duration, esc(path), gif_filters, framenames)) | |
os.execute(string.format("gifski --fps %s --quality %s /tmp/mpv/* -o '%s'", gif_fps, gif_quality, esc(outfile))) | |
elseif mode == "vid" then | |
os.execute(string.format("ffmpeg -ss %s -i '%s' -t %s -lavfi '%s' -async 1 -crf %s -y '%s'", position, esc(path), duration, vid_filters, vid_crf, esc(outfile))) | |
elseif mode == "snd" then | |
os.execute(string.format("ffmpeg -ss %s -t %s -i '%s' -vn -c:a libvorbis -ab %sk -y '%s'", position, duration, esc(path), snd_bitrate, esc(outfile))) | |
end | |
if file_exists(outfile) then | |
if mode == "snd" then | |
os.execute(string.format("vorbiscomment -wRt comment='%s %s %s' '%s'", esc(filename), position, duration, esc(outfile))) | |
else | |
os.execute(string.format("exiftool -overwrite_original_in_place -comment='%s %s %s' '%s'", esc(filename), position, duration, esc(outfile))) | |
end | |
msg.info(type.." created.") | |
mp.osd_message(type.." created.") | |
else | |
msg.info("Failed to create "..type) | |
mp.osd_message("Failed to create "..type) | |
end | |
end | |
function make_gif() | |
mode = "gif" | |
make() | |
end | |
function make_vid() | |
mode = "vid" | |
make() | |
end | |
function make_snd() | |
mode = "snd" | |
make() | |
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 | |
function get_containing_path(str,sep) | |
sep=sep or package.config:sub(1,1) | |
return str:match("(.*"..sep..")") | |
end | |
mp.add_key_binding("g", "set_gif_start", set_gif_start) | |
mp.add_key_binding("G", "set_gif_end", set_gif_end) | |
mp.add_key_binding("Ctrl+g", "make_gif", make_gif) | |
mp.add_key_binding("Ctrl+v", "make_vid", make_vid) | |
mp.add_key_binding("Ctrl+a", "make_snd", make_snd) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment