mpv-iptv/iptv.lua

439 lines
9.0 KiB
Lua
Raw Normal View History

2020-01-11 18:40:33 +01:00
--redefine keybindings here if needed; multiple bindings are possible
local keybinds = {
activate = {'\\', 'MOUSE_BTN2'},
plsup = {'UP', 'MOUSE_BTN3'},
plsdown = {'DOWN', 'MOUSE_BTN4'},
plsenter = {'ENTER', 'MOUSE_BTN0'}
}
--hide playlist after specified number of seconds
2017-06-04 15:55:23 +02:00
local osd_time=10
2020-01-11 18:40:33 +01:00
--show only specified number of playlist entries
2017-06-04 15:55:23 +02:00
local window=7
local timer
-- pls — список элементов плейлиста
local pls
-- plsfiltered — список индексов выбранных фильтром элементов плейлиста
local plsfiltered
--local plscount
local plspos
local wndstart
local wndend
local cursor
local pattern=""
local is_active
local is_playlist_loaded
-- UTF-8 lower/upper conversion
local utf8_lc_uc = {
["a"] = "A",
["b"] = "B",
["c"] = "C",
["d"] = "D",
["e"] = "E",
["f"] = "F",
["g"] = "G",
["h"] = "H",
["i"] = "I",
["j"] = "J",
["k"] = "K",
["l"] = "L",
["m"] = "M",
["n"] = "N",
["o"] = "O",
["p"] = "P",
["q"] = "Q",
["r"] = "R",
["s"] = "S",
["t"] = "T",
["u"] = "U",
["v"] = "V",
["w"] = "W",
["x"] = "X",
["y"] = "Y",
["z"] = "Z",
["а"] = "А",
["б"] = "Б",
["в"] = "В",
["г"] = "Г",
["д"] = "Д",
["е"] = "Е",
["ж"] = "Ж",
["з"] = "З",
["и"] = "И",
["й"] = "Й",
["к"] = "К",
["л"] = "Л",
["м"] = "М",
["н"] = "Н",
["о"] = "О",
["п"] = "П",
["р"] = "Р",
["с"] = "С",
["т"] = "Т",
["у"] = "У",
["ф"] = "Ф",
["х"] = "Х",
["ц"] = "Ц",
["ч"] = "Ч",
["ш"] = "Ш",
["щ"] = "Щ",
["ъ"] = "Ъ",
["ы"] = "Ы",
["ь"] = "Ь",
["э"] = "Э",
["ю"] = "Ю",
["я"] = "Я",
["ё"] = "Ё"
}
local utf8_uc_lc = {
["A"] = "a",
["B"] = "b",
["C"] = "c",
["D"] = "d",
["E"] = "e",
["F"] = "f",
["G"] = "g",
["H"] = "h",
["I"] = "i",
["J"] = "j",
["K"] = "k",
["L"] = "l",
["M"] = "m",
["N"] = "n",
["O"] = "o",
["P"] = "p",
["Q"] = "q",
["R"] = "r",
["S"] = "s",
["T"] = "t",
["U"] = "u",
["V"] = "v",
["W"] = "w",
["X"] = "x",
["Y"] = "y",
["Z"] = "z",
["А"] = "а",
["Б"] = "б",
["В"] = "в",
["Г"] = "г",
["Д"] = "д",
["Е"] = "е",
["Ж"] = "ж",
["З"] = "з",
["И"] = "и",
["Й"] = "й",
["К"] = "к",
["Л"] = "л",
["М"] = "м",
["Н"] = "н",
["О"] = "о",
["П"] = "п",
["Р"] = "р",
["С"] = "с",
["Т"] = "т",
["У"] = "у",
["Ф"] = "ф",
["Х"] = "х",
["Ц"] = "ц",
["Ч"] = "ч",
["Ш"] = "ш",
["Щ"] = "щ",
["Ъ"] = "ъ",
["Ы"] = "ы",
["Ь"] = "ь",
["Э"] = "э",
["Ю"] = "ю",
["Я"] = "я",
["Ё"] = "ё"
}
--utf8 char pattern
local utf8_char="[\1-\127\192-\223][\128-\191]*"
local cyr_chars={'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я'}
-- символы, которые возможно вводить для поиска
local chars={}
for i=string.byte('a'),string.byte('z') do
table.insert(chars,i)
end
for i=string.byte('A'),string.byte('Z') do
table.insert(chars,i)
end
for i=string.byte('0'),string.byte('9') do
table.insert(chars,i)
end
for _,v in ipairs({',','^','$','(',')','%','.','[',']','*','+','-','?','`',"'",";"}) do
table.insert(chars,string.byte(v))
end
2020-01-11 18:40:33 +01:00
local keybinder = {
remove = function(action)
for i,_ in ipairs(keybinds[action]) do
mp.remove_key_binding(action..tostring(i))
end
end,
add = function(action, func, repeatable)
for i,key in ipairs(keybinds[action]) do
assert(type(func)=="function", "not a function")
if repeatable then
mp.add_forced_key_binding(key, action..tostring(i), func, "repeatable")
else
mp.add_forced_key_binding(key, action..tostring(i), func)
end
end
end
}
2017-06-04 15:55:23 +02:00
function add_bindings()
2020-01-11 18:40:33 +01:00
keybinder.add("plsup", up, true)
keybinder.add("plsdown", down, true)
2017-06-04 15:55:23 +02:00
for i,v in ipairs(chars) do
c=string.char(v)
mp.add_forced_key_binding(c, 'search'..v, typing(c),"repeatable")
2017-06-04 15:55:23 +02:00
end
mp.add_forced_key_binding('SPACE', 'search32', typing(' '),"repeatable")
2017-06-04 15:55:23 +02:00
--[[ mp.add_key_binding('а', 'search1000', typing('а'),"repeatable")
mp.add_key_binding('с', 'search1001', typing('с'),"repeatable")]]
mp.add_forced_key_binding('BS', 'searchbs', backspace,"repeatable")
2020-01-11 18:40:33 +01:00
keybinder.add("plsenter", play)
2017-06-04 15:55:23 +02:00
for i,v in ipairs(cyr_chars) do
mp.add_forced_key_binding(v, 'search'..i+1000, typing(v),"repeatable")
2017-06-04 15:55:23 +02:00
end
end
function remove_bindings()
2020-01-11 18:40:33 +01:00
keybinder.remove('plsup')
keybinder.remove('plsdown')
keybinder.remove('plsenter')
for i,v in ipairs(chars) do
c=string.char(v)
mp.remove_key_binding('search'..v)
end
mp.remove_key_binding('search32')
mp.remove_key_binding('searchbs')
for i,v in ipairs(cyr_chars) do
mp.remove_key_binding('search'..i+1000)
end
2017-06-04 15:55:23 +02:00
end
function activate()
local i
local c
if is_active then
shutdown()
return
else
is_active=true
showplaylist()
add_bindings()
if not timer then
timer=mp.add_periodic_timer(osd_time, shutdown)
timer.oneshot=true
else
resumetimer()
end
end
end
function tablekeys(t)
local result={}
for i,v in ipairs(t) do
table.insert(result,i)
end
return result
end
function mylower(s)
local res,n = string.gsub(s,utf8_char,function (c)
return utf8_uc_lc[c]
end)
return res
end
function myupper(s)
local res,n = string.gsub(s,utf8_char,function (c)
return utf8_lc_uc[c]
end)
return res
end
function prepat(s)
--prepare nocase and magic chars
s = string.gsub(s, "[%^%$%(%)%%%.%[%]%*%+%-%?]",function (c)
return '%'..c
end)
--[[ s = string.gsub(s, utf8_char, function (c)
return string.format("[%s%s]", utf8_uc_lc[c] or c, utf8_lc_uc[c] or c)
end)]]
return s
end
function resumetimer()
timer:kill()
timer:resume()
end
function typing(char)
return function()
local c=string.lower(char)
2019-10-12 09:50:37 +02:00
pattern = pattern..c
2017-06-04 15:55:23 +02:00
filterpls()
showplaylist()
resumetimer()
end
end
function backspace()
if string.len(pattern)>0 then
-- pattern = string.sub(pattern,1,-2)
-- for unicode
pattern = string.match(pattern,"(.*)"..utf8_char.."$")
filterpls()
showplaylist()
resumetimer()
end
end
function filterpls()
plsfiltered={}
for i,v in ipairs(pls) do
if string.match(mylower(v.title),'.*'..prepat(pattern)..'.*') then
table.insert(plsfiltered,i)
end
end
wndstart=1
cursor=0
end
function formatentry(v)
local t
t=v.title or ""
if v.current then
t = "*"..t
end
return t
end
function play()
-- mp.commandv("playlist-move", wndstart+cursor, 1)
-- mp.commandv("playlist-clear")
-- mp.commandv("playlist-next")
mp.commandv("loadfile",pls[plsfiltered[wndstart+cursor]].filename)
if plspos then
pls[plspos].current=false
end
plspos=plsfiltered[wndstart+cursor]
pls[plspos].current=true
showplaylist()
resumetimer()
end
function showplaylist()
local i
local newpos
local msg
--media-title
--playlist t[2].title
--[[ if not pls then
pls=mp.get_property_native("playlist")
pattern=""
plsfiltered=tablekeys(pls)
end]]
if not plsfiltered then
return
end
if not plspos then
plspos=mp.get_property_native("playlist-pos-1")
--plscount=mp.get_property_native("playlist-count")
end
if not wndstart or not cursor then
wndstart=1
cursor=0
end
msg=""
i = wndstart
while plsfiltered[i] and i<=wndstart+window-1 do
if i==wndstart+cursor then
msg = msg..">"
end
msg = msg..formatentry(pls[plsfiltered[i]]).."\n"
i = i+1
end
if wndstart>1 then
msg = "...\n"..msg
else
msg = " \n"..msg
end
if wndstart+window-1<#plsfiltered then
msg = msg.."..."
end
2019-10-12 09:50:37 +02:00
msg="/"..pattern.."\n"..msg
2017-06-04 15:55:23 +02:00
mp.osd_message(msg, osd_time)
end
function shutdown()
local c
remove_bindings()
is_active=false
mp.osd_message("", 1)
end
function down()
if cursor >= #plsfiltered-1 then return end
if cursor<window-1 then
cursor=cursor+1
showplaylist()
else
if wndstart<#plsfiltered-window+1 then
wndstart=wndstart+1
end
showplaylist()
end
resumetimer()
end
function up()
if cursor>0 then
cursor=cursor-1
showplaylist()
else
if wndstart>1 then
wndstart=wndstart-1
showplaylist()
end
end
resumetimer()
end
function on_start_file()
if is_playlist_loaded then
if not pls then
pls=mp.get_property_native("playlist")
pattern=""
plsfiltered=tablekeys(pls)
end
mp.commandv("stop")
mp.unregister_event(on_start_file)
activate()
else
is_playlist_loaded = true
end
end
if mp.get_opt("iptv") then
mp.set_property_bool("idle", true)
mp.set_property_bool("force-window", true)
mp.register_event("start-file", on_start_file)
2020-01-11 18:40:33 +01:00
keybinder.add("activate", activate)
2017-06-04 15:55:23 +02:00
end