mpv: Move into multimedia module
This commit is contained in:
parent
5a1c779a0d
commit
4c33a6da56
13 changed files with 7 additions and 1 deletions
220
multimedia/.config/mpv/scripts/autoload.lua
Normal file
220
multimedia/.config/mpv/scripts/autoload.lua
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
-- 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 it would add an already existing
|
||||
-- playlist entry at the same position - this makes it "stable".)
|
||||
-- Add at most 5000 * 2 files when starting a file (before + after).
|
||||
|
||||
--[[
|
||||
To configure this script use file autoload.conf in directory script-opts (the "script-opts"
|
||||
directory must be in the mpv configuration directory, typically ~/.config/mpv/).
|
||||
|
||||
Example configuration would be:
|
||||
|
||||
disabled=no
|
||||
images=no
|
||||
videos=yes
|
||||
audio=yes
|
||||
|
||||
--]]
|
||||
|
||||
MAXENTRIES = 5000
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
local options = require 'mp.options'
|
||||
local utils = require 'mp.utils'
|
||||
|
||||
o = {
|
||||
disabled = false,
|
||||
images = true,
|
||||
videos = true,
|
||||
audio = true
|
||||
}
|
||||
options.read_options(o)
|
||||
|
||||
function Set (t)
|
||||
local set = {}
|
||||
for _, v in pairs(t) do set[v] = true end
|
||||
return set
|
||||
end
|
||||
|
||||
function SetUnion (a,b)
|
||||
local res = {}
|
||||
for k in pairs(a) do res[k] = true end
|
||||
for k in pairs(b) do res[k] = true end
|
||||
return res
|
||||
end
|
||||
|
||||
EXTENSIONS_VIDEO = Set {
|
||||
'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp'
|
||||
}
|
||||
|
||||
EXTENSIONS_AUDIO = Set {
|
||||
'mp3', 'wav', 'ogm', 'flac', 'm4a', 'wma', 'ogg', 'opus'
|
||||
}
|
||||
|
||||
EXTENSIONS_IMAGES = Set {
|
||||
'jpg', 'jpeg', 'png', 'tif', 'tiff', 'gif', 'webp', 'svg', 'bmp'
|
||||
}
|
||||
|
||||
EXTENSIONS = Set {}
|
||||
if o.videos then EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_VIDEO) end
|
||||
if o.audio then EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_AUDIO) end
|
||||
if o.images then EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_IMAGES) end
|
||||
|
||||
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)
|
||||
match = string.match(path, "%.([^%.]+)$" )
|
||||
if match == nil then
|
||||
return "nomatch"
|
||||
else
|
||||
return match
|
||||
end
|
||||
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
|
||||
|
||||
-- splitbynum and alnumcomp from alphanum.lua (C) Andre Bogus
|
||||
-- Released under the MIT License
|
||||
-- http://www.davekoelle.com/files/alphanum.lua
|
||||
|
||||
-- split a string into a table of number and string values
|
||||
function splitbynum(s)
|
||||
local result = {}
|
||||
for x, y in (s or ""):gmatch("(%d*)(%D*)") do
|
||||
if x ~= "" then table.insert(result, tonumber(x)) end
|
||||
if y ~= "" then table.insert(result, y) end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function clean_key(k)
|
||||
k = (' '..k..' '):gsub("%s+", " "):sub(2, -2):lower()
|
||||
return splitbynum(k)
|
||||
end
|
||||
|
||||
-- compare two strings
|
||||
function alnumcomp(x, y)
|
||||
local xt, yt = clean_key(x), clean_key(y)
|
||||
for i = 1, math.min(#xt, #yt) do
|
||||
local xe, ye = xt[i], yt[i]
|
||||
if type(xe) == "string" then ye = tostring(ye)
|
||||
elseif type(ye) == "string" then xe = tostring(xe) end
|
||||
if xe ~= ye then return xe < ye end
|
||||
end
|
||||
return #xt < #yt
|
||||
end
|
||||
|
||||
local autoloaded = nil
|
||||
|
||||
function find_and_add_entries()
|
||||
local path = mp.get_property("path", "")
|
||||
local dir, filename = utils.split_path(path)
|
||||
msg.trace(("dir: %s, filename: %s"):format(dir, filename))
|
||||
if o.disabled then
|
||||
msg.verbose("stopping: autoload disabled")
|
||||
return
|
||||
elseif #dir == 0 then
|
||||
msg.verbose("stopping: not a local path")
|
||||
return
|
||||
end
|
||||
|
||||
local pl_count = mp.get_property_number("playlist-count", 1)
|
||||
-- check if this is a manually made playlist
|
||||
if (pl_count > 1 and autoloaded == nil) or
|
||||
(pl_count == 1 and EXTENSIONS[string.lower(get_extension(filename))] == nil) then
|
||||
msg.verbose("stopping: manually made playlist")
|
||||
return
|
||||
else
|
||||
autoloaded = true
|
||||
end
|
||||
|
||||
local pl = mp.get_property_native("playlist", {})
|
||||
local pl_current = mp.get_property_number("playlist-pos-1", 1)
|
||||
msg.trace(("playlist-pos-1: %s, playlist: %s"):format(pl_current,
|
||||
utils.to_string(pl)))
|
||||
|
||||
local files = utils.readdir(dir, "files")
|
||||
if files == nil then
|
||||
msg.verbose("no other files in directory")
|
||||
return
|
||||
end
|
||||
table.filter(files, function (v, k)
|
||||
if string.match(v, "^%.") then
|
||||
return false
|
||||
end
|
||||
local ext = get_extension(v)
|
||||
if ext == nil then
|
||||
return false
|
||||
end
|
||||
return EXTENSIONS[string.lower(ext)]
|
||||
end)
|
||||
table.sort(files, alnumcomp)
|
||||
|
||||
if dir == "." then
|
||||
dir = ""
|
||||
end
|
||||
|
||||
-- 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
|
||||
msg.trace("current file position in files: "..current)
|
||||
|
||||
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.
|
||||
msg.trace(pl_e.filename.." == "..filepath.." ?")
|
||||
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
|
||||
msg.info("Prepending " .. file)
|
||||
table.insert(append[-1], 1, filepath)
|
||||
end
|
||||
else
|
||||
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)
|
||||
25
multimedia/.config/mpv/scripts/battery.lua
Normal file
25
multimedia/.config/mpv/scripts/battery.lua
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
-- If the laptop is on battery, the profile 'lq' will be loaded; otherwise 'hq' is used
|
||||
--
|
||||
local lqprofile = "lowquality"
|
||||
local hqprofile = "highquality"
|
||||
|
||||
local function powerstate()
|
||||
local f = io.open("/sys/class/power_supply/AC/online")
|
||||
if f == nil then return end
|
||||
local t = f:read("*n")
|
||||
f:close()
|
||||
return t
|
||||
end
|
||||
|
||||
local function adjust()
|
||||
local state = powerstate()
|
||||
-- this actually overrides automatically applied profiles
|
||||
-- like 'protocol.http'
|
||||
if state == 0 then
|
||||
mp.msg.info("Running on battery, setting low-quality options.")
|
||||
mp.set_property("profile", lqprofile)
|
||||
else
|
||||
mp.msg.info("Not running on battery, setting high-quality options.")
|
||||
end
|
||||
end
|
||||
mp.add_hook("on_load", 1, adjust)
|
||||
32
multimedia/.config/mpv/scripts/gallery-dl.lua
Normal file
32
multimedia/.config/mpv/scripts/gallery-dl.lua
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
-- gallery-dl_hook.lua
|
||||
--
|
||||
-- load online image galleries as playlists using gallery-dl
|
||||
-- https://github.com/mikf/gallery-dl
|
||||
--
|
||||
-- to use, prepend the gallery url with: gallery-dl://
|
||||
-- e.g.
|
||||
-- `mpv gallery-dl://https://imgur.com/....`
|
||||
|
||||
local utils = require 'mp.utils'
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
local function exec(args)
|
||||
local ret = utils.subprocess({args = args})
|
||||
return ret.status, ret.stdout, ret
|
||||
end
|
||||
|
||||
mp.add_hook("on_load", 15, function()
|
||||
local url = mp.get_property("stream-open-filename", "")
|
||||
if (url:find("gdl://") ~= 1) then
|
||||
msg.debug("not a gdl:// url: " .. url)
|
||||
return
|
||||
end
|
||||
local url = string.gsub(url,"gdl://","")
|
||||
|
||||
local es, urls, result = exec({"gallery-dl", "-g", url})
|
||||
if (es < 0) or (urls == nil) or (urls == "") then
|
||||
msg.error("failed to get album list.")
|
||||
end
|
||||
|
||||
mp.commandv("loadlist", "memory://" .. urls)
|
||||
end)
|
||||
1011
multimedia/.config/mpv/scripts/playlistmanager.lua
Normal file
1011
multimedia/.config/mpv/scripts/playlistmanager.lua
Normal file
File diff suppressed because it is too large
Load diff
94
multimedia/.config/mpv/scripts/sponsorblock_minimal.lua
Normal file
94
multimedia/.config/mpv/scripts/sponsorblock_minimal.lua
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
-- sponsorblock_minimal.lua
|
||||
--
|
||||
-- This script skips sponsored segments of YouTube videos
|
||||
-- using data from https://github.com/ajayyy/SponsorBlock
|
||||
--
|
||||
-- original from https://codeberg.org/jouni/mpv_sponsorblock_minimal
|
||||
-- adapted for local playback skipping and some refactoring by me
|
||||
local options = {
|
||||
API = "https://sponsor.ajay.app/api/skipSegments",
|
||||
|
||||
-- Categories to fetch and skip
|
||||
categories = '"sponsor","intro","outro","interaction","selfpromo"'
|
||||
}
|
||||
|
||||
local function getranges()
|
||||
local args = {
|
||||
"curl", "-s", "-d", "videoID=" .. Youtube_id, "-d",
|
||||
"categories=[" .. options.categories .. "]", "-G", options.API
|
||||
}
|
||||
local sponsors = mp.command_native({
|
||||
name = "subprocess",
|
||||
capture_stdout = true,
|
||||
playback_only = false,
|
||||
args = args
|
||||
})
|
||||
|
||||
if string.match(sponsors.stdout, "%[(.-)%]") then
|
||||
Ranges = {}
|
||||
for i in string.gmatch(string.sub(sponsors.stdout, 2, -2), "%[(.-)%]") do
|
||||
local k, v = string.match(i, "(%d+.?%d*),(%d+.?%d*)")
|
||||
Ranges[k] = v
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local function skip_ads(name, pos)
|
||||
if pos ~= nil then
|
||||
for k, v in pairs(Ranges) do
|
||||
if tonumber(k) <= pos and tonumber(v) > pos then
|
||||
-- this message may sometimes be wrong
|
||||
-- it only seems to be a visual thing though
|
||||
mp.osd_message("[sponsorblock] skipping forward " ..
|
||||
math.floor(
|
||||
tonumber(v) - mp.get_property("time-pos")) ..
|
||||
"s")
|
||||
-- need to do the +0.01 otherwise mpv will start spamming skip sometimes
|
||||
-- example: https://www.youtube.com/watch?v=4ypMJzeNooo
|
||||
mp.set_property("time-pos", tonumber(v) + 0.01)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local function file_loaded()
|
||||
local video_path = mp.get_property("path")
|
||||
local youtube_id1 = string.match(video_path,
|
||||
"https?://youtu%.be/([%w-_]+).*")
|
||||
local youtube_id2 = string.match(video_path,
|
||||
"https?://w?w?w?%.?youtube%.com/v/([%w-_]+).*")
|
||||
local youtube_id3 = string.match(video_path, "/watch.*[?&]v=([%w-_]+).*")
|
||||
local youtube_id4 = string.match(video_path, "/embed/([%w-_]+).*")
|
||||
local localytfile = string.match(video_path,
|
||||
"-([%a%d%-_]+)%.[mw][kpe][v4b][m]?$")
|
||||
Youtube_id = youtube_id1 or youtube_id2 or youtube_id3 or youtube_id4 or
|
||||
localytfile
|
||||
if not Youtube_id or string.len(Youtube_id) < 11 then return end
|
||||
Youtube_id = string.sub(Youtube_id, 1, 11)
|
||||
|
||||
getranges()
|
||||
if Ranges then
|
||||
ON = true
|
||||
mp.add_key_binding("b", "sponsorblock", toggle)
|
||||
mp.observe_property("time-pos", "native", skip_ads)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local function toggle()
|
||||
if ON then
|
||||
mp.unobserve_property(skip_ads)
|
||||
mp.osd_message("[sponsorblock] off")
|
||||
ON = false
|
||||
return
|
||||
end
|
||||
mp.observe_property("time-pos", "native", skip_ads)
|
||||
mp.osd_message("[sponsorblock] on")
|
||||
ON = true
|
||||
return
|
||||
end
|
||||
|
||||
mp.register_event("file-loaded", file_loaded)
|
||||
3655
multimedia/.config/mpv/scripts/uosc.lua
Normal file
3655
multimedia/.config/mpv/scripts/uosc.lua
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue