From 3b94b429286c50eb98e31b9f153c9082373f4328 Mon Sep 17 00:00:00 2001 From: Erik Sandström Date: Sat, 15 Aug 2015 21:04:16 +0200 Subject: Updated mpv conf and changed some structure --- mpv/config | 48 +- mpv/input.conf | 1 + mpv/scripts.other/fpsadjust.lua | 50 ++ mpv/scripts.other/mpv-progressbar.lua | 1052 +++++++++++++++++++++++++++++++++ mpv/scripts/autoload.lua | 121 ++++ mpv/scripts/autosub.lua | 24 + mpv/scripts/stats.lua | 263 +++++++++ 7 files changed, 1540 insertions(+), 19 deletions(-) create mode 100644 mpv/scripts.other/fpsadjust.lua create mode 100644 mpv/scripts.other/mpv-progressbar.lua create mode 100644 mpv/scripts/autoload.lua create mode 100644 mpv/scripts/autosub.lua create mode 100644 mpv/scripts/stats.lua (limited to 'mpv') diff --git a/mpv/config b/mpv/config index 99c1536..a56e32b 100644 --- a/mpv/config +++ b/mpv/config @@ -1,40 +1,49 @@ -# misc settings +## Misc settings title="MPV" -no-osc -no-osd +#no-osc no-osd-bar +script-opts=osc-layout=bottombar + +## Audio Stuffs +#af=drc +ao=pulse +softvol=yes +alang=en,eng,English,jpn,jap,Japanese +audio-channels=2 + + +## Video Stuffs #hwdec=vaapi #vo=vaapi +video-sync=display-resample +display-fps=60 +vo=opengl-hq:interpolation:tscale=robidouxsharp:dither-depth=auto:temporal-dither:source-shader=/home/zephcom/.config/mpv/shaders/deband.glsl:gamma=0.8:target-prim=bt.709:target-trc=bt.1886:blend-subtitles:pbo +force-window -#Mitchell -vo=opengl-hq:interpolation:tscale=mitchell:dither-depth=8:temporal-dither:pbo:target-prim=bt.709:target-trc=bt.1886:source-shader=/home/zephcom/.mpv/shaders/deband.glsl:gamma-auto +demuxer-thread=yes framedrop=vo cache=10000 geometry=50%:50% autofit-larger=90%x90% -audio-channels=2 save-position-on-quit=yes -softvol=yes -ao=pulse -alang=en,eng,English,jpn,jap,Japanese +# Youtube-dl stuffs ytdl -ytdl-format=bestvideo+bestaudio +#ytdl-format=bestvideo+bestaudio # Pretty srt font! slang=en,eng,English osd-font="Liberation Sans" -sub-text-font="Helvetica" -sub-text-font-size=38 -#sub-text-margin-y=14 +sub-text-font="Open Sans Semibold" +sub-text-font-size=48 sub-text-color="#ffffffff" -sub-text-border-color="#ff000000" -sub-text-border-size=2.5 +sub-text-border-color="#220035" +sub-text-border-size=3.5 sub-text-shadow-offset=1 -sub-text-shadow-color="#00000000" -sub-text-spacing=-0.2 +sub-text-shadow-color="#220035" +sub-text-spacing=-0.3 ass-force-style=Kerning=yes demuxer-mkv-subtitle-preroll sub-use-margins @@ -45,8 +54,9 @@ screenshot-format="png" screenshot-png-filter=0 screenshot-png-compression=4 -#really-quiet -# loop weebums +# loop weebums and gifs [extension.webm] loop-file=inf +[extension.gif] +loop-file=inf diff --git a/mpv/input.conf b/mpv/input.conf index 1622822..2abd93b 100644 --- a/mpv/input.conf +++ b/mpv/input.conf @@ -2,3 +2,4 @@ + add volume 2 o ignore F2 cycle_values video-aspect "16:9" "16:10" "4:3" "2.35:1" "-1" +# F3 cycle_values gamma "1.0" "0.9" "0.8" "1.1" diff --git a/mpv/scripts.other/fpsadjust.lua b/mpv/scripts.other/fpsadjust.lua new file mode 100644 index 0000000..61065cf --- /dev/null +++ b/mpv/scripts.other/fpsadjust.lua @@ -0,0 +1,50 @@ +require 'mp.options' +local opt = { + maxiters = 5, -- Frames involving at most this many frames will be + -- considered acceptable. + + maxdelta = 0.01, -- Maximum allowed speed change (setting this too high + -- could cause noticeable change in pitch and tempo) + + mindelta = 0.0005, -- Minimum speed change that would be considered + -- significant enough to be worth calculating. Any lower + -- and it will just play at 100% speed to preserve CPU + -- cycles. +} +read_options(opt) + +function get_scale(ratio, factor) + scale = ratio * factor / math.floor(ratio * factor + 0.5) + delta = math.abs(scale - 1) + + if (delta < opt.mindelta) then + return 1 -- close enough, just use it + end + if (delta > opt.maxdelta) then + return nil -- large deviation, skip + end + return scale -- decent match found +end + +function adjust_speed(event) + clip_fps = mp.get_property_number("fps") + disp_fps = mp.get_property_number("display-fps") + + if not clip_fps or not disp_fps or disp_fps == 0 then + return + end + + for i=1,opt.maxiters do + scale = get_scale(disp_fps / clip_fps, i) + if scale then + break + end + end + + if scale then + mp.set_property("speed", scale) + print("Setting speed to", scale) + end +end + +mp.register_event("playback-restart", adjust_speed) diff --git a/mpv/scripts.other/mpv-progressbar.lua b/mpv/scripts.other/mpv-progressbar.lua new file mode 100644 index 0000000..bbdd9aa --- /dev/null +++ b/mpv/scripts.other/mpv-progressbar.lua @@ -0,0 +1,1052 @@ +local msg = require('mp.msg') +local bar_height = 2 +local hover_zone = 20 +local log = { + debug = function(format, ...) + return msg.debug(format:format(...)) + end, + info = function(format, ...) + return msg.info(format:format(...)) + end, + warn = function(format, ...) + return msg.warn(format:format(...)) + end, + dump = function(item, ignore) + local level = 2 + if "table" ~= type(item) then + msg.info(tostring(item)) + return + end + local count = 1 + local tablecount = 1 + local result = { + "{ @" .. tostring(tablecount) + } + local seen = { + [item] = tablecount + } + local recurse + recurse = function(item, space) + for key, value in pairs(item) do + if not (key == ignore) then + if "table" == type(value) then + if not (seen[value]) then + tablecount = tablecount + 1 + seen[value] = tablecount + count = count + 1 + result[count] = space .. tostring(key) .. ": { @" .. tostring(tablecount) + recurse(value, space .. " ") + count = count + 1 + result[count] = space .. "}" + else + count = count + 1 + result[count] = space .. tostring(key) .. ": @" .. tostring(seen[value]) + end + else + if "string" == type(value) then + value = ("%q"):format(value) + end + count = count + 1 + result[count] = space .. tostring(key) .. ": " .. tostring(value) + end + end + end + end + recurse(item, " ") + count = count + 1 + result[count] = "}" + return msg.info(table.concat(result, "\n")) + end +} +local OSDAggregator +do + local _base_0 = { + addSubscriber = function(self, subscriber) + if not subscriber then + return + end + self.subscriberCount = self.subscriberCount + 1 + subscriber.aggregatorIndex = self.subscriberCount + self.subscribers[self.subscriberCount] = subscriber + self.script[self.subscriberCount] = subscriber:stringify() + end, + removeSubscriber = function(self, index) + table.remove(self.subscribers, index) + table.remove(self.script, index) + self.subscriberCount = self.subscriberCount - 1 + for i = index, self.subscriberCount do + self.subscribers[i].aggregatorIndex = i + end + end, + update = function(self, force) + if force == nil then + force = false + end + local needsRedraw = force + local x, y = mp.get_mouse_pos() + local w, h = mp.get_screen_size() + local needsResize = false + if w ~= self.w or h ~= self.h then + self.w, self.h = w, h + needsResize = true + end + for sub = 1, self.subscriberCount do + local theSub = self.subscribers[sub] + local update = false + if theSub:update(x, y, self.mouseOver) then + update = true + end + if (needsResize and theSub:updateSize(w, h)) or update then + needsRedraw = true + self.script[sub] = theSub:stringify() + end + end + if true == needsRedraw then + return mp.set_osd_ass(self.w, self.h, table.concat(self.script, '\n')) + end + end, + pause = function(self, event, paused) + self.paused = paused + if self.paused then + return self.updateTimer:stop() + else + return self.updateTimer:resume() + end + end, + forceUpdate = function(self) + self.updateTimer:kill() + self:update(true) + if not (self.paused) then + return self.updateTimer:resume() + end + end + } + _base_0.__index = _base_0 + local _class_0 = setmetatable({ + __init = function(self) + self.script = { } + self.subscribers = { } + self.subscriberCount = 0 + self.mouseOver = false + self.w = 0 + self.h = 0 + local redrawFrequency = 0.05 + self.updateTimer = mp.add_periodic_timer(redrawFrequency, (function() + local _base_1 = self + local _fn_0 = _base_1.update + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + mp.register_event('shutdown', function() + return self.updateTimer:kill() + end) + mp.add_key_binding("MOUSE_LEAVE", function() + self.mouseOver = false + end) + return mp.add_key_binding("MOUSE_ENTER", function() + self.mouseOver = true + end) + end, + __base = _base_0, + __name = "OSDAggregator" + }, { + __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 + OSDAggregator = _class_0 +end +local AnimationQueue +do + local _base_0 = { + registerAnimation = function(self, animation) + if self.list then + self.list.next = animation + end + animation.prev = self.list + animation.isRegistered = true + self.list = animation + self.animationCount = self.animationCount + 1 + return self:startAnimation() + end, + unregisterAnimation = function(self, animation) + local prev = animation.prev + local next = animation.next + if prev then + prev.next = next + end + if next then + next.prev = prev + end + if self.list == animation then + self.list = prev + end + animation.next = nil + animation.prev = nil + animation.isRegistered = false + self.animationCount = self.animationCount - 1 + if 0 == self.animationCount then + self:stopAnimation() + end + return prev + end, + startAnimation = function(self) + if self.animating then + return + end + self.timer:resume() + self.animating = true + end, + stopAnimation = function(self) + if not (self.animating) then + return + end + self.timer:kill() + self.animating = false + end, + destroyAnimationStack = function(self) + self:stopAnimation() + local currentAnimation = self.list + while currentAnimation do + currentAnimation = self.list.prev + self.list.prev = nil + self.list.next = nil + self.list = currentAnimation + end + end, + animate = function(self) + local currentAnimation = self.list + local currentTime = mp.get_time() + while currentAnimation do + if currentAnimation:update(currentTime) then + currentAnimation = self:unregisterAnimation(currentAnimation) + else + currentAnimation = currentAnimation.prev + end + end + return self.aggregator:forceUpdate() + end + } + _base_0.__index = _base_0 + local _class_0 = setmetatable({ + __init = function(self, aggregator) + self.aggregator = aggregator + self.list = nil + self.animationCount = 0 + self.animating = false + self.timer = mp.add_periodic_timer(0.05, (function() + local _base_1 = self + local _fn_0 = _base_1.animate + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + return self.timer:kill() + end, + __base = _base_0, + __name = "AnimationQueue" + }, { + __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 + AnimationQueue = _class_0 +end +local Animation +do + local _base_0 = { + update = function(self, currentTime) + self.currentTime = currentTime + local progress = math.max(0, math.min(1, (self.currentTime - self.startTime) * self.durationR)) + if progress == 1 then + self.isFinished = true + end + if self.accel then + progress = math.pow(progress, self.accel) + end + local value = (1 - progress) * self.initialValue + progress * self.endValue + self:updateCb(value) + if self.isFinished and self.finishedCb then + self:finishedCb() + end + return self.isFinished + end, + interrupt = function(self, reverse, queue) + if reverse ~= self.isReversed then + self:reverse() + end + if not (self.isRegistered) then + self:restart() + return queue:registerAnimation(self) + end + end, + reverse = function(self) + self.isReversed = not self.isReversed + self.initialValue, self.endValue = self.endValue, self.initialValue + self.startTime = 2 * self.currentTime - self.duration - self.startTime + self.accel = 1 / self.accel + end, + restart = function(self) + self.startTime = mp.get_time() + self.currentTime = self.startTime + self.isFinished = false + end + } + _base_0.__index = _base_0 + local _class_0 = setmetatable({ + __init = function(self, initialValue, endValue, duration, updateCb, finishedCb, accel) + if accel == nil then + accel = 1 + end + self.initialValue, self.endValue, self.duration, self.updateCb, self.finishedCb, self.accel = initialValue, endValue, duration, updateCb, finishedCb, accel + self.startTime = mp.get_time() + self.currentTime = self.startTime + self.durationR = 1 / self.duration + self.isFinished = (self.duration <= 0) + self.isRegistered = false + self.isReversed = false + end, + __base = _base_0, + __name = "Animation" + }, { + __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 + Animation = _class_0 +end +local Rect +do + local _base_0 = { + setPosition = function(self, x, y) + self.x = x or self.x + self.y = y or self.y + end, + setDimensions = function(self, w, h) + self.w = w or self.w + self.h = h or self.h + end, + move = function(self, x, y) + self.x = self.x + (x or 0) + self.y = self.y + (y or 0) + end, + stretch = function(self, w, h) + self.w = self.w + (w or 0) + self.h = self.h + (h or 0) + end, + containsPoint = function(self, x, y) + return ((x >= self.x) and (y >= self.y) and (x < self.x + self.w) and (y < self.y + self.h)) + end + } + _base_0.__index = _base_0 + local _class_0 = setmetatable({ + __init = function(self, x, y, w, h) + self.x, self.y, self.w, self.h = x, y, w, h + end, + __base = _base_0, + __name = "Rect" + }, { + __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 + Rect = _class_0 +end +local Subscriber +do + local _parent_0 = Rect + local _base_0 = { + stringify = function(self) + if not self.hovered and not self.animation.isRegistered then + return "" + end + return table.concat(self.line) + end, + updateSize = function(self, w, h) + self.y = h - hover_zone * bar_height + self.w, self.h = w, hover_zone * bar_height + end, + update = function(self, mouseX, mouseY, mouseOver, hoverCondition) + if hoverCondition == nil then + hoverCondition = self:containsPoint(mouseX, mouseY) + end + local update = self.needsUpdate + self.needsUpdate = false + if mouseOver and hoverCondition then + if not (self.hovered) then + update = true + self.hovered = true + self.animation:interrupt(false, self.animationQueue) + end + else + if self.hovered then + update = true + self.hovered = false + self.animation:interrupt(true, self.animationQueue) + end + end + return update + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self) + _parent_0.__init(self, 0, 0, 0, 0) + self.hovered = false + self.needsUpdate = false + end, + __base = _base_0, + __name = "Subscriber", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + Subscriber = _class_0 +end +local ProgressBar +do + local _parent_0 = Subscriber + local _base_0 = { + clickUpSeek = function(self) + local x, y = mp.get_mouse_pos() + if self:containsPoint(x, y) then + return mp.commandv("seek", x * 100 / self.w, "absolute-percent", "keyframes") + end + end, + stringify = function(self) + return table.concat(self.line) + end, + updateSize = function(self, w, h) + _parent_0.updateSize(self, w, h) + self.line[2] = ([[%d,%d]]):format(0, h) + self.line[8] = ([[%d 0 %d %d 0 %d]]):format(w * 4, w * 4, bar_height * 4, bar_height * 4) + return true + end, + animateHeight = function(self, animation, value) + self.line[6] = ([[%g]]):format(value) + self.needsUpdate = true + end, + update = function(self, mouseX, mouseY, mouseOver) + local update = _parent_0.update(self, mouseX, mouseY, mouseOver) + local position = mp.get_property_number('percent-pos', 0) + if position ~= self.lastPosition then + update = true + self.line[4] = ([[%g]]):format(position) + self.lastPosition = position + end + return update + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self, animationQueue) + self.animationQueue = animationQueue + _parent_0.__init(self) + self.line = { + [[{\an1\bord0\c&HFFFFFF&\p3\pos(]], + 0, + [[)\fscx]], + 0, + [[\fscy]], + 100, + [[}m 0 0 l ]], + 0 + } + self.lastPosition = 0 + self.animation = Animation(100, 400, 0.25, (function() + local _base_1 = self + local _fn_0 = _base_1.animateHeight + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + return mp.add_key_binding("MOUSE_BTN0", (function() + local _base_1 = self + local _fn_0 = _base_1.clickUpSeek + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + end, + __base = _base_0, + __name = "ProgressBar", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + ProgressBar = _class_0 +end +local ProgressBarBackground +do + local _parent_0 = Subscriber + local _base_0 = { + stringify = function(self) + return table.concat(self.line) + end, + updateSize = function(self, w, h) + _parent_0.updateSize(self, w, h) + self.line[2] = ([[%d,%d]]):format(0, h) + self.line[6] = ([[%d 0 %d %d 0 %d]]):format(w, w, bar_height, bar_height) + return true + end, + animateHeight = function(self, animation, value) + self.line[4] = ([[%g]]):format(value) + self.needsUpdate = true + end, + update = function(self, mouseX, mouseY, mouseOver) + return _parent_0.update(self, mouseX, mouseY, mouseOver) + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self, animationQueue) + self.animationQueue = animationQueue + _parent_0.__init(self) + self.line = { + [[{\an1\bord0\c&H262626&\p1\pos(]], + 0, + [[)\fscy]], + 100, + [[}m 0 0 l ]], + 0 + } + self.animation = Animation(100, 400, 0.25, (function() + local _base_1 = self + local _fn_0 = _base_1.animateHeight + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + end, + __base = _base_0, + __name = "ProgressBarBackground", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + ProgressBarBackground = _class_0 +end +local ChapterMarker +do + local _parent_0 = Subscriber + local _base_0 = { + stringify = function(self) + if self.passed then + self.line[2][7] = [[\c&H262626&]] + else + self.line[2][7] = [[\c&HFFFFFF&]] + end + if self.hovered or self.animation.isRegistered then + return table.concat({ + table.concat(self.line[1]), + table.concat(self.line[2]) + }, '\n') + else + return table.concat(self.line[2]) + end + end, + updateSize = function(self, w, h) + self.x = math.floor(w * self.position) + self.y = h - hover_zone * bar_height + self.line[1][2] = ([[%d,%d]]):format(self.x + 10, h - hover_zone - 10) + self.line[2][2] = ([[%d,%d]]):format(self.x + 10, h) + return true + end, + animateAlpha = function(self, animation, value) + self.line[1][4] = ([[%02X]]):format(value) + self.needsUpdate = true + end, + animateSize = function(self, value) + self.line[2][4] = ([[%g]]):format(value * 100 + 100) + self.line[2][6] = ([[%g]]):format(value * 300 + 100) + end, + update = function(self, mouseX, mouseY, mouseOver, position) + local update = _parent_0.update(self, mouseX, mouseY, mouseOver) + local changed = self.passed + self.passed = position > self.position + update = update or changed ~= self.passed + return update + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self, animationQueue, title, position, w, h) + self.animationQueue, self.position = animationQueue, position + _parent_0.__init(self) + self.x = math.floor(w * self.position) - 10 + self.y = h - hover_zone * bar_height + self.w = 20 + self.h = hover_zone * bar_height + self.line = { + { + [[{\an2\bord2\c&H262626&\3c&HFFFFFF\fs30\pos(]], + ([[%d,%d]]):format(self.x + 10, h - hover_zone - 10), + [[)\alpha&H]], + [[FF]], + ([[&}%s]]):format(title) + }, + { + [[{\an2\bord0\p1\pos(]], + ([[%d,%d]]):format(self.x + 10, h), + [[)\fscx]], + 100, + [[\fscy]], + 100, + [[\c&HFFFFFF&]], + [[}m 0 0 l 2 0 2 2 0 2]] + } + } + self.passed = false + self.animation = Animation(255, 0, 0.25, (function() + local _base_1 = self + local _fn_0 = _base_1.animateAlpha + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + end, + __base = _base_0, + __name = "ChapterMarker", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + ChapterMarker = _class_0 +end +local Chapters +do + local _parent_0 = Subscriber + local _base_0 = { + createMarkers = function(self, w, h) + self.markers = { } + local totalTime = mp.get_property_number('length', 0) + local chapters = mp.get_property_native('chapter-list', { }) + for _index_0 = 1, #chapters do + local chapter = chapters[_index_0] + table.insert(self.markers, ChapterMarker(self.animationQueue, chapter.title, chapter.time / totalTime, w, h)) + end + end, + stringify = function(self) + return table.concat(self.line, '\n') + end, + redrawMarkers = function(self) + self.line = { } + local _list_0 = self.markers + for _index_0 = 1, #_list_0 do + local marker = _list_0[_index_0] + table.insert(self.line, marker:stringify()) + end + end, + updateSize = function(self, w, h) + _parent_0.updateSize(self, w, h) + local _list_0 = self.markers + for _index_0 = 1, #_list_0 do + local marker = _list_0[_index_0] + marker:updateSize(w, h) + end + self:redrawMarkers() + return true + end, + animateSize = function(self, animation, value) + local _list_0 = self.markers + for _index_0 = 1, #_list_0 do + local marker = _list_0[_index_0] + marker:animateSize(value) + end + self.needsUpdate = true + end, + update = function(self, mouseX, mouseY, mouseOver) + local update = _parent_0.update(self, mouseX, mouseY, mouseOver) + local currentPosition = mp.get_property_number('percent-pos', 0) * 0.01 + local _list_0 = self.markers + for _index_0 = 1, #_list_0 do + local marker = _list_0[_index_0] + if marker:update(mouseX, mouseY, mouseOver, currentPosition) then + update = true + end + end + if update then + self:redrawMarkers() + end + return update + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self, animationQueue) + self.animationQueue = animationQueue + _parent_0.__init(self) + self.line = { } + self.markers = { } + self.animation = Animation(0, 1, 0.25, (function() + local _base_1 = self + local _fn_0 = _base_1.animateSize + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + end, + __base = _base_0, + __name = "Chapters", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + Chapters = _class_0 +end +local TimeElapsed +do + local _parent_0 = Subscriber + local _base_0 = { + updateSize = function(self, w, h) + _parent_0.updateSize(self, w, h) + self.line[2] = ([[%g,%g]]):format(self.position, self.y + (hover_zone - 4) * bar_height) + return true + end, + animatePos = function(self, animation, value) + self.position = value + self.line[2] = ([[%g,%g]]):format(self.position, self.y + (hover_zone - 4) * bar_height) + self.needsUpdate = true + end, + update = function(self, mouseX, mouseY, mouseOver) + local update = _parent_0.update(self, mouseX, mouseY, mouseOver) + local timeElapsed = math.floor(mp.get_property_number('time-pos', 0)) + if timeElapsed ~= self.lastTime then + update = true + self.line[4] = ([[%d:%02d:%02d]]):format(timeElapsed / 3600, (timeElapsed / 60) % 60, timeElapsed % 60) + self.lastTime = timeElapsed + end + return update + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self, animationQueue) + self.animationQueue = animationQueue + _parent_0.__init(self) + self.line = { + [[{\fnSource Sans Pro Semibold\bord2\fs30\pos(]], + [[-100,0]], + [[)\3c&H262626&\c&HFFFFFF&\an1}]], + 0 + } + self.lastTime = -1 + self.position = -100 + self.animation = Animation(-100, 2, 0.25, (function() + local _base_1 = self + local _fn_0 = _base_1.animatePos + return function(...) + return _fn_0(_base_1, ...) + end + end)(), nil, 0.25) + end, + __base = _base_0, + __name = "TimeElapsed", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + TimeElapsed = _class_0 +end +local TimeRemaining +do + local _parent_0 = Subscriber + local _base_0 = { + updateSize = function(self, w, h) + _parent_0.updateSize(self, w, h) + self.line[2] = ([[%g,%g]]):format(self.position, self.y + (hover_zone - 4) * bar_height) + return true + end, + animatePos = function(self, animation, value) + self.position = self.w - value + self.line[2] = ([[%g,%g]]):format(self.position, self.y + (hover_zone - 4) * bar_height) + self.needsUpdate = true + end, + update = function(self, mouseX, mouseY, mouseOver) + local update = _parent_0.update(self, mouseX, mouseY, mouseOver) + local timeRemaining = math.floor(mp.get_property_number('playtime-remaining', 0)) + if timeRemaining ~= self.lastTime then + update = true + self.line[4] = ([[%d:%02d:%02d]]):format(timeRemaining / 3600, (timeRemaining / 60) % 60, timeRemaining % 60) + self.lastTime = timeRemaining + end + return update + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self, animationQueue) + self.animationQueue = animationQueue + _parent_0.__init(self, 0, 0, 0, 0) + self.line = { + [[{\fnSource Sans Pro Semibold\bord2\fs30\pos(]], + [[-100,0]], + [[)\3c&H262626&\c&HFFFFFF&\an3}]], + 0 + } + self.lastTime = -1 + self.position = -100 + self.animation = Animation(-100, 4, 0.25, (function() + local _base_1 = self + local _fn_0 = _base_1.animatePos + return function(...) + return _fn_0(_base_1, ...) + end + end)(), nil, 0.25) + end, + __base = _base_0, + __name = "TimeRemaining", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + TimeRemaining = _class_0 +end +local HoverTime +do + local _parent_0 = Subscriber + local _base_0 = { + animateAlpha = function(self, animation, value) + self.line[4] = ([[%02X]]):format(value) + self.needsUpdate = true + end, + update = function(self, mouseX, mouseY, mouseOver) + local update = _parent_0.update(self, mouseX, mouseY, mouseOver) + if mouseX ~= self.lastX or mouseY ~= self.lastY then + self.line[2] = ("%g,%g"):format(math.min(self.w - 130, math.max(120, mouseX)), self.y + (hover_zone - 4) * bar_height) + self.lastX, self.lastY = mouseX, mouseY + local hoverTime = mp.get_property_number('length', 0) * mouseX / self.w + if hoverTime ~= self.lastTime and (self.hovered or self.animation.isRegistered) then + update = true + self.line[6] = ([[%d:%02d:%02d]]):format(hoverTime / 3600, (hoverTime / 60) % 60, hoverTime % 60) + self.lastTime = hoverTime + end + end + return update + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + local _class_0 = setmetatable({ + __init = function(self, animationQueue) + self.animationQueue = animationQueue + _parent_0.__init(self) + self.line = { + [[{\fnSource Sans Pro Semibold\bord2\fs26\pos(]], + [[-100,0]], + [[)\3c&H262626&\c&HFFFFFF&\an2\&H]], + [[FF]], + [[&}]], + 0 + } + self.lastTime = 0 + self.lastX = -1 + self.lastY = -1 + self.position = -100 + self.animation = Animation(255, 0, 0.25, (function() + local _base_1 = self + local _fn_0 = _base_1.animateAlpha + return function(...) + return _fn_0(_base_1, ...) + end + end)()) + end, + __base = _base_0, + __name = "HoverTime", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + return _parent_0[name] + 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 + HoverTime = _class_0 +end +local aggregator = OSDAggregator() +local animationQueue = AnimationQueue(aggregator) +local progressBar = ProgressBar(animationQueue) +local progressBarBackground = ProgressBarBackground(animationQueue) +local chapters = Chapters(animationQueue) +local timeElapsed = TimeElapsed(animationQueue) +local timeRemaining = TimeRemaining(animationQueue) +local hoverTime = HoverTime(animationQueue) +aggregator:addSubscriber(progressBarBackground) +aggregator:addSubscriber(progressBar) +aggregator:addSubscriber(chapters) +aggregator:addSubscriber(timeElapsed) +aggregator:addSubscriber(timeRemaining) +aggregator:addSubscriber(hoverTime) +local notFrameStepping = true +mp.add_key_binding('.', 'mp_progbar_stepforward', function() + notFrameStepping = false + return mp.commandv('frame_step') +end, { + repeatable = true +}) +mp.add_key_binding(',', 'mp_progbar_stepbackward', function() + notFrameStepping = false + return mp.commandv('frame_back_step') +end, { + repeatable = true +}) +mp.observe_property('pause', 'bool', PauseIndicatorWrapper) +local initDraw +initDraw = function() + mp.unregister_event(initDraw) + local width, height = mp.get_screen_size() + chapters:createMarkers(width, height) +end +local fileLoaded +fileLoaded = function() + return mp.register_event('playback-restart', initDraw) +end +return mp.register_event('file-loaded', fileLoaded) diff --git a/mpv/scripts/autoload.lua b/mpv/scripts/autoload.lua new file mode 100644 index 0000000..ffe6ddb --- /dev/null +++ b/mpv/scripts/autoload.lua @@ -0,0 +1,121 @@ +-- This script automatically loads playlist entries before and after the +-- the currently played file. It does so by scanning the directory a file is +-- located in when starting playback. It sorts the directory entries +-- alphabetically, and adds entries before and after the current file to +-- the internal playlist. (It stops if the it would add an already existing +-- playlist entry at the same position - this makes it "stable".) +-- Add at most 5 * 2 files when starting a file (before + after). +MAXENTRIES = 5 + +function Set (t) + local set = {} + for _, v in pairs(t) do set[v] = true end + return set +end + +EXTENSIONS = Set { + 'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp', + 'mp3', 'wav', 'ogv', 'flac', 'm4a', 'wma', +} + +mputils = require 'mp.utils' + +function add_files_at(index, files) + index = index - 1 + local oldcount = mp.get_property_number("playlist-count", 1) + for i = 1, #files do + mp.commandv("loadfile", files[i], "append") + mp.commandv("playlist_move", oldcount + i - 1, index + i - 1) + end +end + +function get_extension(path) + return string.match(path, "%.([^%.]+)$" ) +end + +table.filter = function(t, iter) + for i = #t, 1, -1 do + if not iter(t[i]) then + table.remove(t, i) + end + end +end + +function find_and_add_entries() + local path = mp.get_property("path", "") + local dir, filename = mputils.split_path(path) + if #dir == 0 then + return + end + local isplaylist = mp.get_property("playlist-count") + if #isplaylist > 1 then + return + end + + local files = mputils.readdir(dir, "files") + if files == nil then + return + end + table.filter(files, function (v, k) + local ext = get_extension(v) + if ext == nil then + return false + end + return EXTENSIONS[string.lower(ext)] + end) + table.sort(files, function (a, b) + return string.lower(a) < string.lower(b) + end) + + if dir == "." then + dir = "" + end + + local pl = mp.get_property_native("playlist", {}) + local pl_current = mp.get_property_number("playlist-pos", 0) + 1 + -- Find the current pl entry (dir+"/"+filename) in the sorted dir list + local current + for i = 1, #files do + if files[i] == filename then + current = i + break + end + end + if current == nil then + return + end + + local append = {[-1] = {}, [1] = {}} + for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1 + for i = 1, MAXENTRIES do + local file = files[current + i * direction] + local pl_e = pl[pl_current + i * direction] + if file == nil or file[1] == "." then + break + end + + local filepath = dir .. file + if pl_e then + -- If there's a playlist entry, and it's the same file, stop. + if pl_e.filename == filepath then + break + end + end + + if direction == -1 then + if pl_current == 1 then -- never add additional entries in the middle + mp.msg.info("Prepending " .. file) + table.insert(append[-1], 1, filepath) + end + else + mp.msg.info("Adding " .. file) + table.insert(append[1], filepath) + end + end + end + + add_files_at(pl_current + 1, append[1]) + add_files_at(pl_current, append[-1]) +end + +mp.register_event("start-file", find_and_add_entries) diff --git a/mpv/scripts/autosub.lua b/mpv/scripts/autosub.lua new file mode 100644 index 0000000..a05206f --- /dev/null +++ b/mpv/scripts/autosub.lua @@ -0,0 +1,24 @@ +-- default keybinding: b +-- add the following to your input.conf to change the default keybinding: +-- keyname script_binding auto_load_subs +local utils = require 'mp.utils' +function load_sub_fn() + subl = "/usr/bin/subliminal" -- use 'which subliminal' to find the path + mp.msg.info("Searching subtitle") + mp.osd_message("Searching subtitle") + t = {} + t.args = {subl, "download", "-s", "-l", "en", mp.get_property("path")} + res = utils.subprocess(t) + if res.status == 0 then + sub_path = string.gsub(mp.get_property("path"), "%.%w+$", ".srt") + mp.osd_message(sub_path) + mp.commandv("sub_add", sub_path) + mp.msg.info("Subtitle download succeeded") + mp.osd_message("Subtitle download succeeded") + else + mp.msg.warn("Subtitle download failed") + mp.osd_message("Subtitle download failed") + end +end + +mp.add_key_binding("b", "auto_load_subs", load_sub_fn) diff --git a/mpv/scripts/stats.lua b/mpv/scripts/stats.lua new file mode 100644 index 0000000..f844d21 --- /dev/null +++ b/mpv/scripts/stats.lua @@ -0,0 +1,263 @@ +-- Display some stats. +-- +-- You can invoke the script with "i" by default or create a different key +-- binding in input.conf using " script_binding stats". +-- +-- The style is configurable through a config file named "lua-settings/stats.conf" +-- located in your mpv directory. +-- +-- Please note: not every property is always available and therefore not always +-- visible. + +local options = require 'mp.options' + +-- Options +local o = { + ass_formatting = true, + duration = 3, + debug = false, + + -- Text style + font = "Source Sans Pro", + font_size = 11, + font_color = "FFFFFF", + border_size = 1.0, + border_color = "262626", + shadow_x_offset = 0.0, + shadow_y_offset = 0.0, + shadow_color = "000000", + alpha = "11", + + -- Custom header for ASS tags to style the text output. + -- Specifying this will ignore the text style values above and just + -- use this string instead. + custom_header = "", + + -- Text formatting + -- With ASS + nl = "\\N", + prop_indent = "\\h\\h\\h\\h\\h", + kv_sep = "\\h\\h", + b1 = "{\\b1}", + b0 = "{\\b0}", + -- Without ASS + no_ass_nl = "\n", + no_ass_prop_indent = "\t", + no_ass_kv_sep = " ", + no_ass_b1 = "\027[1m", + no_ass_b0 = "\027[0m", +} +options.read_options(o) + + +function main() + local stats = { + header = "", + file = "", + video = "", + audio = "" + } + + o.ass_formatting = o.ass_formatting and has_vo_window() + if not o.ass_formatting then + o.nl = o.no_ass_nl + o.prop_indent = o.no_ass_prop_indent + o.kv_sep = o.no_ass_kv_sep + if not has_ansi() then + o.b1 = "" + o.b0 = "" + else + o.b1 = o.no_ass_b1 + o.b0 = o.no_ass_b0 + end + end + + add_header(stats) + add_file(stats) + add_video(stats) + add_audio(stats) + + mp.osd_message(join_stats(stats), o.duration) +end + + +function add_file(s) + local sec = "file" + s[sec] = "" + + append_property(s, sec, "filename", {prefix="File:", nl="", indent=""}) + append_property(s, sec, "metadata/title", {prefix="Title:"}) + append_property(s, sec, "chapter", {prefix="Chapter:"}) + if append_property(s, sec, "cache-used", {prefix="Cache:"}) then + append_property(s, sec, "demuxer-cache-duration", + {prefix="+", suffix=" sec", nl="", indent=o.kv_sep, + prefix_sep="", no_prefix_markup=true}) + end +end + + +function add_video(s) + local sec = "video" + s[sec] = "" + if not has_video() then + return + end + + if append_property(s, sec, "video-codec", {prefix="Video:", nl="", indent=""}) then + append_property(s, sec, "hwdec-active", + {prefix="(hwdec)", nl="", indent=" ", + no_prefix_markup=true, no_value=true}, + {no=true}) + end + append_property(s, sec, "avsync", {prefix="A-V:"}) + if append_property(s, sec, "drop-frame-count", {prefix="Dropped:"}) then + append_property(s, sec, "vo-drop-frame-count", {prefix="VO:", nl=""}) + end + if append_property(s, sec, "fps", {prefix="FPS:", suffix=" (specified)"}) then + append_property(s, sec, "estimated-vf-fps", + {suffix=" (estimated)", nl="", indent=""}) + else + append_property(s, sec, "estimated-vf-fps", + {prefix="FPS:", suffix=" (estimated)"}) + end + if append_property(s, sec, "video-params/w", {prefix="Native Resolution:"}) then + append_property(s, sec, "video-params/h", + {prefix="x", nl="", indent=" ", prefix_sep=" ", no_prefix_markup=true}) + end + append_property(s, sec, "window-scale", {prefix="Window Scale:"}) + append_property(s, sec, "video-params/aspect", {prefix="Aspect Ratio:"}) + append_property(s, sec, "video-params/pixelformat", {prefix="Pixel format:"}) + append_property(s, sec, "video-params/colormatrix", {prefix="Colormatrix:"}) + append_property(s, sec, "video-params/primaries", {prefix="Primaries:"}) + append_property(s, sec, "video-params/colorlevels", {prefix="Levels:"}) + append_property(s, sec, "packet-video-bitrate", {prefix="Bitrate:", suffix=" kbps"}) +end + + +function add_audio(s) + local sec = "audio" + s[sec] = "" + if not has_audio() then + return + end + + append_property(s, sec, "audio-codec", {prefix="Audio:", nl="", indent=""}) + append_property(s, sec, "audio-params/samplerate", {prefix="Sample Rate:", suffix=" Hz"}) + append_property(s, sec, "audio-params/channel-count", {prefix="Channels:"}) + append_property(s, sec, "packet-audio-bitrate", {prefix="Bitrate:", suffix=" kbps"}) +end + + +function add_header(s) + if not o.ass_formatting then + s.header = "" + return + end + if o.custom_header and o.custom_header ~= "" then + s.header = set_ASS(true) .. o.custom_header + else + s.header = string.format("%s{\\fs%d}{\\fn%s}{\\bord%f}{\\3c&H%s&}{\\1c&H%s&}" .. + "{\\alpha&H%s&}{\\xshad%f}{\\yshad%f}{\\4c&H%s&}", + set_ASS(true), o.font_size, o.font, o.border_size, + o.border_color, o.font_color, o.alpha, o.shadow_x_offset, + o.shadow_y_offset, o.shadow_color) + end +end + + +-- Format and append a property. +-- A property whose value is either `nil` or empty (hereafter called "invalid") +-- is skipped and not appended. +-- Returns `false` in case nothing was appended, otherwise `true`. +-- +-- s : Table containing key `sec`. +-- sec : Existing key in table `s`, value treated as a string. +-- property: The property to query and format (based on its OSD representation). +-- attr : Optional table to overwrite certain (formatting) attributes for +-- this property. +-- exclude : Optional table containing keys which are considered invalid values +-- for this property. Specifying this will replace empty string as +-- default invalid value (nil is always invalid). +function append_property(s, sec, prop, attr, excluded) + excluded = excluded or {[""] = true} + local ret = mp.get_property_osd(prop) + if not ret or excluded[ret] then + if o.debug then + print("No value for property: " .. prop) + end + return false + end + + attr.prefix_sep = attr.prefix_sep or o.kv_sep + attr.indent = attr.indent or o.prop_indent + attr.nl = attr.nl or o.nl + attr.suffix = attr.suffix or "" + attr.prefix = attr.prefix or "" + attr.no_prefix_markup = attr.no_prefix_markup or false + attr.prefix = attr.no_prefix_markup and attr.prefix or b(attr.prefix) + ret = attr.no_value and "" or ret + + s[sec] = string.format("%s%s%s%s%s%s%s", s[sec], attr.nl, attr.indent, + attr.prefix, attr.prefix_sep, no_ASS(ret), attr.suffix) + return true +end + + +function no_ASS(t) + return set_ASS(false) .. t .. set_ASS(true) +end + + +function set_ASS(b) + if not o.ass_formatting then + return "" + end + return mp.get_property_osd("osd-ass-cc/" .. (b and "0" or "1")) +end + + +function join_stats(s) + r = s.header .. s.file + + if s.video and s.video ~= "" then + r = r .. o.nl .. o.nl .. s.video + end + if s.audio and s.audio ~= "" then + r = r .. o.nl .. o.nl .. s.audio + end + + return r +end + + +function has_vo_window() + return mp.get_property("vo-configured") == "yes" +end + + +function has_video() + local r = mp.get_property("video") + return r and r ~= "no" and r ~= "" +end + + +function has_audio() + local r = mp.get_property("audio") + return r and r ~= "no" and r ~= "" +end + +function has_ansi() + local is_windows = type(package) == 'table' and type(package.config) == 'string' and package.config:sub(1,1) == '\\' + if is_windows then + return os.getenv("ANSICON") + end + return true +end + +function b(t) + return o.b1 .. t .. o.b0 +end + + + +mp.add_key_binding("i", mp.get_script_name(), main, {repeatable=true}) -- cgit v1.2.3-54-g00ecf