From 583d6a1d20f213b84589e4ce6198ca1109dfe2af Mon Sep 17 00:00:00 2001 From: Raymaekers Luca Date: Sun, 16 Apr 2023 20:48:40 +0200 Subject: moved mpv and alacritty to common --- config/X/mpv/scripts/webm.lua | 2914 ----------------------------------------- 1 file changed, 2914 deletions(-) delete mode 100644 config/X/mpv/scripts/webm.lua (limited to 'config/X/mpv/scripts/webm.lua') diff --git a/config/X/mpv/scripts/webm.lua b/config/X/mpv/scripts/webm.lua deleted file mode 100644 index 4397b9b..0000000 --- a/config/X/mpv/scripts/webm.lua +++ /dev/null @@ -1,2914 +0,0 @@ -local mp = require("mp") -local assdraw = require("mp.assdraw") -local msg = require("mp.msg") -local utils = require("mp.utils") -local mpopts = require("mp.options") -local options = { - -- Defaults to shift+w - keybind = "W", - -- If empty, saves on the same directory of the playing video. - -- A starting "~" will be replaced by the home dir. - -- This field is delimited by double-square-brackets - [[ and ]] - instead of - -- quotes, because Windows users might run into a issue when using - -- backslashes as a path separator. Examples of valid inputs for this field - -- would be: [[]] (the default, empty value), [[C:\Users\John]] (on Windows), - -- and [[/home/john]] (on Unix-like systems eg. Linux). - -- The [[]] delimiter is not needed when using from a configuration file - -- in the script-opts folder. - output_directory = [[]], - run_detached = false, - -- Template string for the output file - -- %f - Filename, with extension - -- %F - Filename, without extension - -- %T - Media title, if it exists, or filename, with extension (useful for some streams, such as YouTube). - -- %s, %e - Start and end time, with milliseconds - -- %S, %E - Start and end time, without milliseconds - -- %M - "-audio", if audio is enabled, empty otherwise - -- %R - "-(height)p", where height is the video's height, or scale_height, if it's enabled. - -- More specifiers are supported, see https://mpv.io/manual/master/#options-screenshot-template - -- Property expansion is supported (with %{} at top level, ${} when nested), see https://mpv.io/manual/master/#property-expansion - output_template = "%F-[%s-%e]%M", - -- Scale video to a certain height, keeping the aspect ratio. -1 disables it. - scale_height = -1, - -- Change the FPS of the output video, dropping or duplicating frames as needed. - -- -1 means the FPS will be unchanged from the source. - fps = -1, - -- Target filesize, in kB. This will be used to calculate the bitrate - -- used on the encode. If this is set to <= 0, the video bitrate will be set - -- to 0, which might enable constant quality modes, depending on the - -- video codec that's used (VP8 and VP9, for example). - target_filesize = 2500, - -- If true, will use stricter flags to ensure the resulting file doesn't - -- overshoot the target filesize. Not recommended, as constrained quality - -- mode should work well, unless you're really having trouble hitting - -- the target size. - strict_filesize_constraint = false, - strict_bitrate_multiplier = 0.95, - -- In kilobits. - strict_audio_bitrate = 64, - -- Sets the output format, from a few predefined ones. - -- Currently we have: - -- webm-vp8 (libvpx/libvorbis) - -- webm-vp9 (libvpx-vp9/libopus) - -- mp4 (h264/AAC) - -- mp4-nvenc (h264-NVENC/AAC) - -- raw (rawvideo/pcm_s16le). - -- mp3 (libmp3lame) - -- and gif - output_format = "webm-vp8", - twopass = true, - -- If set, applies the video filters currently used on the playback to the encode. - apply_current_filters = true, - -- If set, writes the video's filename to the "Title" field on the metadata. - write_filename_on_metadata = false, - -- Set the number of encoding threads, for codecs libvpx and libvpx-vp9 - libvpx_threads = 4, - additional_flags = "", - -- Constant Rate Factor (CRF). The value meaning and limits may change, - -- from codec to codec. Set to -1 to disable. - crf = 10, - -- Useful for flags that may impact output filesize, such as qmin, qmax etc - -- Won't be applied when strict_filesize_constraint is on. - non_strict_additional_flags = "", - -- Display the encode progress, in %. Requires run_detached to be disabled. - -- On Windows, it shows a cmd popup. "auto" will display progress on non-Windows platforms. - display_progress = "auto", - -- The font size used in the menu. Isn't used for the notifications (started encode, finished encode etc) - font_size = 28, - margin = 10, - message_duration = 5, - -- gif dither mode, 0-5 for bayer w/ bayer_scale 0-5, 6 for paletteuse default (sierra2_4a) - gif_dither = 2, - -- Force square pixels on output video - -- Some players like recent Firefox versions display videos with non-square pixels with wrong aspect ratio - force_square_pixels = false, -} - -mpopts.read_options(options) -local base64_chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - --- encoding -function base64_encode(data) - return ((data:gsub('.', function(x) - local r,b='',x:byte() - for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end - return r; - end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) - if (#x < 6) then return '' end - local c=0 - for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end - return base64_chars:sub(c+1,c+1) - end)..({ '', '==', '=' })[#data%3+1]) -end - --- decoding -function base64_decode(data) - data = string.gsub(data, '[^'..base64_chars..'=]', '') - return (data:gsub('.', function(x) - if (x == '=') then return '' end - local r,f='',(base64_chars:find(x)-1) - for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end - return r; - end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x) - if (#x ~= 8) then return '' end - local c=0 - for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end - return string.char(c) - end)) -end -local emit_event -emit_event = function(event_name, ...) - return mp.commandv("script-message", "webm-" .. tostring(event_name), ...) -end -local test_set_options -test_set_options = function(new_options_json) - local new_options = utils.parse_json(new_options_json) - for k, v in pairs(new_options) do - options[k] = v - end -end -mp.register_script_message("mpv-webm-set-options", test_set_options) -local bold -bold = function(text) - return "{\\b1}" .. tostring(text) .. "{\\b0}" -end -local message -message = function(text, duration) - local ass = mp.get_property_osd("osd-ass-cc/0") - ass = ass .. text - return mp.osd_message(ass, duration or options.message_duration) -end -local append -append = function(a, b) - for _, val in ipairs(b) do - a[#a + 1] = val - end - return a -end -local seconds_to_time_string -seconds_to_time_string = function(seconds, no_ms, full) - if seconds < 0 then - return "unknown" - end - local ret = "" - if not (no_ms) then - ret = string.format(".%03d", seconds * 1000 % 1000) - end - ret = string.format("%02d:%02d%s", math.floor(seconds / 60) % 60, math.floor(seconds) % 60, ret) - if full or seconds > 3600 then - ret = string.format("%d:%s", math.floor(seconds / 3600), ret) - end - return ret -end -local seconds_to_path_element -seconds_to_path_element = function(seconds, no_ms, full) - local time_string = seconds_to_time_string(seconds, no_ms, full) - local _ - time_string, _ = time_string:gsub(":", ".") - return time_string -end -local file_exists -file_exists = function(name) - local info, err = utils.file_info(name) - if info ~= nil then - return true - end - return false -end -local expand_properties -expand_properties = function(text, magic) - if magic == nil then - magic = "$" - end - for prefix, raw, prop, colon, fallback, closing in text:gmatch("%" .. magic .. "{([?!]?)(=?)([^}:]*)(:?)([^}]*)(}*)}") do - local err - local prop_value - local compare_value - local original_prop = prop - local get_property = mp.get_property_osd - if raw == "=" then - get_property = mp.get_property - end - if prefix ~= "" then - for actual_prop, compare in prop:gmatch("(.-)==(.*)") do - prop = actual_prop - compare_value = compare - end - end - if colon == ":" then - prop_value, err = get_property(prop, fallback) - else - prop_value, err = get_property(prop, "(error)") - end - prop_value = tostring(prop_value) - if prefix == "?" then - if compare_value == nil then - prop_value = err == nil and fallback .. closing or "" - else - prop_value = prop_value == compare_value and fallback .. closing or "" - end - prefix = "%" .. prefix - elseif prefix == "!" then - if compare_value == nil then - prop_value = err ~= nil and fallback .. closing or "" - else - prop_value = prop_value ~= compare_value and fallback .. closing or "" - end - else - prop_value = prop_value .. closing - end - if colon == ":" then - local _ - text, _ = text:gsub("%" .. magic .. "{" .. prefix .. raw .. original_prop:gsub("%W", "%%%1") .. ":" .. fallback:gsub("%W", "%%%1") .. closing .. "}", expand_properties(prop_value)) - else - local _ - text, _ = text:gsub("%" .. magic .. "{" .. prefix .. raw .. original_prop:gsub("%W", "%%%1") .. closing .. "}", prop_value) - end - end - return text -end -local format_filename -format_filename = function(startTime, endTime, videoFormat) - local hasAudioCodec = videoFormat.audioCodec ~= "" - local replaceFirst = { - ["%%mp"] = "%%mH.%%mM.%%mS", - ["%%mP"] = "%%mH.%%mM.%%mS.%%mT", - ["%%p"] = "%%wH.%%wM.%%wS", - ["%%P"] = "%%wH.%%wM.%%wS.%%wT" - } - local replaceTable = { - ["%%wH"] = string.format("%02d", math.floor(startTime / (60 * 60))), - ["%%wh"] = string.format("%d", math.floor(startTime / (60 * 60))), - ["%%wM"] = string.format("%02d", math.floor(startTime / 60 % 60)), - ["%%wm"] = string.format("%d", math.floor(startTime / 60)), - ["%%wS"] = string.format("%02d", math.floor(startTime % 60)), - ["%%ws"] = string.format("%d", math.floor(startTime)), - ["%%wf"] = string.format("%s", startTime), - ["%%wT"] = string.sub(string.format("%.3f", startTime % 1), 3), - ["%%mH"] = string.format("%02d", math.floor(endTime / (60 * 60))), - ["%%mh"] = string.format("%d", math.floor(endTime / (60 * 60))), - ["%%mM"] = string.format("%02d", math.floor(endTime / 60 % 60)), - ["%%mm"] = string.format("%d", math.floor(endTime / 60)), - ["%%mS"] = string.format("%02d", math.floor(endTime % 60)), - ["%%ms"] = string.format("%d", math.floor(endTime)), - ["%%mf"] = string.format("%s", endTime), - ["%%mT"] = string.sub(string.format("%.3f", endTime % 1), 3), - ["%%f"] = mp.get_property("filename"), - ["%%F"] = mp.get_property("filename/no-ext"), - ["%%s"] = seconds_to_path_element(startTime), - ["%%S"] = seconds_to_path_element(startTime, true), - ["%%e"] = seconds_to_path_element(endTime), - ["%%E"] = seconds_to_path_element(endTime, true), - ["%%T"] = mp.get_property("media-title"), - ["%%M"] = (mp.get_property_native('aid') and not mp.get_property_native('mute') and hasAudioCodec) and '-audio' or '', - ["%%R"] = (options.scale_height ~= -1) and "-" .. tostring(options.scale_height) .. "p" or "-" .. tostring(mp.get_property_native('height')) .. "p", - ["%%t%%"] = "%%" - } - local filename = options.output_template - for format, value in pairs(replaceFirst) do - local _ - filename, _ = filename:gsub(format, value) - end - for format, value in pairs(replaceTable) do - local _ - filename, _ = filename:gsub(format, value) - end - if mp.get_property_bool("demuxer-via-network", false) then - local _ - filename, _ = filename:gsub("%%X{([^}]*)}", "%1") - filename, _ = filename:gsub("%%x", "") - else - local x = string.gsub(mp.get_property("stream-open-filename", ""), string.gsub(mp.get_property("filename", ""), "%W", "%%%1") .. "$", "") - local _ - filename, _ = filename:gsub("%%X{[^}]*}", x) - filename, _ = filename:gsub("%%x", x) - end - filename = expand_properties(filename, "%") - for format in filename:gmatch("%%t([aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ])") do - local _ - filename, _ = filename:gsub("%%t" .. format, os.date("%" .. format)) - end - local _ - filename, _ = filename:gsub("[<>:\"/\\|?*]", "") - return tostring(filename) .. "." .. tostring(videoFormat.outputExtension) -end -local parse_directory -parse_directory = function(dir) - local home_dir = os.getenv("HOME") - if not home_dir then - home_dir = os.getenv("USERPROFILE") - end - if not home_dir then - local drive = os.getenv("HOMEDRIVE") - local path = os.getenv("HOMEPATH") - if drive and path then - home_dir = utils.join_path(drive, path) - else - msg.warn("Couldn't find home dir.") - home_dir = "" - end - end - local _ - dir, _ = dir:gsub("^~", home_dir) - return dir -end -local is_windows = type(package) == "table" and type(package.config) == "string" and package.config:sub(1, 1) == "\\" -local trim -trim = function(s) - return s:match("^%s*(.-)%s*$") -end -local get_null_path -get_null_path = function() - if file_exists("/dev/null") then - return "/dev/null" - end - return "NUL" -end -local run_subprocess -run_subprocess = function(params) - local res = utils.subprocess(params) - msg.verbose("Command stdout: ") - msg.verbose(res.stdout) - if res.status ~= 0 then - msg.verbose("Command failed! Reason: ", res.error, " Killed by us? ", res.killed_by_us and "yes" or "no") - return false - end - return true -end -local shell_escape -shell_escape = function(args) - local ret = { } - for i, a in ipairs(args) do - local s = tostring(a) - if string.match(s, "[^A-Za-z0-9_/:=-]") then - if is_windows then - s = '"' .. string.gsub(s, '"', '"\\""') .. '"' - else - s = "'" .. string.gsub(s, "'", "'\\''") .. "'" - end - end - table.insert(ret, s) - end - local concat = table.concat(ret, " ") - if is_windows then - concat = '"' .. concat .. '"' - end - return concat -end -local run_subprocess_popen -run_subprocess_popen = function(command_line) - local command_line_string = shell_escape(command_line) - command_line_string = command_line_string .. " 2>&1" - msg.verbose("run_subprocess_popen: running " .. tostring(command_line_string)) - return io.popen(command_line_string) -end -local calculate_scale_factor -calculate_scale_factor = function() - local baseResY = 720 - local osd_w, osd_h = mp.get_osd_size() - return osd_h / baseResY -end -local should_display_progress -should_display_progress = function() - if options.display_progress == "auto" then - return not is_windows - end - return options.display_progress -end -local reverse -reverse = function(list) - local _accum_0 = { } - local _len_0 = 1 - local _max_0 = 1 - for _index_0 = #list, _max_0 < 0 and #list + _max_0 or _max_0, -1 do - local element = list[_index_0] - _accum_0[_len_0] = element - _len_0 = _len_0 + 1 - end - return _accum_0 -end -local get_pass_logfile_path -get_pass_logfile_path = function(encode_out_path) - return tostring(encode_out_path) .. "-video-pass1.log" -end -local dimensions_changed = true -local _video_dimensions = { } -local get_video_dimensions -get_video_dimensions = function() - if not (dimensions_changed) then - return _video_dimensions - end - local video_params = mp.get_property_native("video-out-params") - if not video_params then - return nil - end - dimensions_changed = false - local keep_aspect = mp.get_property_bool("keepaspect") - local w = video_params["w"] - local h = video_params["h"] - local dw = video_params["dw"] - local dh = video_params["dh"] - if mp.get_property_number("video-rotate") % 180 == 90 then - w, h = h, w - dw, dh = dh, dw - end - _video_dimensions = { - top_left = { }, - bottom_right = { }, - ratios = { } - } - local window_w, window_h = mp.get_osd_size() - if keep_aspect then - local unscaled = mp.get_property_native("video-unscaled") - local panscan = mp.get_property_number("panscan") - local fwidth = window_w - local fheight = math.floor(window_w / dw * dh) - if fheight > window_h or fheight < h then - local tmpw = math.floor(window_h / dh * dw) - if tmpw <= window_w then - fheight = window_h - fwidth = tmpw - end - end - local vo_panscan_area = window_h - fheight - local f_w = fwidth / fheight - local f_h = 1 - if vo_panscan_area == 0 then - vo_panscan_area = window_h - fwidth - f_w = 1 - f_h = fheight / fwidth - end - if unscaled or unscaled == "downscale-big" then - vo_panscan_area = 0 - if unscaled or (dw <= window_w and dh <= window_h) then - fwidth = dw - fheight = dh - end - end - local scaled_width = fwidth + math.floor(vo_panscan_area * panscan * f_w) - local scaled_height = fheight + math.floor(vo_panscan_area * panscan * f_h) - local split_scaling - split_scaling = function(dst_size, scaled_src_size, zoom, align, pan) - scaled_src_size = math.floor(scaled_src_size * 2 ^ zoom) - align = (align + 1) / 2 - local dst_start = math.floor((dst_size - scaled_src_size) * align + pan * scaled_src_size) - if dst_start < 0 then - dst_start = dst_start + 1 - end - local dst_end = dst_start + scaled_src_size - if dst_start >= dst_end then - dst_start = 0 - dst_end = 1 - end - return dst_start, dst_end - end - local zoom = mp.get_property_number("video-zoom") - local align_x = mp.get_property_number("video-align-x") - local pan_x = mp.get_property_number("video-pan-x") - _video_dimensions.top_left.x, _video_dimensions.bottom_right.x = split_scaling(window_w, scaled_width, zoom, align_x, pan_x) - local align_y = mp.get_property_number("video-align-y") - local pan_y = mp.get_property_number("video-pan-y") - _video_dimensions.top_left.y, _video_dimensions.bottom_right.y = split_scaling(window_h, scaled_height, zoom, align_y, pan_y) - else - _video_dimensions.top_left.x = 0 - _video_dimensions.bottom_right.x = window_w - _video_dimensions.top_left.y = 0 - _video_dimensions.bottom_right.y = window_h - end - _video_dimensions.ratios.w = w / (_video_dimensions.bottom_right.x - _video_dimensions.top_left.x) - _video_dimensions.ratios.h = h / (_video_dimensions.bottom_right.y - _video_dimensions.top_left.y) - return _video_dimensions -end -local set_dimensions_changed -set_dimensions_changed = function() - dimensions_changed = true -end -local monitor_dimensions -monitor_dimensions = function() - local properties = { - "keepaspect", - "video-out-params", - "video-unscaled", - "panscan", - "video-zoom", - "video-align-x", - "video-pan-x", - "video-align-y", - "video-pan-y", - "osd-width", - "osd-height" - } - for _, p in ipairs(properties) do - mp.observe_property(p, "native", set_dimensions_changed) - end -end -local clamp -clamp = function(min, val, max) - if val <= min then - return min - end - if val >= max then - return max - end - return val -end -local clamp_point -clamp_point = function(top_left, point, bottom_right) - return { - x = clamp(top_left.x, point.x, bottom_right.x), - y = clamp(top_left.y, point.y, bottom_right.y) - } -end -local VideoPoint -do - local _class_0 - local _base_0 = { - set_from_screen = function(self, sx, sy) - local d = get_video_dimensions() - local point = clamp_point(d.top_left, { - x = sx, - y = sy - }, d.bottom_right) - self.x = math.floor(d.ratios.w * (point.x - d.top_left.x) + 0.5) - self.y = math.floor(d.ratios.h * (point.y - d.top_left.y) + 0.5) - end, - to_screen = function(self) - local d = get_video_dimensions() - return { - x = math.floor(self.x / d.ratios.w + d.top_left.x + 0.5), - y = math.floor(self.y / d.ratios.h + d.top_left.y + 0.5) - } - end - } - _base_0.__index = _base_0 - _class_0 = setmetatable({ - __init = function(self) - self.x = -1 - self.y = -1 - end, - __base = _base_0, - __name = "VideoPoint" - }, { - __index = _base_0, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - VideoPoint = _class_0 -end -local Region -do - local _class_0 - local _base_0 = { - is_valid = function(self) - return self.x > -1 and self.y > -1 and self.w > -1 and self.h > -1 - end, - set_from_points = function(self, p1, p2) - self.x = math.min(p1.x, p2.x) - self.y = math.min(p1.y, p2.y) - self.w = math.abs(p1.x - p2.x) - self.h = math.abs(p1.y - p2.y) - end - } - _base_0.__index = _base_0 - _class_0 = setmetatable({ - __init = function(self) - self.x = -1 - self.y = -1 - self.w = -1 - self.h = -1 - end, - __base = _base_0, - __name = "Region" - }, { - __index = _base_0, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - Region = _class_0 -end -local make_fullscreen_region -make_fullscreen_region = function() - local r = Region() - local d = get_video_dimensions() - local a = VideoPoint() - local b = VideoPoint() - local xa, ya - do - local _obj_0 = d.top_left - xa, ya = _obj_0.x, _obj_0.y - end - a:set_from_screen(xa, ya) - local xb, yb - do - local _obj_0 = d.bottom_right - xb, yb = _obj_0.x, _obj_0.y - end - b:set_from_screen(xb, yb) - r:set_from_points(a, b) - return r -end -local read_double -read_double = function(bytes) - local sign = 1 - local mantissa = bytes[2] % 2 ^ 4 - for i = 3, 8 do - mantissa = mantissa * 256 + bytes[i] - end - if bytes[1] > 127 then - sign = -1 - end - local exponent = (bytes[1] % 128) * 2 ^ 4 + math.floor(bytes[2] / 2 ^ 4) - if exponent == 0 then - return 0 - end - mantissa = (math.ldexp(mantissa, -52) + 1) * sign - return math.ldexp(mantissa, exponent - 1023) -end -local write_double -write_double = function(num) - local bytes = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - } - if num == 0 then - return bytes - end - local anum = math.abs(num) - local mantissa, exponent = math.frexp(anum) - exponent = exponent - 1 - mantissa = mantissa * 2 - 1 - local sign = num ~= anum and 128 or 0 - exponent = exponent + 1023 - bytes[1] = sign + math.floor(exponent / 2 ^ 4) - mantissa = mantissa * 2 ^ 4 - local currentmantissa = math.floor(mantissa) - mantissa = mantissa - currentmantissa - bytes[2] = (exponent % 2 ^ 4) * 2 ^ 4 + currentmantissa - for i = 3, 8 do - mantissa = mantissa * 2 ^ 8 - currentmantissa = math.floor(mantissa) - mantissa = mantissa - currentmantissa - bytes[i] = currentmantissa - end - return bytes -end -local FirstpassStats -do - local _class_0 - local duration_multiplier, fields_before_duration, fields_after_duration - local _base_0 = { - get_duration = function(self) - local big_endian_binary_duration = reverse(self.binary_duration) - return read_double(reversed_binary_duration) / duration_multiplier - end, - set_duration = function(self, duration) - local big_endian_binary_duration = write_double(duration * duration_multiplier) - self.binary_duration = reverse(big_endian_binary_duration) - end, - _bytes_to_string = function(self, bytes) - return string.char(unpack(bytes)) - end, - as_binary_string = function(self) - local before_duration_string = self:_bytes_to_string(self.binary_data_before_duration) - local duration_string = self:_bytes_to_string(self.binary_duration) - local after_duration_string = self:_bytes_to_string(self.binary_data_after_duration) - return before_duration_string .. duration_string .. after_duration_string - end - } - _base_0.__index = _base_0 - _class_0 = setmetatable({ - __init = function(self, before_duration, duration, after_duration) - self.binary_data_before_duration = before_duration - self.binary_duration = duration - self.binary_data_after_duration = after_duration - end, - __base = _base_0, - __name = "FirstpassStats" - }, { - __index = _base_0, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - local self = _class_0 - duration_multiplier = 10000000.0 - fields_before_duration = 16 - fields_after_duration = 1 - self.data_before_duration_size = function(self) - return fields_before_duration * 8 - end - self.data_after_duration_size = function(self) - return fields_after_duration * 8 - end - self.size = function(self) - return (fields_before_duration + 1 + fields_after_duration) * 8 - end - self.from_bytes = function(self, bytes) - local before_duration - do - local _accum_0 = { } - local _len_0 = 1 - local _max_0 = self:data_before_duration_size() - for _index_0 = 1, _max_0 < 0 and #bytes + _max_0 or _max_0 do - local b = bytes[_index_0] - _accum_0[_len_0] = b - _len_0 = _len_0 + 1 - end - before_duration = _accum_0 - end - local duration - do - local _accum_0 = { } - local _len_0 = 1 - local _max_0 = self:data_before_duration_size() + 8 - for _index_0 = self:data_before_duration_size() + 1, _max_0 < 0 and #bytes + _max_0 or _max_0 do - local b = bytes[_index_0] - _accum_0[_len_0] = b - _len_0 = _len_0 + 1 - end - duration = _accum_0 - end - local after_duration - do - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = self:data_before_duration_size() + 8 + 1, #bytes do - local b = bytes[_index_0] - _accum_0[_len_0] = b - _len_0 = _len_0 + 1 - end - after_duration = _accum_0 - end - return self(before_duration, duration, after_duration) - end - FirstpassStats = _class_0 -end -local read_logfile_into_stats_array -read_logfile_into_stats_array = function(logfile_path) - local file = assert(io.open(logfile_path, "rb")) - local logfile_string = base64_decode(file:read()) - file:close() - local stats_size = FirstpassStats:size() - assert(logfile_string:len() % stats_size == 0) - local stats = { } - for offset = 1, #logfile_string, stats_size do - local bytes = { - logfile_string:byte(offset, offset + stats_size - 1) - } - assert(#bytes == stats_size) - stats[#stats + 1] = FirstpassStats:from_bytes(bytes) - end - return stats -end -local write_stats_array_to_logfile -write_stats_array_to_logfile = function(stats_array, logfile_path) - local file = assert(io.open(logfile_path, "wb")) - local logfile_string = "" - for _index_0 = 1, #stats_array do - local stat = stats_array[_index_0] - logfile_string = logfile_string .. stat:as_binary_string() - end - file:write(base64_encode(logfile_string)) - return file:close() -end -local vp8_patch_logfile -vp8_patch_logfile = function(logfile_path, encode_total_duration) - local stats_array = read_logfile_into_stats_array(logfile_path) - local average_duration = encode_total_duration / (#stats_array - 1) - for i = 1, #stats_array - 1 do - stats_array[i]:set_duration(average_duration) - end - stats_array[#stats_array]:set_duration(encode_total_duration) - return write_stats_array_to_logfile(stats_array, logfile_path) -end -local formats = { } -local Format -do - local _class_0 - local _base_0 = { - getPreFilters = function(self) - return { } - end, - getPostFilters = function(self) - return { } - end, - getFlags = function(self) - return { } - end, - getCodecFlags = function(self) - local codecs = { } - if self.videoCodec ~= "" then - codecs[#codecs + 1] = "--ovc=" .. tostring(self.videoCodec) - end - if self.audioCodec ~= "" then - codecs[#codecs + 1] = "--oac=" .. tostring(self.audioCodec) - end - return codecs - end, - postCommandModifier = function(self, command, region, startTime, endTime) - return command - end - } - _base_0.__index = _base_0 - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "Basic" - self.supportsTwopass = true - self.videoCodec = "" - self.audioCodec = "" - self.outputExtension = "" - self.acceptsBitrate = true - end, - __base = _base_0, - __name = "Format" - }, { - __index = _base_0, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - Format = _class_0 -end -local RawVideo -do - local _class_0 - local _parent_0 = Format - local _base_0 = { - getColorspace = function(self) - local csp = mp.get_property("colormatrix") - local _exp_0 = csp - if "bt.601" == _exp_0 then - return "bt601" - elseif "bt.709" == _exp_0 then - return "bt709" - elseif "bt.2020" == _exp_0 then - return "bt2020" - elseif "smpte-240m" == _exp_0 then - return "smpte240m" - else - msg.info("Warning, unknown colorspace " .. tostring(csp) .. " detected, using bt.601.") - return "bt601" - end - end, - getPostFilters = function(self) - return { - "format=yuv444p16", - "lavfi-scale=in_color_matrix=" .. self:getColorspace(), - "format=bgr24" - } - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "Raw" - self.supportsTwopass = false - self.videoCodec = "rawvideo" - self.audioCodec = "pcm_s16le" - self.outputExtension = "avi" - self.acceptsBitrate = false - end, - __base = _base_0, - __name = "RawVideo", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - RawVideo = _class_0 -end -formats["raw"] = RawVideo() -local WebmVP8 -do - local _class_0 - local _parent_0 = Format - local _base_0 = { - getPreFilters = function(self) - local colormatrixFilter = { - ["bt.709"] = "bt709", - ["bt.2020"] = "bt2020", - ["smpte-240m"] = "smpte240m" - } - local ret = { } - local colormatrix = mp.get_property_native("video-params/colormatrix") - if colormatrixFilter[colormatrix] then - append(ret, { - "lavfi-colormatrix=" .. tostring(colormatrixFilter[colormatrix]) .. ":bt601" - }) - end - return ret - end, - getFlags = function(self) - return { - "--ovcopts-add=threads=" .. tostring(options.libvpx_threads), - "--ovcopts-add=auto-alt-ref=1", - "--ovcopts-add=lag-in-frames=25", - "--ovcopts-add=quality=good", - "--ovcopts-add=cpu-used=0" - } - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "WebM" - self.supportsTwopass = true - self.videoCodec = "libvpx" - self.audioCodec = "libvorbis" - self.outputExtension = "webm" - self.acceptsBitrate = true - end, - __base = _base_0, - __name = "WebmVP8", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - WebmVP8 = _class_0 -end -formats["webm-vp8"] = WebmVP8() -local WebmVP9 -do - local _class_0 - local _parent_0 = Format - local _base_0 = { - getFlags = function(self) - return { - "--ovcopts-add=threads=" .. tostring(options.libvpx_threads) - } - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "WebM (VP9)" - self.supportsTwopass = false - self.videoCodec = "libvpx-vp9" - self.audioCodec = "libopus" - self.outputExtension = "webm" - self.acceptsBitrate = true - end, - __base = _base_0, - __name = "WebmVP9", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - WebmVP9 = _class_0 -end -formats["webm-vp9"] = WebmVP9() -local MP4 -do - local _class_0 - local _parent_0 = Format - local _base_0 = { } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "MP4 (h264/AAC)" - self.supportsTwopass = true - self.videoCodec = "libx264" - self.audioCodec = "aac" - self.outputExtension = "mp4" - self.acceptsBitrate = true - end, - __base = _base_0, - __name = "MP4", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - MP4 = _class_0 -end -formats["mp4"] = MP4() -local MP4NVENC -do - local _class_0 - local _parent_0 = Format - local _base_0 = { } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "MP4 (h264-NVENC/AAC)" - self.supportsTwopass = true - self.videoCodec = "h264_nvenc" - self.audioCodec = "aac" - self.outputExtension = "mp4" - self.acceptsBitrate = true - end, - __base = _base_0, - __name = "MP4NVENC", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - MP4NVENC = _class_0 -end -formats["mp4-nvenc"] = MP4NVENC() -local MP3 -do - local _class_0 - local _parent_0 = Format - local _base_0 = { } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "MP3 (libmp3lame)" - self.supportsTwopass = false - self.videoCodec = "" - self.audioCodec = "libmp3lame" - self.outputExtension = "mp3" - self.acceptsBitrate = true - end, - __base = _base_0, - __name = "MP3", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - MP3 = _class_0 -end -formats["mp3"] = MP3() -local GIF -do - local _class_0 - local _parent_0 = Format - local _base_0 = { - postCommandModifier = function(self, command, region, startTime, endTime) - local new_command = { } - local start_ts = seconds_to_time_string(startTime, false, true) - local end_ts = seconds_to_time_string(endTime, false, true) - start_ts = start_ts:gsub(":", "\\\\:") - end_ts = end_ts:gsub(":", "\\\\:") - local cfilter = "[vid1]trim=start=" .. tostring(start_ts) .. ":end=" .. tostring(end_ts) .. "[vidtmp];" - if mp.get_property("deinterlace") == "yes" then - cfilter = cfilter .. "[vidtmp]yadif=mode=1[vidtmp];" - end - for _, v in ipairs(command) do - local _continue_0 = false - repeat - if v:match("^%-%-vf%-add=lavfi%-scale") or v:match("^%-%-vf%-add=lavfi%-crop") or v:match("^%-%-vf%-add=fps") or v:match("^%-%-vf%-add=lavfi%-eq") then - local n = v:gsub("^%-%-vf%-add=", ""):gsub("^lavfi%-", "") - cfilter = cfilter .. "[vidtmp]" .. tostring(n) .. "[vidtmp];" - else - if v:match("^%-%-video%-rotate=90") then - cfilter = cfilter .. "[vidtmp]transpose=1[vidtmp];" - else - if v:match("^%-%-video%-rotate=270") then - cfilter = cfilter .. "[vidtmp]transpose=2[vidtmp];" - else - if v:match("^%-%-video%-rotate=180") then - cfilter = cfilter .. "[vidtmp]transpose=1[vidtmp];[vidtmp]transpose=1[vidtmp];" - else - if v:match("^%-%-deinterlace=") then - _continue_0 = true - break - else - append(new_command, { - v - }) - _continue_0 = true - break - end - end - end - end - end - _continue_0 = true - until true - if not _continue_0 then - break - end - end - cfilter = cfilter .. "[vidtmp]split[topal][vidf];" - cfilter = cfilter .. "[topal]palettegen[pal];" - cfilter = cfilter .. "[vidf]fifo[vidf];" - if options.gif_dither == 6 then - cfilter = cfilter .. "[vidf][pal]paletteuse[vo]" - else - cfilter = cfilter .. "[vidf][pal]paletteuse=dither=bayer:bayer_scale=" .. tostring(options.gif_dither) .. ":diff_mode=rectangle[vo]" - end - append(new_command, { - "--lavfi-complex=" .. tostring(cfilter) - }) - return new_command - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.displayName = "GIF" - self.supportsTwopass = false - self.videoCodec = "gif" - self.audioCodec = "" - self.outputExtension = "gif" - self.acceptsBitrate = false - end, - __base = _base_0, - __name = "GIF", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - GIF = _class_0 -end -formats["gif"] = GIF() -local Page -do - local _class_0 - local _base_0 = { - add_keybinds = function(self) - if not self.keybinds then - return - end - for key, func in pairs(self.keybinds) do - mp.add_forced_key_binding(key, key, func, { - repeatable = true - }) - end - end, - remove_keybinds = function(self) - if not self.keybinds then - return - end - for key, _ in pairs(self.keybinds) do - mp.remove_key_binding(key) - end - end, - observe_properties = function(self) - self.sizeCallback = function() - return self:draw() - end - local properties = { - "keepaspect", - "video-out-params", - "video-unscaled", - "panscan", - "video-zoom", - "video-align-x", - "video-pan-x", - "video-align-y", - "video-pan-y", - "osd-width", - "osd-height" - } - for _index_0 = 1, #properties do - local p = properties[_index_0] - mp.observe_property(p, "native", self.sizeCallback) - end - end, - unobserve_properties = function(self) - if self.sizeCallback then - mp.unobserve_property(self.sizeCallback) - self.sizeCallback = nil - end - end, - clear = function(self) - local window_w, window_h = mp.get_osd_size() - mp.set_osd_ass(window_w, window_h, "") - return mp.osd_message("", 0) - end, - prepare = function(self) - return nil - end, - dispose = function(self) - return nil - end, - show = function(self) - if self.visible then - return - end - self.visible = true - self:observe_properties() - self:add_keybinds() - self:prepare() - self:clear() - return self:draw() - end, - hide = function(self) - if not self.visible then - return - end - self.visible = false - self:unobserve_properties() - self:remove_keybinds() - self:clear() - return self:dispose() - end, - setup_text = function(self, ass) - local scale = calculate_scale_factor() - local margin = options.margin * scale - ass:append("{\\an7}") - ass:pos(margin, margin) - return ass:append("{\\fs" .. tostring(options.font_size * scale) .. "}") - end - } - _base_0.__index = _base_0 - _class_0 = setmetatable({ - __init = function() end, - __base = _base_0, - __name = "Page" - }, { - __index = _base_0, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - Page = _class_0 -end -local EncodeWithProgress -do - local _class_0 - local _parent_0 = Page - local _base_0 = { - draw = function(self) - local progress = 100 * ((self.currentTime - self.startTime) / self.duration) - local progressText = string.format("%d%%", progress) - local window_w, window_h = mp.get_osd_size() - local ass = assdraw.ass_new() - ass:new_event() - self:setup_text(ass) - ass:append("Encoding (" .. tostring(bold(progressText)) .. ")\\N") - return mp.set_osd_ass(window_w, window_h, ass.text) - end, - parseLine = function(self, line) - local matchTime = string.match(line, "Encode time[-]pos: ([0-9.]+)") - local matchExit = string.match(line, "Exiting... [(]([%a ]+)[)]") - if matchTime == nil and matchExit == nil then - return - end - if matchTime ~= nil and tonumber(matchTime) > self.currentTime then - self.currentTime = tonumber(matchTime) - end - if matchExit ~= nil then - self.finished = true - self.finishedReason = matchExit - end - end, - startEncode = function(self, command_line) - local copy_command_line - do - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #command_line do - local arg = command_line[_index_0] - _accum_0[_len_0] = arg - _len_0 = _len_0 + 1 - end - copy_command_line = _accum_0 - end - append(copy_command_line, { - '--term-status-msg=Encode time-pos: ${=time-pos}\\n' - }) - self:show() - local processFd = run_subprocess_popen(copy_command_line) - for line in processFd:lines() do - msg.verbose(string.format('%q', line)) - self:parseLine(line) - self:draw() - end - processFd:close() - self:hide() - if self.finishedReason == "End of file" then - return true - end - return false - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self, startTime, endTime) - self.startTime = startTime - self.endTime = endTime - self.duration = endTime - startTime - self.currentTime = startTime - end, - __base = _base_0, - __name = "EncodeWithProgress", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - EncodeWithProgress = _class_0 -end -local get_active_tracks -get_active_tracks = function() - local accepted = { - video = true, - audio = not mp.get_property_bool("mute"), - sub = mp.get_property_bool("sub-visibility") - } - local active = { - video = { }, - audio = { }, - sub = { } - } - for _, track in ipairs(mp.get_property_native("track-list")) do - if track["selected"] and accepted[track["type"]] then - local count = #active[track["type"]] - active[track["type"]][count + 1] = track - end - end - return active -end -local filter_tracks_supported_by_format -filter_tracks_supported_by_format = function(active_tracks, format) - local has_video_codec = format.videoCodec ~= "" - local has_audio_codec = format.audioCodec ~= "" - local supported = { - video = has_video_codec and active_tracks["video"] or { }, - audio = has_audio_codec and active_tracks["audio"] or { }, - sub = has_video_codec and active_tracks["sub"] or { } - } - return supported -end -local append_track -append_track = function(out, track) - local external_flag = { - ["audio"] = "audio-file", - ["sub"] = "sub-file" - } - local internal_flag = { - ["video"] = "vid", - ["audio"] = "aid", - ["sub"] = "sid" - } - if track['external'] and string.len(track['external-filename']) <= 2048 then - return append(out, { - "--" .. tostring(external_flag[track['type']]) .. "=" .. tostring(track['external-filename']) - }) - else - return append(out, { - "--" .. tostring(internal_flag[track['type']]) .. "=" .. tostring(track['id']) - }) - end -end -local append_audio_tracks -append_audio_tracks = function(out, tracks) - local internal_tracks = { } - for _index_0 = 1, #tracks do - local track = tracks[_index_0] - if track['external'] then - append_track(out, track) - else - append(internal_tracks, { - track - }) - end - end - if #internal_tracks > 1 then - local filter_string = "" - for _index_0 = 1, #internal_tracks do - local track = internal_tracks[_index_0] - filter_string = filter_string .. "[aid" .. tostring(track['id']) .. "]" - end - filter_string = filter_string .. "amix[ao]" - return append(out, { - "--lavfi-complex=" .. tostring(filter_string) - }) - else - if #internal_tracks == 1 then - return append_track(out, internal_tracks[1]) - end - end -end -local get_scale_filters -get_scale_filters = function() - local filters = { } - if options.force_square_pixels then - append(filters, { - "lavfi-scale=iw*sar:ih" - }) - end - if options.scale_height > 0 then - append(filters, { - "lavfi-scale=-2:" .. tostring(options.scale_height) - }) - end - return filters -end -local get_fps_filters -get_fps_filters = function() - if options.fps > 0 then - return { - "fps=" .. tostring(options.fps) - } - end - return { } -end -local get_contrast_brightness_and_saturation_filters -get_contrast_brightness_and_saturation_filters = function() - local mpv_brightness = mp.get_property("brightness") - local mpv_contrast = mp.get_property("contrast") - local mpv_saturation = mp.get_property("saturation") - if mpv_brightness == 0 and mpv_contrast == 0 and mpv_saturation == 0 then - return { } - end - local eq_saturation = (mpv_saturation + 100) / 100.0 - local eq_contrast = (mpv_contrast + 100) / 100.0 - local eq_brightness = (mpv_brightness / 50.0 + eq_contrast - 1) / 2.0 - return { - "lavfi-eq=contrast=" .. tostring(eq_contrast) .. ":saturation=" .. tostring(eq_saturation) .. ":brightness=" .. tostring(eq_brightness) - } -end -local append_property -append_property = function(out, property_name, option_name) - option_name = option_name or property_name - local prop = mp.get_property(property_name) - if prop and prop ~= "" then - return append(out, { - "--" .. tostring(option_name) .. "=" .. tostring(prop) - }) - end -end -local append_list_options -append_list_options = function(out, property_name, option_prefix) - option_prefix = option_prefix or property_name - local prop = mp.get_property_native(property_name) - if prop then - for _index_0 = 1, #prop do - local value = prop[_index_0] - append(out, { - "--" .. tostring(option_prefix) .. "-append=" .. tostring(value) - }) - end - end -end -local get_playback_options -get_playback_options = function() - local ret = { } - append_property(ret, "sub-ass-override") - append_property(ret, "sub-ass-force-style") - append_property(ret, "sub-ass-vsfilter-aspect-compat") - append_property(ret, "sub-auto") - append_property(ret, "sub-pos") - append_property(ret, "sub-delay") - append_property(ret, "video-rotate") - append_property(ret, "ytdl-format") - append_property(ret, "deinterlace") - return ret -end -local get_speed_flags -get_speed_flags = function() - local ret = { } - local speed = mp.get_property_native("speed") - if speed ~= 1 then - append(ret, { - "--vf-add=setpts=PTS/" .. tostring(speed), - "--af-add=atempo=" .. tostring(speed), - "--sub-speed=1/" .. tostring(speed) - }) - end - return ret -end -local get_metadata_flags -get_metadata_flags = function() - local title = mp.get_property("filename/no-ext") - return { - "--oset-metadata=title=%" .. tostring(string.len(title)) .. "%" .. tostring(title) - } -end -local apply_current_filters -apply_current_filters = function(filters) - local vf = mp.get_property_native("vf") - msg.verbose("apply_current_filters: got " .. tostring(#vf) .. " currently applied.") - for _index_0 = 1, #vf do - local _continue_0 = false - repeat - local filter = vf[_index_0] - msg.verbose("apply_current_filters: filter name: " .. tostring(filter['name'])) - if filter["enabled"] == false then - _continue_0 = true - break - end - local str = filter["name"] - local params = filter["params"] or { } - for k, v in pairs(params) do - str = str .. ":" .. tostring(k) .. "=%" .. tostring(string.len(v)) .. "%" .. tostring(v) - end - append(filters, { - str - }) - _continue_0 = true - until true - if not _continue_0 then - break - end - end -end -local get_video_filters -get_video_filters = function(format, region) - local filters = { } - append(filters, format:getPreFilters()) - if options.apply_current_filters then - apply_current_filters(filters) - end - if region and region:is_valid() then - append(filters, { - "lavfi-crop=" .. tostring(region.w) .. ":" .. tostring(region.h) .. ":" .. tostring(region.x) .. ":" .. tostring(region.y) - }) - end - append(filters, get_scale_filters()) - append(filters, get_fps_filters()) - append(filters, get_contrast_brightness_and_saturation_filters()) - append(filters, format:getPostFilters()) - return filters -end -local get_video_encode_flags -get_video_encode_flags = function(format, region) - local flags = { } - append(flags, get_playback_options()) - local filters = get_video_filters(format, region) - for _index_0 = 1, #filters do - local f = filters[_index_0] - append(flags, { - "--vf-add=" .. tostring(f) - }) - end - append(flags, get_speed_flags()) - return flags -end -local calculate_bitrate -calculate_bitrate = function(active_tracks, format, length) - if format.videoCodec == "" then - return nil, options.target_filesize * 8 / length - end - local video_kilobits = options.target_filesize * 8 - local audio_kilobits = nil - local has_audio_track = #active_tracks["audio"] > 0 - if options.strict_filesize_constraint and has_audio_track then - audio_kilobits = length * options.strict_audio_bitrate - video_kilobits = video_kilobits - audio_kilobits - end - local video_bitrate = math.floor(video_kilobits / length) - local audio_bitrate = audio_kilobits and math.floor(audio_kilobits / length) or nil - return video_bitrate, audio_bitrate -end -local find_path -find_path = function(startTime, endTime) - local path = mp.get_property('path') - if not path then - return nil, nil, nil, nil, nil - end - local is_stream = not file_exists(path) - local is_temporary = false - if is_stream then - if mp.get_property('file-format') == 'hls' then - path = utils.join_path(parse_directory('~'), 'cache_dump.ts') - mp.command_native({ - 'dump_cache', - seconds_to_time_string(startTime, false, true), - seconds_to_time_string(endTime + 5, false, true), - path - }) - endTime = endTime - startTime - startTime = 0 - is_temporary = true - end - end - return path, is_stream, is_temporary, startTime, endTime -end -local encode -encode = function(region, startTime, endTime) - local format = formats[options.output_format] - local originalStartTime = startTime - local originalEndTime = endTime - local path, is_stream, is_temporary - path, is_stream, is_temporary, startTime, endTime = find_path(startTime, endTime) - if not path then - message("No file is being played") - return - end - local command = { - "mpv", - path, - "--start=" .. seconds_to_time_string(startTime, false, true), - "--end=" .. seconds_to_time_string(endTime, false, true), - "--loop-file=no", - "--no-pause" - } - append(command, format:getCodecFlags()) - local active_tracks = get_active_tracks() - local supported_active_tracks = filter_tracks_supported_by_format(active_tracks, format) - for track_type, tracks in pairs(supported_active_tracks) do - if track_type == "audio" then - append_audio_tracks(command, tracks) - else - for _index_0 = 1, #tracks do - local track = tracks[_index_0] - append_track(command, track) - end - end - end - for track_type, tracks in pairs(supported_active_tracks) do - local _continue_0 = false - repeat - if #tracks > 0 then - _continue_0 = true - break - end - local _exp_0 = track_type - if "video" == _exp_0 then - append(command, { - "--vid=no" - }) - elseif "audio" == _exp_0 then - append(command, { - "--aid=no" - }) - elseif "sub" == _exp_0 then - append(command, { - "--sid=no" - }) - end - _continue_0 = true - until true - if not _continue_0 then - break - end - end - if format.videoCodec ~= "" then - append(command, get_video_encode_flags(format, region)) - end - append(command, format:getFlags()) - if options.write_filename_on_metadata then - append(command, get_metadata_flags()) - end - if format.acceptsBitrate then - if options.target_filesize > 0 then - local length = endTime - startTime - local video_bitrate, audio_bitrate = calculate_bitrate(supported_active_tracks, format, length) - if video_bitrate then - append(command, { - "--ovcopts-add=b=" .. tostring(video_bitrate) .. "k" - }) - end - if audio_bitrate then - append(command, { - "--oacopts-add=b=" .. tostring(audio_bitrate) .. "k" - }) - end - if options.strict_filesize_constraint then - local type = format.videoCodec ~= "" and "ovc" or "oac" - append(command, { - "--" .. tostring(type) .. "opts-add=minrate=" .. tostring(bitrate) .. "k", - "--" .. tostring(type) .. "opts-add=maxrate=" .. tostring(bitrate) .. "k" - }) - end - else - local type = format.videoCodec ~= "" and "ovc" or "oac" - append(command, { - "--" .. tostring(type) .. "opts-add=b=0" - }) - end - end - for token in string.gmatch(options.additional_flags, "[^%s]+") do - command[#command + 1] = token - end - if not options.strict_filesize_constraint then - for token in string.gmatch(options.non_strict_additional_flags, "[^%s]+") do - command[#command + 1] = token - end - if options.crf >= 0 then - append(command, { - "--ovcopts-add=crf=" .. tostring(options.crf) - }) - end - end - local dir = "" - if is_stream then - dir = parse_directory("~") - else - local _ - dir, _ = utils.split_path(path) - end - if options.output_directory ~= "" then - dir = parse_directory(options.output_directory) - end - local formatted_filename = format_filename(originalStartTime, originalEndTime, format) - local out_path = utils.join_path(dir, formatted_filename) - append(command, { - "--o=" .. tostring(out_path) - }) - emit_event("encode-started") - if options.twopass and format.supportsTwopass and not is_stream then - local first_pass_cmdline - do - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #command do - local arg = command[_index_0] - _accum_0[_len_0] = arg - _len_0 = _len_0 + 1 - end - first_pass_cmdline = _accum_0 - end - append(first_pass_cmdline, { - "--ovcopts-add=flags=+pass1" - }) - message("Starting first pass...") - msg.verbose("First-pass command line: ", table.concat(first_pass_cmdline, " ")) - local res = run_subprocess({ - args = first_pass_cmdline, - cancellable = false - }) - if not res then - message("First pass failed! Check the logs for details.") - emit_event("encode-finished", "fail") - return - end - append(command, { - "--ovcopts-add=flags=+pass2" - }) - if format.videoCodec == "libvpx" then - msg.verbose("Patching libvpx pass log file...") - vp8_patch_logfile(get_pass_logfile_path(out_path), endTime - startTime) - end - end - command = format:postCommandModifier(command, region, startTime, endTime) - msg.info("Encoding to", out_path) - msg.verbose("Command line:", table.concat(command, " ")) - if options.run_detached then - message("Started encode, process was detached.") - return utils.subprocess_detached({ - args = command - }) - else - local res = false - if not should_display_progress() then - message("Started encode...") - res = run_subprocess({ - args = command, - cancellable = false - }) - else - local ewp = EncodeWithProgress(startTime, endTime) - res = ewp:startEncode(command) - end - if res then - message("Encoded successfully! Saved to\\N" .. tostring(bold(out_path))) - emit_event("encode-finished", "success") - else - message("Encode failed! Check the logs for details.") - emit_event("encode-finished", "fail") - end - os.remove(get_pass_logfile_path(out_path)) - if is_temporary then - return os.remove(path) - end - end -end -local CropPage -do - local _class_0 - local _parent_0 = Page - local _base_0 = { - reset = function(self) - local dimensions = get_video_dimensions() - local xa, ya - do - local _obj_0 = dimensions.top_left - xa, ya = _obj_0.x, _obj_0.y - end - self.pointA:set_from_screen(xa, ya) - local xb, yb - do - local _obj_0 = dimensions.bottom_right - xb, yb = _obj_0.x, _obj_0.y - end - self.pointB:set_from_screen(xb, yb) - if self.visible then - return self:draw() - end - end, - setPointA = function(self) - local posX, posY = mp.get_mouse_pos() - self.pointA:set_from_screen(posX, posY) - if self.visible then - return self:draw() - end - end, - setPointB = function(self) - local posX, posY = mp.get_mouse_pos() - self.pointB:set_from_screen(posX, posY) - if self.visible then - return self:draw() - end - end, - cancel = function(self) - self:hide() - return self.callback(false, nil) - end, - finish = function(self) - local region = Region() - region:set_from_points(self.pointA, self.pointB) - self:hide() - return self.callback(true, region) - end, - draw_box = function(self, ass) - local region = Region() - region:set_from_points(self.pointA:to_screen(), self.pointB:to_screen()) - local d = get_video_dimensions() - ass:new_event() - ass:append("{\\an7}") - ass:pos(0, 0) - ass:append('{\\bord0}') - ass:append('{\\shad0}') - ass:append('{\\c&H000000&}') - ass:append('{\\alpha&H77}') - ass:draw_start() - ass:rect_cw(d.top_left.x, d.top_left.y, region.x, region.y + region.h) - ass:rect_cw(region.x, d.top_left.y, d.bottom_right.x, region.y) - ass:rect_cw(d.top_left.x, region.y + region.h, region.x + region.w, d.bottom_right.y) - ass:rect_cw(region.x + region.w, region.y, d.bottom_right.x, d.bottom_right.y) - return ass:draw_stop() - end, - draw = function(self) - local window = { } - window.w, window.h = mp.get_osd_size() - local ass = assdraw.ass_new() - self:draw_box(ass) - ass:new_event() - self:setup_text(ass) - ass:append(tostring(bold('Crop:')) .. "\\N") - ass:append(tostring(bold('1:')) .. " change point A (" .. tostring(self.pointA.x) .. ", " .. tostring(self.pointA.y) .. ")\\N") - ass:append(tostring(bold('2:')) .. " change point B (" .. tostring(self.pointB.x) .. ", " .. tostring(self.pointB.y) .. ")\\N") - ass:append(tostring(bold('r:')) .. " reset to whole screen\\N") - ass:append(tostring(bold('ESC:')) .. " cancel crop\\N") - local width, height = math.abs(self.pointA.x - self.pointB.x), math.abs(self.pointA.y - self.pointB.y) - ass:append(tostring(bold('ENTER:')) .. " confirm crop (" .. tostring(width) .. "x" .. tostring(height) .. ")\\N") - return mp.set_osd_ass(window.w, window.h, ass.text) - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self, callback, region) - self.pointA = VideoPoint() - self.pointB = VideoPoint() - self.keybinds = { - ["1"] = (function() - local _base_1 = self - local _fn_0 = _base_1.setPointA - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["2"] = (function() - local _base_1 = self - local _fn_0 = _base_1.setPointB - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["r"] = (function() - local _base_1 = self - local _fn_0 = _base_1.reset - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["ESC"] = (function() - local _base_1 = self - local _fn_0 = _base_1.cancel - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["ENTER"] = (function() - local _base_1 = self - local _fn_0 = _base_1.finish - return function(...) - return _fn_0(_base_1, ...) - end - end)() - } - self:reset() - self.callback = callback - if region and region:is_valid() then - self.pointA.x = region.x - self.pointA.y = region.y - self.pointB.x = region.x + region.w - self.pointB.y = region.y + region.h - end - end, - __base = _base_0, - __name = "CropPage", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - CropPage = _class_0 -end -local Option -do - local _class_0 - local _base_0 = { - hasPrevious = function(self) - local _exp_0 = self.optType - if "bool" == _exp_0 then - return true - elseif "int" == _exp_0 then - if self.opts.min then - return self.value > self.opts.min - else - return true - end - elseif "list" == _exp_0 then - return self.value > 1 - end - end, - hasNext = function(self) - local _exp_0 = self.optType - if "bool" == _exp_0 then - return true - elseif "int" == _exp_0 then - if self.opts.max then - return self.value < self.opts.max - else - return true - end - elseif "list" == _exp_0 then - return self.value < #self.opts.possibleValues - end - end, - leftKey = function(self) - local _exp_0 = self.optType - if "bool" == _exp_0 then - self.value = not self.value - elseif "int" == _exp_0 then - self.value = self.value - self.opts.step - if self.opts.min and self.opts.min > self.value then - self.value = self.opts.min - end - elseif "list" == _exp_0 then - if self.value > 1 then - self.value = self.value - 1 - end - end - end, - rightKey = function(self) - local _exp_0 = self.optType - if "bool" == _exp_0 then - self.value = not self.value - elseif "int" == _exp_0 then - self.value = self.value + self.opts.step - if self.opts.max and self.opts.max < self.value then - self.value = self.opts.max - end - elseif "list" == _exp_0 then - if self.value < #self.opts.possibleValues then - self.value = self.value + 1 - end - end - end, - getValue = function(self) - local _exp_0 = self.optType - if "bool" == _exp_0 then - return self.value - elseif "int" == _exp_0 then - return self.value - elseif "list" == _exp_0 then - local value, _ - do - local _obj_0 = self.opts.possibleValues[self.value] - value, _ = _obj_0[1], _obj_0[2] - end - return value - end - end, - setValue = function(self, value) - local _exp_0 = self.optType - if "bool" == _exp_0 then - self.value = value - elseif "int" == _exp_0 then - self.value = value - elseif "list" == _exp_0 then - local set = false - for i, possiblePair in ipairs(self.opts.possibleValues) do - local possibleValue, _ - possibleValue, _ = possiblePair[1], possiblePair[2] - if possibleValue == value then - set = true - self.value = i - break - end - end - if not set then - return msg.warn("Tried to set invalid value " .. tostring(value) .. " to " .. tostring(self.displayText) .. " option.") - end - end - end, - getDisplayValue = function(self) - local _exp_0 = self.optType - if "bool" == _exp_0 then - return self.value and "yes" or "no" - elseif "int" == _exp_0 then - if self.opts.altDisplayNames and self.opts.altDisplayNames[self.value] then - return self.opts.altDisplayNames[self.value] - else - return tostring(self.value) - end - elseif "list" == _exp_0 then - local value, displayValue - do - local _obj_0 = self.opts.possibleValues[self.value] - value, displayValue = _obj_0[1], _obj_0[2] - end - return displayValue or value - end - end, - draw = function(self, ass, selected) - if selected then - ass:append(tostring(bold(self.displayText)) .. ": ") - else - ass:append(tostring(self.displayText) .. ": ") - end - if self:hasPrevious() then - ass:append("◀ ") - end - ass:append(self:getDisplayValue()) - if self:hasNext() then - ass:append(" ▶") - end - return ass:append("\\N") - end, - optVisible = function(self) - if self.visibleCheckFn == nil then - return true - else - return self.visibleCheckFn() - end - end - } - _base_0.__index = _base_0 - _class_0 = setmetatable({ - __init = function(self, optType, displayText, value, opts, visibleCheckFn) - self.optType = optType - self.displayText = displayText - self.opts = opts - self.value = 1 - self.visibleCheckFn = visibleCheckFn - return self:setValue(value) - end, - __base = _base_0, - __name = "Option" - }, { - __index = _base_0, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - Option = _class_0 -end -local EncodeOptionsPage -do - local _class_0 - local _parent_0 = Page - local _base_0 = { - getCurrentOption = function(self) - return self.options[self.currentOption][2] - end, - leftKey = function(self) - (self:getCurrentOption()):leftKey() - return self:draw() - end, - rightKey = function(self) - (self:getCurrentOption()):rightKey() - return self:draw() - end, - prevOpt = function(self) - for i = self.currentOption - 1, 1, -1 do - if self.options[i][2]:optVisible() then - self.currentOption = i - break - end - end - return self:draw() - end, - nextOpt = function(self) - for i = self.currentOption + 1, #self.options do - if self.options[i][2]:optVisible() then - self.currentOption = i - break - end - end - return self:draw() - end, - confirmOpts = function(self) - for _, optPair in ipairs(self.options) do - local optName, opt - optName, opt = optPair[1], optPair[2] - options[optName] = opt:getValue() - end - self:hide() - return self.callback(true) - end, - cancelOpts = function(self) - self:hide() - return self.callback(false) - end, - draw = function(self) - local window_w, window_h = mp.get_osd_size() - local ass = assdraw.ass_new() - ass:new_event() - self:setup_text(ass) - ass:append(tostring(bold('Options:')) .. "\\N\\N") - for i, optPair in ipairs(self.options) do - local opt = optPair[2] - if opt:optVisible() then - opt:draw(ass, self.currentOption == i) - end - end - ass:append("\\N▲ / ▼: navigate\\N") - ass:append(tostring(bold('ENTER:')) .. " confirm options\\N") - ass:append(tostring(bold('ESC:')) .. " cancel\\N") - return mp.set_osd_ass(window_w, window_h, ass.text) - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self, callback) - self.callback = callback - self.currentOption = 1 - local scaleHeightOpts = { - possibleValues = { - { - -1, - "no" - }, - { - 144 - }, - { - 240 - }, - { - 360 - }, - { - 480 - }, - { - 540 - }, - { - 720 - }, - { - 1080 - }, - { - 1440 - }, - { - 2160 - } - } - } - local filesizeOpts = { - step = 250, - min = 0, - altDisplayNames = { - [0] = "0 (constant quality)" - } - } - local crfOpts = { - step = 1, - min = -1, - altDisplayNames = { - [-1] = "disabled" - } - } - local fpsOpts = { - possibleValues = { - { - -1, - "source" - }, - { - 15 - }, - { - 24 - }, - { - 30 - }, - { - 48 - }, - { - 50 - }, - { - 60 - }, - { - 120 - }, - { - 240 - } - } - } - local formatIds = { - "webm-vp8", - "webm-vp9", - "mp4", - "mp4-nvenc", - "raw", - "mp3", - "gif" - } - local formatOpts = { - possibleValues = (function() - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #formatIds do - local fId = formatIds[_index_0] - _accum_0[_len_0] = { - fId, - formats[fId].displayName - } - _len_0 = _len_0 + 1 - end - return _accum_0 - end)() - } - local gifDitherOpts = { - possibleValues = { - { - 0, - "bayer_scale 0" - }, - { - 1, - "bayer_scale 1" - }, - { - 2, - "bayer_scale 2" - }, - { - 3, - "bayer_scale 3" - }, - { - 4, - "bayer_scale 4" - }, - { - 5, - "bayer_scale 5" - }, - { - 6, - "sierra2_4a" - } - } - } - self.options = { - { - "output_format", - Option("list", "Output Format", options.output_format, formatOpts) - }, - { - "twopass", - Option("bool", "Two Pass", options.twopass) - }, - { - "apply_current_filters", - Option("bool", "Apply Current Video Filters", options.apply_current_filters) - }, - { - "scale_height", - Option("list", "Scale Height", options.scale_height, scaleHeightOpts) - }, - { - "strict_filesize_constraint", - Option("bool", "Strict Filesize Constraint", options.strict_filesize_constraint) - }, - { - "write_filename_on_metadata", - Option("bool", "Write Filename on Metadata", options.write_filename_on_metadata) - }, - { - "target_filesize", - Option("int", "Target Filesize", options.target_filesize, filesizeOpts) - }, - { - "crf", - Option("int", "CRF", options.crf, crfOpts) - }, - { - "fps", - Option("list", "FPS", options.fps, fpsOpts) - }, - { - "gif_dither", - Option("list", "GIF Dither Type", options.gif_dither, gifDitherOpts, function() - return self.options[1][2]:getValue() == "gif" - end) - }, - { - "force_square_pixels", - Option("bool", "Force Square Pixels", options.force_square_pixels) - } - } - self.keybinds = { - ["LEFT"] = (function() - local _base_1 = self - local _fn_0 = _base_1.leftKey - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["RIGHT"] = (function() - local _base_1 = self - local _fn_0 = _base_1.rightKey - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["UP"] = (function() - local _base_1 = self - local _fn_0 = _base_1.prevOpt - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["DOWN"] = (function() - local _base_1 = self - local _fn_0 = _base_1.nextOpt - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["ENTER"] = (function() - local _base_1 = self - local _fn_0 = _base_1.confirmOpts - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["ESC"] = (function() - local _base_1 = self - local _fn_0 = _base_1.cancelOpts - return function(...) - return _fn_0(_base_1, ...) - end - end)() - } - end, - __base = _base_0, - __name = "EncodeOptionsPage", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - EncodeOptionsPage = _class_0 -end -local PreviewPage -do - local _class_0 - local _parent_0 = Page - local _base_0 = { - prepare = function(self) - local vf = mp.get_property_native("vf") - vf[#vf + 1] = { - name = "sub" - } - if self.region:is_valid() then - vf[#vf + 1] = { - name = "crop", - params = { - w = tostring(self.region.w), - h = tostring(self.region.h), - x = tostring(self.region.x), - y = tostring(self.region.y) - } - } - end - mp.set_property_native("vf", vf) - if self.startTime > -1 and self.endTime > -1 then - mp.set_property_native("ab-loop-a", self.startTime) - mp.set_property_native("ab-loop-b", self.endTime) - mp.set_property_native("time-pos", self.startTime) - end - return mp.set_property_native("pause", false) - end, - dispose = function(self) - mp.set_property("ab-loop-a", "no") - mp.set_property("ab-loop-b", "no") - for prop, value in pairs(self.originalProperties) do - mp.set_property_native(prop, value) - end - end, - draw = function(self) - local window_w, window_h = mp.get_osd_size() - local ass = assdraw.ass_new() - ass:new_event() - self:setup_text(ass) - ass:append("Press " .. tostring(bold('ESC')) .. " to exit preview.\\N") - return mp.set_osd_ass(window_w, window_h, ass.text) - end, - cancel = function(self) - self:hide() - return self.callback() - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self, callback, region, startTime, endTime) - self.callback = callback - self.originalProperties = { - ["vf"] = mp.get_property_native("vf"), - ["time-pos"] = mp.get_property_native("time-pos"), - ["pause"] = mp.get_property_native("pause") - } - self.keybinds = { - ["ESC"] = (function() - local _base_1 = self - local _fn_0 = _base_1.cancel - return function(...) - return _fn_0(_base_1, ...) - end - end)() - } - self.region = region - self.startTime = startTime - self.endTime = endTime - self.isLoop = false - end, - __base = _base_0, - __name = "PreviewPage", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - PreviewPage = _class_0 -end -local MainPage -do - local _class_0 - local _parent_0 = Page - local _base_0 = { - setStartTime = function(self) - self.startTime = mp.get_property_number("time-pos") - if self.visible then - self:clear() - return self:draw() - end - end, - setEndTime = function(self) - self.endTime = mp.get_property_number("time-pos") - if self.visible then - self:clear() - return self:draw() - end - end, - setupStartAndEndTimes = function(self) - if mp.get_property_native("duration") then - self.startTime = 0 - self.endTime = mp.get_property_native("duration") - else - self.startTime = -1 - self.endTime = -1 - end - if self.visible then - self:clear() - return self:draw() - end - end, - draw = function(self) - local window_w, window_h = mp.get_osd_size() - local ass = assdraw.ass_new() - ass:new_event() - self:setup_text(ass) - ass:append(tostring(bold('WebM maker')) .. "\\N\\N") - ass:append(tostring(bold('c:')) .. " crop\\N") - ass:append(tostring(bold('1:')) .. " set start time (current is " .. tostring(seconds_to_time_string(self.startTime)) .. ")\\N") - ass:append(tostring(bold('2:')) .. " set end time (current is " .. tostring(seconds_to_time_string(self.endTime)) .. ")\\N") - ass:append(tostring(bold('o:')) .. " change encode options\\N") - ass:append(tostring(bold('p:')) .. " preview\\N") - ass:append(tostring(bold('e:')) .. " encode\\N\\N") - ass:append(tostring(bold('ESC:')) .. " close\\N") - return mp.set_osd_ass(window_w, window_h, ass.text) - end, - show = function(self) - _class_0.__parent.show(self) - return emit_event("show-main-page") - end, - onUpdateCropRegion = function(self, updated, newRegion) - if updated then - self.region = newRegion - end - return self:show() - end, - crop = function(self) - self:hide() - local cropPage = CropPage((function() - local _base_1 = self - local _fn_0 = _base_1.onUpdateCropRegion - return function(...) - return _fn_0(_base_1, ...) - end - end)(), self.region) - return cropPage:show() - end, - onOptionsChanged = function(self, updated) - return self:show() - end, - changeOptions = function(self) - self:hide() - local encodeOptsPage = EncodeOptionsPage((function() - local _base_1 = self - local _fn_0 = _base_1.onOptionsChanged - return function(...) - return _fn_0(_base_1, ...) - end - end)()) - return encodeOptsPage:show() - end, - onPreviewEnded = function(self) - return self:show() - end, - preview = function(self) - self:hide() - local previewPage = PreviewPage((function() - local _base_1 = self - local _fn_0 = _base_1.onPreviewEnded - return function(...) - return _fn_0(_base_1, ...) - end - end)(), self.region, self.startTime, self.endTime) - return previewPage:show() - end, - encode = function(self) - self:hide() - if self.startTime < 0 then - message("No start time, aborting") - return - end - if self.endTime < 0 then - message("No end time, aborting") - return - end - if self.startTime >= self.endTime then - message("Start time is ahead of end time, aborting") - return - end - return encode(self.region, self.startTime, self.endTime) - end - } - _base_0.__index = _base_0 - setmetatable(_base_0, _parent_0.__base) - _class_0 = setmetatable({ - __init = function(self) - self.keybinds = { - ["c"] = (function() - local _base_1 = self - local _fn_0 = _base_1.crop - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["1"] = (function() - local _base_1 = self - local _fn_0 = _base_1.setStartTime - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["2"] = (function() - local _base_1 = self - local _fn_0 = _base_1.setEndTime - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["o"] = (function() - local _base_1 = self - local _fn_0 = _base_1.changeOptions - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["p"] = (function() - local _base_1 = self - local _fn_0 = _base_1.preview - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["e"] = (function() - local _base_1 = self - local _fn_0 = _base_1.encode - return function(...) - return _fn_0(_base_1, ...) - end - end)(), - ["ESC"] = (function() - local _base_1 = self - local _fn_0 = _base_1.hide - return function(...) - return _fn_0(_base_1, ...) - end - end)() - } - self.startTime = -1 - self.endTime = -1 - self.region = Region() - end, - __base = _base_0, - __name = "MainPage", - __parent = _parent_0 - }, { - __index = function(cls, name) - local val = rawget(_base_0, name) - if val == nil then - local parent = rawget(cls, "__parent") - if parent then - return parent[name] - end - else - return val - end - end, - __call = function(cls, ...) - local _self_0 = setmetatable({}, _base_0) - cls.__init(_self_0, ...) - return _self_0 - end - }) - _base_0.__class = _class_0 - if _parent_0.__inherited then - _parent_0.__inherited(_parent_0, _class_0) - end - MainPage = _class_0 -end -monitor_dimensions() -local mainPage = MainPage() -mp.add_key_binding(options.keybind, "display-webm-encoder", (function() - local _base_0 = mainPage - local _fn_0 = _base_0.show - return function(...) - return _fn_0(_base_0, ...) - end -end)(), { - repeatable = false -}) -mp.register_event("file-loaded", (function() - local _base_0 = mainPage - local _fn_0 = _base_0.setupStartAndEndTimes - return function(...) - return _fn_0(_base_0, ...) - end -end)()) -msg.verbose("Loaded mpv-webm script!") -return emit_event("script-loaded") -- cgit v1.2.3