1337 lines
47 KiB
Lua
1337 lines
47 KiB
Lua
local msg = require('mp.msg')
|
||
local utils = require("mp.utils")
|
||
local unpack = unpack or table.unpack
|
||
|
||
input_loaded, input = pcall(require, "mp.input")
|
||
uosc_available = false
|
||
latest_menu_anime = {}
|
||
|
||
-- 打开番剧数据匹配菜单
|
||
function get_animes(query)
|
||
local encoded_query = url_encode(query)
|
||
local url = options.api_server .. "/api/v2/search/anime"
|
||
local params = "keyword=" .. encoded_query
|
||
local full_url = url .. "?" .. params
|
||
local items = {}
|
||
|
||
local message = "加载数据中..."
|
||
local menu_type = "menu_anime"
|
||
local menu_title = "在此处输入番剧名称"
|
||
local footnote = "使用enter或ctrl+enter进行搜索"
|
||
local menu_cmd = { "script-message-to", mp.get_script_name(), "search-anime-event" }
|
||
if uosc_available then
|
||
update_menu_uosc(menu_type, menu_title, message, footnote, menu_cmd, query)
|
||
else
|
||
show_message(message, 30)
|
||
end
|
||
msg.verbose("尝试获取番剧数据:" .. full_url)
|
||
|
||
local args = make_danmaku_request_args("GET", full_url)
|
||
|
||
if args == nil then
|
||
return
|
||
end
|
||
|
||
local res = mp.command_native({ name = 'subprocess', capture_stdout = true, capture_stderr = true, args = args })
|
||
|
||
if not res.status or res.status ~= 0 then
|
||
local message = "获取数据失败"
|
||
if uosc_available then
|
||
update_menu_uosc(menu_type, menu_title, message, footnote, menu_cmd, query)
|
||
else
|
||
show_message(message, 3)
|
||
end
|
||
msg.error("HTTP 请求失败:" .. res.stderr)
|
||
end
|
||
|
||
local response = utils.parse_json(res.stdout)
|
||
|
||
if not response or not response.animes then
|
||
local message = "无结果"
|
||
if uosc_available then
|
||
update_menu_uosc(menu_type, menu_title, message, footnote, menu_cmd, query)
|
||
else
|
||
show_message(message, 3)
|
||
end
|
||
msg.info("无结果")
|
||
return
|
||
end
|
||
|
||
for _, anime in ipairs(response.animes) do
|
||
table.insert(items, {
|
||
title = anime.animeTitle,
|
||
hint = anime.typeDescription,
|
||
value = {
|
||
"script-message-to",
|
||
mp.get_script_name(),
|
||
"search-episodes-event",
|
||
anime.animeTitle, anime.bangumiId,
|
||
},
|
||
})
|
||
end
|
||
|
||
if uosc_available then
|
||
latest_menu_anime = update_menu_uosc(menu_type, menu_title, items, footnote, menu_cmd, query)
|
||
elseif input_loaded then
|
||
show_message("", 0)
|
||
mp.add_timeout(0.1, function()
|
||
latest_menu_anime = utils.format_json(items)
|
||
open_menu_select(items)
|
||
end)
|
||
end
|
||
end
|
||
|
||
function get_episodes(animeTitle, bangumiId)
|
||
local url = options.api_server .. "/api/v2/bangumi/" .. bangumiId
|
||
local items = {}
|
||
|
||
local message = "加载数据中..."
|
||
local menu_type = "menu_episodes"
|
||
local menu_title = "剧集信息"
|
||
local footnote = "使用 / 打开筛选"
|
||
|
||
if uosc_available then
|
||
update_menu_uosc(menu_type, menu_title, message, footnote)
|
||
else
|
||
show_message(message, 30)
|
||
end
|
||
|
||
local args = make_danmaku_request_args("GET", url)
|
||
|
||
if args == nil then
|
||
return
|
||
end
|
||
|
||
local res = mp.command_native({ name = 'subprocess', capture_stdout = true, capture_stderr = true, args = args })
|
||
|
||
if not res.status or res.status ~= 0 then
|
||
local message = "获取数据失败"
|
||
if uosc_available then
|
||
update_menu_uosc(menu_type, menu_title, message, footnote)
|
||
else
|
||
show_message(message, 3)
|
||
end
|
||
msg.error("HTTP 请求失败:" .. res.stderr)
|
||
end
|
||
|
||
local response = utils.parse_json(res.stdout)
|
||
|
||
if not response or not response.bangumi or not response.bangumi.episodes then
|
||
local message = "无结果"
|
||
if uosc_available then
|
||
update_menu_uosc(menu_type, menu_title, message, footnote)
|
||
else
|
||
show_message(message, 3)
|
||
end
|
||
msg.info("无结果")
|
||
return
|
||
end
|
||
|
||
table.insert(items, {
|
||
title = "← 返回搜索结果",
|
||
value = { "script-message-to", mp.get_script_name(), "open-latest-menu-anime", latest_menu_anime },
|
||
keep_open = false,
|
||
selectable = true,
|
||
})
|
||
|
||
for _, episode in ipairs(response.bangumi.episodes) do
|
||
table.insert(items, {
|
||
title = episode.episodeTitle,
|
||
hint = episode.episodeNumber,
|
||
value = { "script-message-to", mp.get_script_name(), "load-danmaku",
|
||
animeTitle, episode.episodeTitle, episode.episodeId },
|
||
keep_open = false,
|
||
selectable = true,
|
||
})
|
||
end
|
||
|
||
if uosc_available then
|
||
footnote = mp.get_property("filename")
|
||
update_menu_uosc(menu_type, menu_title, items, footnote)
|
||
elseif input_loaded then
|
||
mp.add_timeout(0.1, function()
|
||
open_menu_select(items)
|
||
end)
|
||
end
|
||
end
|
||
|
||
function update_menu_uosc(menu_type, menu_title, menu_item, menu_footnote, menu_cmd, query)
|
||
local items = {}
|
||
if type(menu_item) == "string" then
|
||
table.insert(items, {
|
||
title = menu_item,
|
||
value = "",
|
||
italic = true,
|
||
keep_open = true,
|
||
selectable = false,
|
||
align = "center",
|
||
icon = "spinner",
|
||
})
|
||
else
|
||
items = menu_item
|
||
end
|
||
|
||
local menu_props = {
|
||
type = menu_type,
|
||
title = menu_title,
|
||
search_style = menu_cmd and "palette" or "on_demand",
|
||
search_debounce = menu_cmd and "submit" or 0,
|
||
on_search = menu_cmd,
|
||
footnote = menu_footnote,
|
||
search_suggestion = query,
|
||
items = items,
|
||
}
|
||
local json_props = utils.format_json(menu_props)
|
||
mp.commandv("script-message-to", "uosc", "open-menu", json_props)
|
||
|
||
return json_props
|
||
end
|
||
|
||
function open_menu_select(menu_items, is_time)
|
||
local item_titles, item_values = {}, {}
|
||
for i, v in ipairs(menu_items) do
|
||
item_titles[i] = is_time and "[" .. v.hint .. "] " .. v.title or
|
||
(v.hint and v.title .. " (" .. v.hint .. ")" or v.title)
|
||
item_values[i] = v.value
|
||
end
|
||
mp.commandv('script-message-to', 'console', 'disable')
|
||
input.select({
|
||
prompt = is_time and '筛选:' or '选择:',
|
||
items = item_titles,
|
||
submit = function(id)
|
||
input.terminate()
|
||
local v = item_values[id]
|
||
if type(v) == 'table' then
|
||
mp.commandv(unpack(v))
|
||
elseif type(v) == 'string' then
|
||
mp.command(v)
|
||
end
|
||
end,
|
||
})
|
||
end
|
||
|
||
-- 打开弹幕输入搜索菜单
|
||
function open_input_menu_get()
|
||
mp.commandv('script-message-to', 'console', 'disable')
|
||
local title = parse_title()
|
||
input.get({
|
||
prompt = '番剧名称:',
|
||
default_text = title,
|
||
cursor_position = title and #title + 1,
|
||
submit = function(text)
|
||
input.terminate()
|
||
mp.commandv("script-message-to", mp.get_script_name(), "search-anime-event", text)
|
||
end
|
||
})
|
||
end
|
||
|
||
function open_input_menu_uosc()
|
||
local items = {}
|
||
|
||
if DANMAKU.anime and DANMAKU.episode then
|
||
local episode = DANMAKU.episode:gsub("%s.-$","")
|
||
episode = episode:match("^(第.*[话回集]+)%s*") or episode
|
||
items[#items + 1] = {
|
||
title = string.format("已关联弹幕:%s-%s", DANMAKU.anime, episode),
|
||
bold = true,
|
||
italic = true,
|
||
keep_open = true,
|
||
selectable = false,
|
||
}
|
||
end
|
||
|
||
items[#items + 1] = {
|
||
hint = " 追加|ds或|dy或|dm可搜索电视剧|电影|国漫",
|
||
keep_open = true,
|
||
selectable = false,
|
||
}
|
||
|
||
local menu_props = {
|
||
type = "menu_danmaku",
|
||
title = "在此处输入番剧名称",
|
||
search_style = "palette",
|
||
search_debounce = "submit",
|
||
search_suggestion = parse_title(),
|
||
on_search = { "script-message-to", mp.get_script_name(), "search-anime-event" },
|
||
footnote = "使用enter或ctrl+enter进行搜索",
|
||
items = items
|
||
}
|
||
local json_props = utils.format_json(menu_props)
|
||
mp.commandv("script-message-to", "uosc", "open-menu", json_props)
|
||
end
|
||
|
||
function open_input_menu()
|
||
if uosc_available then
|
||
open_input_menu_uosc()
|
||
elseif input_loaded then
|
||
open_input_menu_get()
|
||
end
|
||
end
|
||
|
||
-- 打开弹幕源添加管理菜单
|
||
function open_add_menu_get()
|
||
local menu_log, deal_value = {}, {}
|
||
|
||
-- 重建菜单内容函数
|
||
local function rebuild_menu_log(select_num)
|
||
deal_value = {}
|
||
menu_log = {
|
||
{ text = "【既有弹幕源】", style = "{\\c&H00CCFF&\\b1}" },
|
||
{ text = "----------------------------", style = "{\\c&H888888&}" }
|
||
}
|
||
|
||
local serial = 0
|
||
for url, source in pairs(DANMAKU.sources) do
|
||
if source.data then
|
||
serial = serial + 1
|
||
local action, text
|
||
|
||
if source.from == "api_server" then
|
||
action = source.blocked and "unblock" or "block"
|
||
text = string.format(" [%02d] %s [来源:弹幕服务器%s] ", serial, url,
|
||
source.blocked and "(已屏蔽)" or "(未屏蔽)")
|
||
else
|
||
action = "delete"
|
||
text = string.format(" [%02d] %s [来源:用户添加] ", serial, url)
|
||
end
|
||
|
||
local style = (tonumber(select_num) == serial) and
|
||
"{\\c&HFFDE7F&\\b1}" or (action == "unblock" and "{\\c&H4C4CC3&\\b0}" or "{\\c&HCCCCCC&\\b0}")
|
||
|
||
deal_value[serial] = {value = url, action = action}
|
||
table.insert(menu_log, {text = text, style = style})
|
||
end
|
||
end
|
||
|
||
if serial == 0 then
|
||
table.insert(menu_log, { text = " 无", style = "" })
|
||
end
|
||
end
|
||
|
||
-- 显示菜单
|
||
local function show_menu(extra_lines, select_num)
|
||
rebuild_menu_log(select_num)
|
||
|
||
local display = {}
|
||
for _, item in ipairs(menu_log) do table.insert(display, item) end
|
||
table.insert(display, { text = "----------------------------", style = "{\\c&H888888&}" })
|
||
|
||
if extra_lines then
|
||
if #extra_lines < 2 then table.insert(display, { text = "\n", style = "" }) end
|
||
for _, line in ipairs(extra_lines) do table.insert(display, line) end
|
||
else
|
||
table.insert(display, { text = "\n", style = "" })
|
||
table.insert(display, {
|
||
text = "提示: 输入【选项数字】可屏蔽或删除既有弹幕源",
|
||
style = "{\\c&H999999&}"
|
||
})
|
||
end
|
||
|
||
input.set_log(display)
|
||
end
|
||
|
||
-- 获取操作提示
|
||
local function get_hint(action)
|
||
local hints = {
|
||
block = "按回车执行,屏蔽该弹幕源",
|
||
unblock = "按回车执行,解除该弹幕源的屏蔽",
|
||
delete = "按回车执行,删除该弹幕源"
|
||
}
|
||
return hints[action] or "按回车执行,获取输入源地址url的弹幕"
|
||
end
|
||
|
||
input.get({
|
||
keep_open = true,
|
||
prompt = "请在此输入源地址url: ",
|
||
opened = function() show_menu() end,
|
||
edited = function(text)
|
||
text = text:gsub("^%s*(.-)%s*$", "%1")
|
||
|
||
if text == "" then
|
||
show_menu()
|
||
return
|
||
end
|
||
|
||
local num = tonumber(text)
|
||
local event = num and deal_value[num]
|
||
local hint = get_hint(event and event.action)
|
||
|
||
show_menu({
|
||
{ text = string.format("已输入: %s", text), style = "{\\c&HCCCCCC&}" },
|
||
{ text = hint, style = "{\\c&H999999&}" }
|
||
}, text)
|
||
end,
|
||
submit = function(text)
|
||
text = text:gsub("^%s*(.-)%s*$", "%1")
|
||
if text == "" then return end
|
||
|
||
local num = tonumber(text)
|
||
local event = num and deal_value[num]
|
||
|
||
if event then
|
||
local args = string.format('{"type":"activate","value":"%s","action":"%s"}',
|
||
string.gsub(event.value, '\\', '\\\\'), event.action)
|
||
mp.commandv("script-message-to", mp.get_script_name(), "setup-danmaku-source", args)
|
||
else
|
||
input.terminate()
|
||
mp.commandv("script-message-to", mp.get_script_name(), "add-source-event", text)
|
||
end
|
||
|
||
mp.add_timeout(0.1, show_menu)
|
||
end
|
||
})
|
||
end
|
||
|
||
function open_add_menu_uosc()
|
||
local sources = {}
|
||
for url, source in pairs(DANMAKU.sources) do
|
||
if source.data then
|
||
local item = {title = url, value = url, keep_open = true,}
|
||
if source.from == "api_server" then
|
||
if source.blocked then
|
||
item.hint = "来源:弹幕服务器(已屏蔽)"
|
||
item.actions = {{icon = "check", name = "unblock", label = "解除屏蔽"},}
|
||
else
|
||
item.hint = "来源:弹幕服务器(未屏蔽)"
|
||
item.actions = {{icon = "not_interested", name = "block", label = "屏蔽"},}
|
||
end
|
||
else
|
||
item.hint = "来源:用户添加"
|
||
item.actions = {{icon = "delete", name = "delete", label = "删除"},}
|
||
end
|
||
table.insert(sources, item)
|
||
end
|
||
end
|
||
local menu_props = {
|
||
type = "menu_source",
|
||
title = "在此输入源地址url",
|
||
search_style = "palette",
|
||
search_debounce = "submit",
|
||
on_search = { "script-message-to", mp.get_script_name(), "add-source-event" },
|
||
footnote = "使用enter或ctrl+enter进行添加",
|
||
items = sources,
|
||
item_actions_place = "outside",
|
||
callback = {mp.get_script_name(), 'setup-danmaku-source'},
|
||
}
|
||
local json_props = utils.format_json(menu_props)
|
||
mp.commandv("script-message-to", "uosc", "open-menu", json_props)
|
||
end
|
||
|
||
function open_add_menu()
|
||
if uosc_available then
|
||
open_add_menu_uosc()
|
||
elseif input_loaded then
|
||
open_add_menu_get()
|
||
end
|
||
end
|
||
|
||
-- 打开弹幕内容菜单
|
||
function open_content_menu(pos)
|
||
local items = {}
|
||
local time_pos = pos or mp.get_property_native("time-pos")
|
||
local duration = mp.get_property_number("duration", 0)
|
||
|
||
if COMMENTS ~= nil then
|
||
for _, event in ipairs(COMMENTS) do
|
||
local text = event.clean_text:gsub("^m%s[mbl%s%-%d%.]+$", ""):gsub("^%s*(.-)%s*$", "%1")
|
||
local delay = event.delay
|
||
local start_time = event.start_time
|
||
local end_time = event.end_time
|
||
if text and text ~= "" and start_time >= 0 and start_time <= duration then
|
||
local delay_label_suffix = nil
|
||
local delay_num = delay and tonumber(delay)
|
||
if delay_num and math.abs(delay_num) > 0 then
|
||
delay_label_suffix = string.format("已存在延迟: %+0.1fs", delay_num)
|
||
end
|
||
|
||
local adjust_label = '调整弹幕延迟'
|
||
if delay_label_suffix then
|
||
adjust_label = adjust_label .. '(' .. delay_label_suffix .. ')'
|
||
end
|
||
|
||
table.insert(items, {
|
||
title = abbr_str(text, 60),
|
||
hint = seconds_to_time(start_time) .. " (" .. utf8_sub(remove_query(event.source), 1, 70) .. ")",
|
||
actions = {
|
||
{
|
||
name = 'block_source',
|
||
icon = 'block',
|
||
label = '屏蔽对应弹幕源'
|
||
},
|
||
{
|
||
name = 'adjust_delay',
|
||
icon = 'more_time',
|
||
label = adjust_label,
|
||
},
|
||
},
|
||
value = { "seek", start_time, "absolute" },
|
||
active = time_pos >= start_time and time_pos <= end_time,
|
||
})
|
||
end
|
||
end
|
||
end
|
||
|
||
local menu_props = {
|
||
type = "menu_content",
|
||
title = "弹幕内容",
|
||
footnote = "使用 / 打开搜索",
|
||
items = items,
|
||
item_actions_place = "outside",
|
||
callback = {mp.get_script_name(), 'handle-danmaku-content-action'},
|
||
}
|
||
local json_props = utils.format_json(menu_props)
|
||
|
||
if uosc_available then
|
||
mp.commandv("script-message-to", "uosc", "open-menu", json_props)
|
||
elseif input_loaded then
|
||
open_menu_select(items, true)
|
||
end
|
||
end
|
||
|
||
local menu_items_config = {
|
||
bold = { title = "粗体", hint = options.bold, original = options.bold,
|
||
footnote = "true / false", },
|
||
fontsize = { title = "大小", hint = options.fontsize, original = options.fontsize,
|
||
scope = { min = 0, max = math.huge }, footnote = "请输入整数(>=0)", },
|
||
outline = { title = "描边", hint = options.outline, original = options.outline,
|
||
scope = { min = 0.0, max = 4.0 }, footnote = "输入范围:(0.0-4.0)" },
|
||
shadow = { title = "阴影", hint = options.shadow, original = options.shadow,
|
||
scope = { min = 0, max = math.huge }, footnote = "请输入整数(>=0)", },
|
||
scrolltime = { title = "速度", hint = options.scrolltime, original = options.scrolltime,
|
||
scope = { min = 1, max = math.huge }, footnote = "请输入整数(>=1)", },
|
||
opacity = { title = "透明度", hint = options.opacity, original = options.opacity,
|
||
scope = { min = 0, max = 1 }, footnote = "输入范围:0(完全透明)到1(不透明)", },
|
||
displayarea = { title = "弹幕显示范围", hint = options.displayarea, original = options.displayarea,
|
||
scope = { min = 0.0, max = 1.0 }, footnote = "显示范围(0.0-1.0)", },
|
||
}
|
||
-- 创建一个包含键顺序的表,这是样式菜单的排布顺序
|
||
local ordered_keys = {"bold", "fontsize", "outline", "shadow", "scrolltime", "opacity", "displayarea"}
|
||
|
||
-- 设置弹幕样式菜单
|
||
function open_style_menu_get(query, indicator)
|
||
mp.commandv('script-message-to', 'console', 'disable')
|
||
local menu_log = {}
|
||
|
||
local select_num = 0
|
||
local select_query = nil
|
||
if query then
|
||
if tonumber(query) ~= nil then
|
||
select_num = tonumber(query)
|
||
else
|
||
for i, v in ipairs(ordered_keys) do
|
||
if v == query then
|
||
select_num = i
|
||
end
|
||
end
|
||
end
|
||
select_query = ordered_keys[select_num]
|
||
end
|
||
|
||
local function build_menu(source)
|
||
menu_log = {
|
||
{ text = "【弹幕样式菜单】", style = "{\\c&H00CCFF&\\b1}" },
|
||
{ text = ("-"):rep(33), style = "{\\c&H888888&}" }
|
||
}
|
||
|
||
local serial = 0
|
||
for _, key in ipairs(ordered_keys) do
|
||
serial = serial + 1
|
||
local config = menu_items_config[key]
|
||
local text = string.format(" [%02d] %s [目前:%s] ", serial, config.title, config.hint)
|
||
text = config.hint ~= config.original and text .. "⟳" or text
|
||
local style = serial == select_num and "{\\c&HFFDE7F&}" or "{\\c&HCCCCCC&}"
|
||
local item_config = { text = text, style = style }
|
||
table.insert(menu_log, item_config)
|
||
end
|
||
|
||
table.insert(menu_log, { text = ("-"):rep(33), style = "{\\c&H888888&}" })
|
||
if select_num == 0 then
|
||
table.insert(menu_log, {
|
||
text = "注: 样式更改仅在本次播放生效",
|
||
style = "{\\c&HFFDE7F&}"
|
||
})
|
||
table.insert(menu_log, {
|
||
text = "提示: 输入【w】可上移选项,【s】可下移选项",
|
||
style = "{\\c&H999999&}"
|
||
})
|
||
else
|
||
local input_text = source and source or ""
|
||
local config = menu_items_config[select_query]
|
||
local suffix = ""
|
||
if config and config.hint ~= config.original then
|
||
suffix = "(输入\\r恢复默认配置)"
|
||
end
|
||
input_text = string.format("已输入%s: %s", suffix, input_text)
|
||
|
||
local scope = config and config.footnote or ""
|
||
local hint_text = select_query == "bold" and "提示: 输入【y】切换状态" or "提示: " .. scope
|
||
local hint_style = "{\\c&H999999&}"
|
||
if source and source:lower() == "\\r" then
|
||
hint_text = string.format("提示: 回车将恢复默认配置 < %s >", config.original)
|
||
end
|
||
if indicator == "refresh" or indicator == "updata" then
|
||
indicator = ""
|
||
hint_text = "提示: 样式更改成功"
|
||
hint_style = "{\\c&HFFDE7F&}"
|
||
mp.add_timeout(1.5, build_menu)
|
||
elseif indicator == "error" then
|
||
indicator = ""
|
||
hint_text = "提示: 输入非数字字符或范围出错"
|
||
hint_style = "{\\c&H4C4CC3&}"
|
||
mp.add_timeout(1.5, build_menu)
|
||
end
|
||
|
||
table.insert(menu_log, { text = input_text, style = "{\\c&HCCCCCC&}" })
|
||
table.insert(menu_log, { text = hint_text, style = hint_style })
|
||
end
|
||
input.set_log(menu_log)
|
||
end
|
||
|
||
input.get({
|
||
keep_open = true,
|
||
prompt = "请在此输入操作(w/s|上移/下移): ",
|
||
opened = function() build_menu() end,
|
||
edited = function(text)
|
||
text = text:gsub("^%s*(.-)%s*$", "%1")
|
||
|
||
if text == "" then
|
||
build_menu()
|
||
return
|
||
end
|
||
|
||
if text:lower() == "w" or text:lower() == "s" then
|
||
input.terminate()
|
||
select_num = text:lower() == "w" and select_num - 1 or select_num + 1
|
||
select_num = (select_num > #ordered_keys) and 1 or (select_num <= 0 and #ordered_keys or select_num)
|
||
mp.add_timeout(0.01, function()
|
||
open_style_menu_get(select_num)
|
||
end)
|
||
return
|
||
end
|
||
|
||
build_menu(text)
|
||
end,
|
||
submit = function(text)
|
||
if select_query == nil then return end
|
||
text = text:gsub("^%s*(.-)%s*$", "%1")
|
||
if text == "" then return end
|
||
|
||
if text:lower() == "\\r" then
|
||
input.terminate()
|
||
local args = string.format('{"type":"activate","action":"%s","index":%d}', select_query, select_num)
|
||
mp.commandv("script-message-to", mp.get_script_name(), "setup-danmaku-style", args)
|
||
else
|
||
if menu_items_config[select_query]["scope"] ~= nil then
|
||
input.terminate()
|
||
mp.commandv("script-message-to", mp.get_script_name(), "setup-danmaku-style", select_query, text)
|
||
elseif text:lower() == "y" and select_query == "bold" then
|
||
input.terminate()
|
||
local args = string.format('{"type":"activate","index":%d}', select_num)
|
||
mp.commandv("script-message-to", mp.get_script_name(), "setup-danmaku-style", args)
|
||
end
|
||
end
|
||
return
|
||
end
|
||
})
|
||
end
|
||
|
||
function open_style_menu_uosc(actived, status)
|
||
local items = {}
|
||
for _, key in ipairs(ordered_keys) do
|
||
local config = menu_items_config[key]
|
||
local item_config = {
|
||
title = config.title,
|
||
hint = "目前:" .. tostring(config.hint),
|
||
active = key == actived,
|
||
keep_open = true,
|
||
selectable = true,
|
||
}
|
||
if config.hint ~= config.original then
|
||
local original_str = tostring(config.original)
|
||
item_config.actions = {{icon = "refresh", name = key, label = "恢复默认配置 < " .. original_str .. " >"}}
|
||
end
|
||
table.insert(items, item_config)
|
||
end
|
||
|
||
local menu_props = {
|
||
type = "menu_style",
|
||
title = "弹幕样式",
|
||
search_style = "disabled",
|
||
footnote = "样式更改仅在本次播放生效",
|
||
item_actions_place = "outside",
|
||
items = items,
|
||
callback = { mp.get_script_name(), 'setup-danmaku-style'},
|
||
}
|
||
|
||
local actions = "open-menu"
|
||
if status ~= nil then
|
||
-- msg.info(status)
|
||
if status == "updata" then
|
||
-- "updata" 模式会保留输入框文字
|
||
menu_props.title = " " .. menu_items_config[actived]["footnote"]
|
||
actions = "update-menu"
|
||
elseif status == "refresh" then
|
||
-- "refresh" 模式会清除输入框文字
|
||
menu_props.title = " " .. menu_items_config[actived]["footnote"]
|
||
elseif status == "error" then
|
||
menu_props.title = "输入非数字字符或范围出错"
|
||
-- 创建一个定时器,在1秒后触发回调函数,删除搜索栏错误信息
|
||
mp.add_timeout(1.0, function() open_style_menu_uosc(actived, "updata") end)
|
||
end
|
||
menu_props.search_style = "palette"
|
||
menu_props.search_debounce = "submit"
|
||
menu_props.footnote = menu_items_config[actived]["footnote"] or ""
|
||
menu_props.on_search = { "script-message-to", mp.get_script_name(), "setup-danmaku-style", actived }
|
||
end
|
||
|
||
local json_props = utils.format_json(menu_props)
|
||
mp.commandv("script-message-to", "uosc", actions, json_props)
|
||
end
|
||
|
||
function open_style_menu(actived, status)
|
||
if uosc_available then
|
||
open_style_menu_uosc(actived, status)
|
||
elseif input_loaded then
|
||
mp.add_timeout(0.01, function()
|
||
open_style_menu_get(actived, status)
|
||
end)
|
||
else
|
||
show_message("无支持可用的 UI框架,不支持使用该功能", 3)
|
||
end
|
||
end
|
||
|
||
-- 打开以指定时间为起点的延迟菜单
|
||
function open_delay_from_time_get(source, time, status)
|
||
mp.commandv('script-message-to', 'console', 'disable')
|
||
local menu_log = {}
|
||
|
||
local function build_menu(query, input_text)
|
||
menu_log = {
|
||
{ text = "【从该时间起调整弹幕延迟】", style = "{\\c&H00CCFF&\\b1}" },
|
||
{ text = ("-"):rep(33), style = "{\\c&H888888&}" }
|
||
}
|
||
|
||
table.insert(menu_log, { text = "\n", style = "" })
|
||
local hint_text = "提示:请输入数字,单位(秒)/ 或者按照形如\"14m15s\"的格式输入分钟数加秒数"
|
||
local hint_style = "{\\c&H999999&}"
|
||
if status == "error" then
|
||
hint_text = "提示: 输入非数字字符或范围出错"
|
||
hint_style = "{\\c&H4C4CC3&}"
|
||
end
|
||
|
||
table.insert(menu_log, { text = input_text and ("已输入:" .. input_text) or "", style = "{\\c&HCCCCCC&}" })
|
||
table.insert(menu_log, { text = hint_text, style = hint_style })
|
||
input.set_log(menu_log)
|
||
end
|
||
|
||
input.get({
|
||
keep_open = true,
|
||
prompt = "请输入要设置的延迟(秒或 XmYs): ",
|
||
opened = function() build_menu() end,
|
||
edited = function(text)
|
||
text = text:gsub("^%s*(.-)%s*$", "%1")
|
||
if text == "" then
|
||
build_menu()
|
||
return
|
||
end
|
||
build_menu(text)
|
||
end,
|
||
submit = function(text)
|
||
text = text and text:gsub("^%s*(.-)%s*$", "%1") or ""
|
||
if text == "" then return end
|
||
input.terminate()
|
||
local parsed = parse_delay_input(text)
|
||
if parsed ~= nil then
|
||
mp.commandv("script-message", "danmaku-delay", tostring(parsed), tostring(time), tostring(source))
|
||
else
|
||
open_delay_from_time(time, "error")
|
||
end
|
||
end
|
||
})
|
||
end
|
||
|
||
function open_delay_from_time_uosc(source, time, status)
|
||
if not uosc_available then
|
||
show_message("无uosc UI框架,不支持使用该功能", 2)
|
||
return
|
||
end
|
||
|
||
local menu_props = {
|
||
type = "menu_delay_from_time",
|
||
title = "从该时间起调整弹幕延迟",
|
||
search_style = "palette",
|
||
search_debounce = "submit",
|
||
footnote = "请输入数字,单位(秒)/ 或者按照形如\"14m15s\"的格式输入分钟数加秒数",
|
||
items = {},
|
||
on_search = { "script-message-to", mp.get_script_name(), "setup-content-delay", tostring(time), tostring(source) },
|
||
}
|
||
|
||
if status == "error" then
|
||
menu_props.title = "输入非数字字符或范围出错"
|
||
mp.add_timeout(1.0, function() open_delay_from_time_uosc(source, time) end)
|
||
end
|
||
|
||
local json_props = utils.format_json(menu_props)
|
||
mp.commandv("script-message-to", "uosc", "open-menu", json_props)
|
||
end
|
||
|
||
function open_delay_from_time(source, time, status)
|
||
if uosc_available then
|
||
open_delay_from_time_uosc(source, time, status)
|
||
elseif input_loaded then
|
||
mp.add_timeout(0.01, function()
|
||
open_delay_from_time_get(source, time, status)
|
||
end)
|
||
else
|
||
show_message("无支持可用的 UI框架,不支持使用该功能", 3)
|
||
end
|
||
end
|
||
|
||
-- 设置弹幕源延迟菜单
|
||
function open_delay_menu_get(source, status)
|
||
mp.commandv('script-message-to', 'console', 'disable')
|
||
local menu_log = {}
|
||
|
||
local serial = 0
|
||
local select_num = 0
|
||
if source and tonumber(source) ~= nil then
|
||
select_num = tonumber(source)
|
||
end
|
||
local select_url = nil
|
||
|
||
local function build_menu(query, text)
|
||
menu_log = {
|
||
{ text = "【弹幕源延迟菜单】", style = "{\\c&H00CCFF&\\b1}" },
|
||
{ text = ("-"):rep(33), style = "{\\c&H888888&}" }
|
||
}
|
||
|
||
serial, select_num = 0, 0
|
||
for url, src in pairs(DANMAKU.sources) do
|
||
if src.data and not src.blocked then
|
||
local delay = 0
|
||
serial = serial + 1
|
||
select_num = (url == source) and serial or select_num
|
||
if src.delay_segments then
|
||
for _, seg in ipairs(src.delay_segments) do
|
||
if seg.start == 0 then
|
||
delay = seg.delay or 0
|
||
break
|
||
end
|
||
end
|
||
end
|
||
local hint = "当前弹幕源延迟: " .. string.format("%.1f", delay + 1e-10) .. "秒"
|
||
local text = string.format(" [%02d] %s [%s] ", serial, url, hint)
|
||
local style = (serial == select_num) and "{\\c&HFFDE7F&}" or "{\\c&HCCCCCC&}"
|
||
table.insert(menu_log, { text = text, style = style })
|
||
select_url = serial == select_num and url or select_url
|
||
end
|
||
end
|
||
if serial == 0 then
|
||
table.insert(menu_log, { text = " 无", style = "" })
|
||
end
|
||
|
||
table.insert(menu_log, { text = ("-"):rep(33), style = "{\\c&H888888&}" })
|
||
if select_num == 0 then
|
||
table.insert(menu_log, { text = "\n", style = "" })
|
||
table.insert(menu_log, {
|
||
text = "提示: 输入【w】可上移选项,【s】可下移选项",
|
||
style = "{\\c&H999999&}"
|
||
})
|
||
else
|
||
local input_text = "已输入:" .. (text ~= nil and text or "")
|
||
|
||
local hint_text = "提示:请输入数字,单位(秒)/ 或者按照形如\"14m15s\"的格式输入分钟数加秒数"
|
||
local hint_style = "{\\c&H999999&}"
|
||
if status == "refresh" then
|
||
status = ""
|
||
hint_text = "提示: 样式更改成功"
|
||
hint_style = "{\\c&HFFDE7F&}"
|
||
mp.add_timeout(1.5, build_menu)
|
||
elseif status == "error" then
|
||
status = ""
|
||
hint_text = "提示: 输入非数字字符或范围出错"
|
||
hint_style = "{\\c&H4C4CC3&}"
|
||
mp.add_timeout(1.5, build_menu)
|
||
end
|
||
|
||
-- table.insert(menu_log, { text = input_text, style = "{\\c&HCCCCCC&}" })
|
||
table.insert(menu_log, { text = input_text, style = "{\\c&HCCCCCC&}" })
|
||
table.insert(menu_log, { text = hint_text, style = hint_style })
|
||
end
|
||
input.set_log(menu_log)
|
||
end
|
||
|
||
input.get({
|
||
keep_open = true,
|
||
prompt = "请在此输入操作(w/s|上移/下移): ",
|
||
opened = function() build_menu() end,
|
||
edited = function(text)
|
||
text = text:gsub("^%s*(.-)%s*$", "%1")
|
||
|
||
if text == "" then
|
||
build_menu()
|
||
return
|
||
end
|
||
|
||
if text:lower() == "w" or text:lower() == "s" then
|
||
input.terminate()
|
||
select_num = text:lower() == "w" and select_num - 1 or select_num + 1
|
||
select_num = (select_num > serial) and 1 or (select_num <= 0 and serial or select_num)
|
||
mp.add_timeout(0.01, function()
|
||
open_delay_menu_get(select_num)
|
||
end)
|
||
return
|
||
end
|
||
|
||
build_menu(select_num, text)
|
||
end,
|
||
submit = function(text)
|
||
if select_url == nil then return end
|
||
text = text:gsub("^%s*(.-)%s*$", "%1")
|
||
if text == "" then return end
|
||
|
||
input.terminate()
|
||
mp.commandv("script-message-to", mp.get_script_name(), "setup-source-delay", select_url, text)
|
||
return
|
||
end
|
||
})
|
||
end
|
||
|
||
function open_delay_menu_uosc(source_url, status)
|
||
if not uosc_available then
|
||
show_message("无uosc UI框架,不支持使用该功能", 2)
|
||
return
|
||
end
|
||
|
||
local sources = {}
|
||
for url, source in pairs(DANMAKU.sources) do
|
||
if source.data and not source.blocked then
|
||
local delay = 0
|
||
if source.delay_segments then
|
||
for _, seg in ipairs(source.delay_segments) do
|
||
if seg.start == 0 then
|
||
delay = seg.delay or 0
|
||
break
|
||
end
|
||
end
|
||
end
|
||
local item = {title = url, value = url, keep_open = true,}
|
||
item.hint = "当前弹幕源延迟:" .. string.format("%.1f", delay + 1e-10) .. "秒"
|
||
item.active = url == source_url
|
||
table.insert(sources, item)
|
||
end
|
||
end
|
||
|
||
local menu_props = {
|
||
type = "menu_delay",
|
||
title = "弹幕源延迟设置",
|
||
search_style = "disabled",
|
||
items = sources,
|
||
callback = {mp.get_script_name(), 'setup-source-delay'},
|
||
}
|
||
if source_url ~= nil then
|
||
if status == "error" then
|
||
menu_props.title = "输入非数字字符或范围出错"
|
||
-- 创建一个定时器,在1秒后触发回调函数,删除搜索栏错误信息
|
||
mp.add_timeout(1.0, function() open_delay_menu_uosc(source_url) end)
|
||
else
|
||
menu_props.title = "请输入数字,单位(秒)/ 或者按照形如\"14m15s\"的格式输入分钟数加秒数"
|
||
end
|
||
menu_props.search_style = "palette"
|
||
menu_props.search_debounce = "submit"
|
||
menu_props.on_search = { "script-message-to", mp.get_script_name(), "setup-source-delay", source_url }
|
||
end
|
||
|
||
local json_props = utils.format_json(menu_props)
|
||
mp.commandv("script-message-to", "uosc", "open-menu", json_props)
|
||
end
|
||
|
||
function open_delay_menu(source, status)
|
||
if uosc_available then
|
||
open_delay_menu_uosc(source, status)
|
||
elseif input_loaded then
|
||
mp.add_timeout(0.01, function()
|
||
open_delay_menu_get(source, status)
|
||
end)
|
||
else
|
||
show_message("无支持可用的 UI框架,不支持使用该功能", 3)
|
||
end
|
||
end
|
||
|
||
-- 总集合弹幕菜单
|
||
local total_menu_items_config = {
|
||
{ title = "弹幕搜索", action = "open_search_danmaku_menu" },
|
||
{ title = "从源添加弹幕", action = "open_add_source_menu" },
|
||
{ title = "弹幕源延迟设置", action = "open_source_delay_menu" },
|
||
{ title = "弹幕样式", action = "open_danmaku_style_menu" },
|
||
{ title = "弹幕内容", action = "open_content_danmaku_menu" },
|
||
}
|
||
|
||
function open_add_total_menu_uosc()
|
||
local items = {}
|
||
|
||
if DANMAKU.anime and DANMAKU.episode then
|
||
local episode = DANMAKU.episode:gsub("%s.-$","")
|
||
episode = episode:match("^(第.*[话回集]+)%s*") or episode
|
||
items[#items + 1] = {
|
||
title = string.format("已关联弹幕:%s-%s", DANMAKU.anime, episode),
|
||
bold = true,
|
||
italic = true,
|
||
keep_open = true,
|
||
selectable = false,
|
||
}
|
||
end
|
||
|
||
for _, config in ipairs(total_menu_items_config) do
|
||
table.insert(items, {
|
||
title = config.title,
|
||
value = { "script-message-to", mp.get_script_name(), config.action },
|
||
keep_open = false,
|
||
selectable = true,
|
||
})
|
||
end
|
||
|
||
local menu_props = {
|
||
type = "menu_total",
|
||
title = "弹幕设置",
|
||
search_style = "disabled",
|
||
items = items,
|
||
}
|
||
local json_props = utils.format_json(menu_props)
|
||
mp.commandv("script-message-to", "uosc", "open-menu", json_props)
|
||
end
|
||
|
||
function open_add_total_menu_select()
|
||
local item_titles, item_values = {}, {}
|
||
for i, config in ipairs(total_menu_items_config) do
|
||
item_titles[i] = config.title
|
||
item_values[i] = { "script-message-to", mp.get_script_name(), config.action }
|
||
end
|
||
|
||
mp.commandv('script-message-to', 'console', 'disable')
|
||
input.select({
|
||
prompt = '选择:',
|
||
items = item_titles,
|
||
submit = function(id)
|
||
mp.commandv(unpack(item_values[id]))
|
||
end,
|
||
})
|
||
end
|
||
|
||
function open_add_total_menu()
|
||
if uosc_available then
|
||
open_add_total_menu_uosc()
|
||
elseif input_loaded then
|
||
open_add_total_menu_select()
|
||
end
|
||
end
|
||
|
||
|
||
mp.commandv(
|
||
"script-message-to",
|
||
"uosc",
|
||
"set-button",
|
||
"danmaku",
|
||
utils.format_json({
|
||
icon = "search",
|
||
tooltip = "弹幕搜索",
|
||
command = "script-message open_search_danmaku_menu",
|
||
})
|
||
)
|
||
|
||
mp.commandv(
|
||
"script-message-to",
|
||
"uosc",
|
||
"set-button",
|
||
"danmaku_source",
|
||
utils.format_json({
|
||
icon = "add_box",
|
||
tooltip = "从源添加弹幕",
|
||
command = "script-message open_add_source_menu",
|
||
})
|
||
)
|
||
|
||
mp.commandv(
|
||
"script-message-to",
|
||
"uosc",
|
||
"set-button",
|
||
"danmaku_styles",
|
||
utils.format_json({
|
||
icon = "palette",
|
||
tooltip = "弹幕样式",
|
||
command = "script-message open_danmaku_style_menu",
|
||
})
|
||
)
|
||
|
||
mp.commandv(
|
||
"script-message-to",
|
||
"uosc",
|
||
"set-button",
|
||
"danmaku_delay",
|
||
utils.format_json({
|
||
icon = "more_time",
|
||
tooltip = "弹幕源延迟设置",
|
||
command = "script-message open_source_delay_menu",
|
||
})
|
||
)
|
||
|
||
mp.commandv(
|
||
"script-message-to",
|
||
"uosc",
|
||
"set-button",
|
||
"danmaku_menu",
|
||
utils.format_json({
|
||
icon = "grid_view",
|
||
tooltip = "弹幕设置",
|
||
command = "script-message open_add_total_menu",
|
||
})
|
||
)
|
||
|
||
|
||
mp.register_script_message('uosc-version', function()
|
||
uosc_available = true
|
||
end)
|
||
|
||
mp.commandv("script-message-to", "uosc", "set", "show_danmaku", "off")
|
||
mp.register_script_message("set", function(prop, value)
|
||
if prop ~= "show_danmaku" then
|
||
return
|
||
end
|
||
|
||
if value == "on" then
|
||
ENABLED = true
|
||
if COMMENTS == nil then
|
||
set_danmaku_visibility(true)
|
||
local path = mp.get_property("path")
|
||
init(path)
|
||
else
|
||
show_loaded()
|
||
show_danmaku_func()
|
||
end
|
||
else
|
||
show_message("关闭弹幕", 2)
|
||
ENABLED = false
|
||
hide_danmaku_func()
|
||
end
|
||
|
||
mp.commandv("script-message-to", "uosc", "set", "show_danmaku", value)
|
||
end)
|
||
|
||
-- 注册函数给 uosc 按钮使用
|
||
mp.register_script_message("search-anime-event", function(query)
|
||
if uosc_available then
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_danmaku")
|
||
end
|
||
local name, class = query:match("^(.-)%s*|%s*(.-)%s*$")
|
||
if name and class then
|
||
query_extra(name, class)
|
||
else
|
||
get_animes(query)
|
||
end
|
||
end)
|
||
mp.register_script_message("search-episodes-event", function(animeTitle, bangumiId)
|
||
if uosc_available then
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_anime")
|
||
end
|
||
get_episodes(animeTitle, bangumiId)
|
||
end)
|
||
|
||
-- Register script message to show the input menu
|
||
mp.register_script_message("load-danmaku", function(animeTitle, episodeTitle, episodeId)
|
||
ENABLED = true
|
||
DANMAKU.anime = animeTitle
|
||
DANMAKU.episode = episodeTitle
|
||
set_episode_id(episodeId, true)
|
||
end)
|
||
|
||
mp.register_script_message("add-source-event", function(query)
|
||
if uosc_available then
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_source")
|
||
end
|
||
ENABLED = true
|
||
add_danmaku_source(query, true)
|
||
end)
|
||
|
||
mp.register_script_message("open_danmaku_style_menu", function()
|
||
if uosc_available then
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_total")
|
||
end
|
||
open_style_menu()
|
||
end)
|
||
|
||
mp.register_script_message("open_content_danmaku_menu", function()
|
||
if uosc_available then
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_total")
|
||
end
|
||
open_content_menu()
|
||
end)
|
||
|
||
mp.register_script_message("open-latest-menu-anime", function ()
|
||
if uosc_available then
|
||
mp.commandv("script-message-to", "uosc", "open-menu", latest_menu_anime)
|
||
elseif input_loaded then
|
||
show_message("", 0)
|
||
mp.add_timeout(0.1, function()
|
||
open_menu_select(utils.parse_json(latest_menu_anime))
|
||
end)
|
||
end
|
||
end)
|
||
|
||
mp.register_script_message("setup-danmaku-style", function(query, text)
|
||
local event = utils.parse_json(query)
|
||
if event ~= nil then
|
||
-- item点击 或 图标点击
|
||
if event.type == "activate" then
|
||
if not event.action then
|
||
if ordered_keys[event.index] == "bold" then
|
||
options.bold = not options.bold
|
||
menu_items_config.bold.hint = options.bold and "true" or "false"
|
||
end
|
||
-- "updata" 模式会保留输入框文字
|
||
open_style_menu(ordered_keys[event.index], "updata")
|
||
return
|
||
else
|
||
-- msg.info("event.action:" .. event.action)
|
||
options[event.action] = menu_items_config[event.action]["original"]
|
||
menu_items_config[event.action]["hint"] = options[event.action]
|
||
open_style_menu(event.action, "updata")
|
||
if event.action == "fontsize" or event.action == "scrolltime" then
|
||
load_danmaku(true)
|
||
end
|
||
end
|
||
end
|
||
else
|
||
-- 数值输入
|
||
if text == nil or text == "" then
|
||
return
|
||
end
|
||
local newText, _ = text:gsub("%s", "") -- 移除所有空白字符
|
||
if tonumber(newText) ~= nil and menu_items_config[query]["scope"] ~= nil then
|
||
local num = tonumber(newText)
|
||
local min_num = menu_items_config[query]["scope"]["min"]
|
||
local max_num = menu_items_config[query]["scope"]["max"]
|
||
if num and min_num <= num and num <= max_num then
|
||
if string.match(menu_items_config[query]["footnote"], "整数") then
|
||
-- 输入范围为整数时向下取整
|
||
num = tostring(math.floor(num))
|
||
end
|
||
options[query] = tostring(num)
|
||
menu_items_config[query]["hint"] = options[query]
|
||
-- "refresh" 模式会清除输入框文字
|
||
open_style_menu(query, "refresh")
|
||
if query == "fontsize" or query == "scrolltime" then
|
||
load_danmaku(true, true)
|
||
end
|
||
return
|
||
end
|
||
end
|
||
open_style_menu(query, "error")
|
||
end
|
||
end)
|
||
|
||
mp.register_script_message('setup-danmaku-source', function(json)
|
||
local event = utils.parse_json(json)
|
||
if event.type == 'activate' then
|
||
|
||
if event.action == "delete" then
|
||
DANMAKU.sources[event.value] = nil
|
||
remove_source_from_history(event.value)
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_source")
|
||
open_add_menu()
|
||
load_danmaku(true)
|
||
end
|
||
|
||
if event.action == "block" then
|
||
DANMAKU.sources[event.value]["blocked"] = true
|
||
add_source_to_history(event.value, DANMAKU.sources[event.value])
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_source")
|
||
open_add_menu()
|
||
load_danmaku(true)
|
||
end
|
||
|
||
if event.action == "unblock" then
|
||
DANMAKU.sources[event.value]["blocked"] = false
|
||
add_source_to_history(event.value, DANMAKU.sources[event.value])
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_source")
|
||
open_add_menu()
|
||
load_danmaku(true)
|
||
end
|
||
end
|
||
end)
|
||
|
||
mp.register_script_message("setup-source-delay", function(query, text)
|
||
local event = utils.parse_json(query)
|
||
if event ~= nil then
|
||
-- item点击
|
||
if event.type == "activate" then
|
||
open_delay_menu(event.value)
|
||
end
|
||
else
|
||
-- 数值输入
|
||
if text == nil or text == "" then
|
||
return
|
||
end
|
||
local delay = parse_delay_input(text)
|
||
if delay ~= nil then
|
||
mp.commandv("script-message", "danmaku-delay", tostring(delay), "0")
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_delay")
|
||
mp.add_timeout(0.1, function()
|
||
open_delay_menu(query, "refresh")
|
||
end)
|
||
else
|
||
open_delay_menu(query, "error")
|
||
end
|
||
end
|
||
end)
|
||
|
||
mp.register_script_message('handle-danmaku-content-action', function(json)
|
||
local event = utils.parse_json(json)
|
||
if not event or event.type ~= 'activate' then return end
|
||
|
||
if event.action then
|
||
local d = COMMENTS[event.index]
|
||
if not d or not d.source then return end
|
||
|
||
if event.action == "block_source" then
|
||
DANMAKU.sources[d.source]["blocked"] = true
|
||
add_source_to_history(d.source, DANMAKU.sources[d.source])
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_content")
|
||
load_danmaku(true)
|
||
elseif event.action == "adjust_delay" then
|
||
-- 打开以该弹幕时间为起点的延迟菜单(该延迟将作用于该时间点及之后的弹幕),仅针对该条弹幕的 source
|
||
mp.commandv("script-message", "open_content_delay_menu", d.source, tostring(d.start_time))
|
||
end
|
||
else
|
||
if event.value then
|
||
if type(event.value) == "table" then
|
||
mp.commandv(unpack(event.value))
|
||
else
|
||
mp.command(event.value)
|
||
end
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_content")
|
||
end
|
||
end
|
||
end)
|
||
|
||
mp.register_script_message("open_content_delay_menu", function(source, time)
|
||
open_delay_from_time(source, tonumber(time))
|
||
end)
|
||
|
||
mp.register_script_message("setup-content-delay", function(...)
|
||
local args = {...}
|
||
if #args == 1 then
|
||
return
|
||
end
|
||
if #args >= 2 then
|
||
local time = tonumber(args[1])
|
||
local source = args[2]
|
||
local delay_str = args[3]
|
||
local delay = parse_delay_input(delay_str)
|
||
if delay ~= nil then
|
||
mp.commandv("script-message", "danmaku-delay", tostring(delay), tostring(time), tostring(source))
|
||
mp.commandv("script-message-to", "uosc", "close-menu", "menu_delay_from_time")
|
||
else
|
||
open_delay_from_time(source, tonumber(time), "error")
|
||
end
|
||
end
|
||
end) |