first commit
This commit is contained in:
190
mpv/scripts/subtitle_manager.lua
Normal file
190
mpv/scripts/subtitle_manager.lua
Normal file
@@ -0,0 +1,190 @@
|
||||
local utils = require 'mp.utils'
|
||||
|
||||
-- 参数设置
|
||||
local subtitlesPerPage = 10
|
||||
local closeAfterLoad = true
|
||||
local rate = 1.5
|
||||
|
||||
-- 全局变量和实用函数
|
||||
local styleOn = mp.get_property("osd-ass-cc/0")
|
||||
local subtitles = {}
|
||||
local currentSlot = 1
|
||||
local currentPage = 1
|
||||
local maxPage = 1
|
||||
local active = false
|
||||
|
||||
-- 控制列表
|
||||
local subtitleControls = {
|
||||
ESC = function() abort("") end,
|
||||
e = function() abort("") end,
|
||||
DOWN = function() jumpSlot(1) end,
|
||||
UP = function() jumpSlot(-1) end,
|
||||
j = function() jumpSlot(1) end,
|
||||
k = function() jumpSlot(-1) end,
|
||||
RIGHT = function() jumpPage(1) end,
|
||||
LEFT = function() jumpPage(-1) end,
|
||||
ENTER = function() loadSubtitle(currentSlot) end,
|
||||
KP_ENTER = function() loadSubtitle(currentSlot) end
|
||||
}
|
||||
|
||||
local subtitleFlags = {
|
||||
DOWN = {repeatable = true},
|
||||
UP = {repeatable = true},
|
||||
RIGHT = {repeatable = true},
|
||||
LEFT = {repeatable = true}
|
||||
}
|
||||
|
||||
-- 激活自定义控件
|
||||
function activateControls(name, controls, flags)
|
||||
for key, func in pairs(controls) do
|
||||
mp.add_forced_key_binding(key, name..key, func, flags[key])
|
||||
end
|
||||
end
|
||||
|
||||
-- 取消激活自定义控件
|
||||
function deactivateControls(name, controls)
|
||||
for key, _ in pairs(controls) do
|
||||
mp.remove_key_binding(name..key)
|
||||
end
|
||||
end
|
||||
|
||||
-- 实用函数
|
||||
function fileExists(path)
|
||||
local f = io.open(path, "r")
|
||||
if f ~= nil then
|
||||
io.close(f)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- 加载字幕列表
|
||||
function listSubtitles()
|
||||
subtitles = {}
|
||||
local tracks = mp.get_property_native("track-list")
|
||||
for _, track in ipairs(tracks) do
|
||||
if track.type == "sub" then
|
||||
table.insert(subtitles, track)
|
||||
end
|
||||
end
|
||||
calcPages()
|
||||
end
|
||||
|
||||
-- 计算当前页和总页数
|
||||
function calcPages()
|
||||
currentPage = math.floor((currentSlot - 1) / subtitlesPerPage) + 1
|
||||
if currentPage == 0 then currentPage = 1 end
|
||||
maxPage = math.floor((#subtitles - 1) / subtitlesPerPage) + 1
|
||||
if maxPage == 0 then maxPage = 1 end
|
||||
end
|
||||
|
||||
-- 获取指定页的字幕数量
|
||||
function getAmountSubtitlesOnPage(page)
|
||||
local n = subtitlesPerPage
|
||||
if page == maxPage then n = #subtitles % subtitlesPerPage end
|
||||
if n == 0 then n = subtitlesPerPage end
|
||||
if #subtitles == 0 then n = 0 end
|
||||
return n
|
||||
end
|
||||
|
||||
-- 获取指定页的第一个字幕索引
|
||||
function getFirstSlotOnPage(page)
|
||||
return (page - 1) * subtitlesPerPage + 1
|
||||
end
|
||||
|
||||
-- 获取指定页的最后一个字幕索引
|
||||
function getLastSlotOnPage(page)
|
||||
local endSlot = getFirstSlotOnPage(page) + getAmountSubtitlesOnPage(page) - 1
|
||||
if endSlot > #subtitles then endSlot = #subtitles end
|
||||
return endSlot
|
||||
end
|
||||
|
||||
-- 跳到指定数量的字幕前或后
|
||||
function jumpSlot(i)
|
||||
currentSlot = currentSlot + i
|
||||
local startSlot = getFirstSlotOnPage(currentPage)
|
||||
local endSlot = getLastSlotOnPage(currentPage)
|
||||
|
||||
if currentSlot < startSlot then currentSlot = endSlot end
|
||||
if currentSlot > endSlot then currentSlot = startSlot end
|
||||
|
||||
displaySubtitles()
|
||||
end
|
||||
|
||||
-- 跳到指定数量的页前或后
|
||||
function jumpPage(i)
|
||||
local oldPos = currentSlot - getFirstSlotOnPage(currentPage) + 1
|
||||
currentPage = currentPage + i
|
||||
if currentPage < 1 then currentPage = maxPage + currentPage end
|
||||
if currentPage > maxPage then currentPage = currentPage - maxPage end
|
||||
|
||||
local subtitlesOnPage = getAmountSubtitlesOnPage(currentPage)
|
||||
if oldPos > subtitlesOnPage then oldPos = subtitlesOnPage end
|
||||
currentSlot = getFirstSlotOnPage(currentPage) + oldPos - 1
|
||||
|
||||
displaySubtitles()
|
||||
end
|
||||
|
||||
-- 显示当前页的字幕
|
||||
function displaySubtitles()
|
||||
-- 确定当前页的第一个和最后一个字幕索引
|
||||
local startSlot = getFirstSlotOnPage(currentPage)
|
||||
local endSlot = getLastSlotOnPage(currentPage)
|
||||
|
||||
-- 准备显示的文本并显示
|
||||
local display = styleOn .. "{\\b1}Subtitles page " .. currentPage .. "/" .. maxPage .. ":{\\b0}"
|
||||
for i = startSlot, endSlot do
|
||||
local sub = subtitles[i]
|
||||
local selection = ""
|
||||
if i == currentSlot then
|
||||
selection = "{\\b1}{\\c&H00FFFF&}>"
|
||||
end
|
||||
display = display .. "\n" .. selection .. i .. ": " .. (sub.title or sub.lang or sub.src) .. "{\\r}"
|
||||
end
|
||||
mp.osd_message(display, rate)
|
||||
end
|
||||
|
||||
-- 加载指定的字幕
|
||||
function loadSubtitle(slot)
|
||||
if slot >= 1 and slot <= #subtitles then
|
||||
local sub = subtitles[slot]
|
||||
mp.set_property_native("sid", sub.id)
|
||||
mp.osd_message(string.format("Loaded subtitle: %s", sub.title or sub.lang or sub.src), 2)
|
||||
if closeAfterLoad then
|
||||
abort(styleOn.."{\\c&H00FF00&}{\\b1}Successfully loaded subtitle:{\\r}\n"..(sub.title or sub.lang or sub.src))
|
||||
end
|
||||
else
|
||||
abort(styleOn.."{\\c&H0000FF&}{\\b1}Can't find the subtitle at slot " .. slot)
|
||||
end
|
||||
end
|
||||
|
||||
-- 定时器
|
||||
local timer = mp.add_periodic_timer(rate * 0.95, displaySubtitles)
|
||||
timer:kill()
|
||||
|
||||
|
||||
-- 终止程序
|
||||
function abort(message)
|
||||
mode = "none"
|
||||
deactivateControls("subtitle", subtitleControls)
|
||||
timer:kill()
|
||||
mp.osd_message(message)
|
||||
active = false
|
||||
end
|
||||
|
||||
-- 处理字幕菜单的状态
|
||||
function handler()
|
||||
if active then
|
||||
abort("")
|
||||
else
|
||||
activateControls("subtitle", subtitleControls, subtitleFlags)
|
||||
listSubtitles()
|
||||
displaySubtitles()
|
||||
timer:resume()
|
||||
active = true
|
||||
end
|
||||
end
|
||||
|
||||
-- 注册脚本消息
|
||||
mp.register_script_message("subtitle-menu", handler)
|
||||
Reference in New Issue
Block a user