fix streaming with lyric notes in mpv
This commit is contained in:
@@ -92,7 +92,7 @@
|
||||
"(hitfile\\.net/[a-z0-9A-Z]{4,9})"
|
||||
],
|
||||
"regexp": "(hitf\\.(to|cc)/([a-z0-9A-Z]{4,9}))|(htfl\\.(net|to|cc)/([a-z0-9A-Z]{4,9}))|(hitfile\\.(net)/download/free/([a-z0-9A-Z]{4,9}))|((hitfile\\.net/[a-z0-9A-Z]{4,9}))",
|
||||
"status": true
|
||||
"status": false
|
||||
},
|
||||
"mega": {
|
||||
"name": "mega",
|
||||
@@ -618,7 +618,7 @@
|
||||
"(upload42\\.com/[0-9a-zA-Z]{12})"
|
||||
],
|
||||
"regexp": "(upload42\\.com/[0-9a-zA-Z]{12})",
|
||||
"status": true
|
||||
"status": false
|
||||
},
|
||||
"uploadbank": {
|
||||
"name": "uploadbank",
|
||||
@@ -690,7 +690,7 @@
|
||||
"uploadrar\\.(net|com)/([0-9a-z]{12})"
|
||||
],
|
||||
"regexp": "((get|cloud)\\.rahim-soft\\.com/([0-9a-z]{12}))|((fingau\\.com/([0-9a-z]{12})))|((tech|miui|cloud|flash)\\.getpczone\\.com/([0-9a-z]{12}))|(miui.rahim-soft\\.com/([0-9a-z]{12}))|(uploadrar\\.(net|com)/([0-9a-z]{12}))",
|
||||
"status": false,
|
||||
"status": true,
|
||||
"hardRedirect": [
|
||||
"uploadrar.com/([0-9a-zA-Z]{12})"
|
||||
]
|
||||
|
||||
268
MPV/LUA/main.lua
268
MPV/LUA/main.lua
@@ -46,6 +46,8 @@ local DOWNLOAD_STORE_MENU_TYPE = 'medios_download_pick_store'
|
||||
-- Menu types for the command submenu and trim prompt
|
||||
local CMD_MENU_TYPE = 'medios_cmd_menu'
|
||||
local TRIM_PROMPT_MENU_TYPE = 'medios_trim_prompt'
|
||||
local SLEEP_PROMPT_MENU_TYPE = 'medeia_sleep_timer_prompt'
|
||||
local _sleep_timer = nil
|
||||
|
||||
local PIPELINE_REQ_PROP = 'user-data/medeia-pipeline-request'
|
||||
local PIPELINE_RESP_PROP = 'user-data/medeia-pipeline-response'
|
||||
@@ -277,6 +279,66 @@ local function find_file_upwards(start_dir, relative_path, max_levels)
|
||||
return nil
|
||||
end
|
||||
|
||||
local function _append_unique_path(out, seen, path)
|
||||
path = trim(tostring(path or ''))
|
||||
if path == '' then
|
||||
return
|
||||
end
|
||||
local key = path:gsub('\\', '/'):lower()
|
||||
if seen[key] then
|
||||
return
|
||||
end
|
||||
seen[key] = true
|
||||
out[#out + 1] = path
|
||||
end
|
||||
|
||||
local function _build_sibling_script_candidates(file_name)
|
||||
local candidates = {}
|
||||
local seen = {}
|
||||
local script_dir = mp.get_script_directory() or ''
|
||||
local cwd = utils.getcwd() or ''
|
||||
|
||||
if script_dir ~= '' then
|
||||
_append_unique_path(candidates, seen, script_dir .. '/' .. file_name)
|
||||
_append_unique_path(candidates, seen, script_dir .. '/LUA/' .. file_name)
|
||||
_append_unique_path(candidates, seen, script_dir .. '/../' .. file_name)
|
||||
_append_unique_path(candidates, seen, find_file_upwards(script_dir, 'MPV/LUA/' .. file_name, 8))
|
||||
end
|
||||
|
||||
if cwd ~= '' then
|
||||
_append_unique_path(candidates, seen, find_file_upwards(cwd, 'MPV/LUA/' .. file_name, 8))
|
||||
end
|
||||
|
||||
return candidates
|
||||
end
|
||||
|
||||
local function _load_lua_chunk_from_candidates(label, file_name)
|
||||
local candidates = _build_sibling_script_candidates(file_name)
|
||||
local last_error = nil
|
||||
|
||||
for _, candidate in ipairs(candidates) do
|
||||
local ok_load, chunk_or_err, load_err = pcall(loadfile, candidate)
|
||||
if ok_load and chunk_or_err then
|
||||
local ok_run, result_or_err = pcall(chunk_or_err)
|
||||
if ok_run then
|
||||
_lua_log(label .. ': loaded from ' .. candidate)
|
||||
return true, result_or_err, candidate
|
||||
end
|
||||
last_error = tostring(result_or_err or 'runtime error')
|
||||
_lua_log(label .. ': runtime error at ' .. candidate .. ' (' .. last_error .. ')')
|
||||
elseif ok_load then
|
||||
last_error = tostring(load_err or 'loadfile failed')
|
||||
_lua_log(label .. ': load failed at ' .. candidate .. ' (' .. last_error .. ')')
|
||||
else
|
||||
last_error = tostring(chunk_or_err or 'loadfile failed')
|
||||
_lua_log(label .. ': load failed at ' .. candidate .. ' (' .. last_error .. ')')
|
||||
end
|
||||
end
|
||||
|
||||
_lua_log(label .. ': load failed; candidates=' .. tostring(#candidates) .. ' last_error=' .. tostring(last_error or 'not found'))
|
||||
return false, nil, nil, last_error
|
||||
end
|
||||
|
||||
-- Forward declaration (defined later) used by helper auto-start.
|
||||
local _resolve_python_exe
|
||||
|
||||
@@ -1309,6 +1371,153 @@ mp.register_script_message('medeia-audio-only', function()
|
||||
_audio_only()
|
||||
end)
|
||||
|
||||
local function _cancel_sleep_timer(show_message)
|
||||
if _sleep_timer ~= nil then
|
||||
pcall(function()
|
||||
_sleep_timer:kill()
|
||||
end)
|
||||
_sleep_timer = nil
|
||||
end
|
||||
if show_message then
|
||||
mp.osd_message('Sleep timer cancelled', 1.5)
|
||||
end
|
||||
end
|
||||
|
||||
local function _parse_sleep_minutes(text)
|
||||
local s = trim(tostring(text or '')):lower()
|
||||
if s == '' then
|
||||
return nil
|
||||
end
|
||||
|
||||
if s == 'off' or s == 'cancel' or s == 'stop' or s == '0' then
|
||||
return 0
|
||||
end
|
||||
|
||||
local hours = s:match('^([%d%.]+)%s*h$')
|
||||
if hours then
|
||||
local value = tonumber(hours)
|
||||
if value and value > 0 then
|
||||
return value * 60
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local mins = s:match('^([%d%.]+)%s*m$')
|
||||
if mins then
|
||||
local value = tonumber(mins)
|
||||
if value and value >= 0 then
|
||||
return value
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local value = tonumber(s)
|
||||
if value and value >= 0 then
|
||||
return value
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function _open_sleep_timer_prompt()
|
||||
local items = {
|
||||
{
|
||||
title = '15 minutes',
|
||||
hint = 'Quick preset',
|
||||
value = { 'script-message-to', mp.get_script_name(), 'medeia-sleep-timer-event', utils.format_json({ type = 'search', query = '15' }) },
|
||||
},
|
||||
{
|
||||
title = '30 minutes',
|
||||
hint = 'Quick preset',
|
||||
value = { 'script-message-to', mp.get_script_name(), 'medeia-sleep-timer-event', utils.format_json({ type = 'search', query = '30' }) },
|
||||
},
|
||||
{
|
||||
title = '60 minutes',
|
||||
hint = 'Quick preset',
|
||||
value = { 'script-message-to', mp.get_script_name(), 'medeia-sleep-timer-event', utils.format_json({ type = 'search', query = '60' }) },
|
||||
},
|
||||
{
|
||||
title = 'Cancel timer',
|
||||
hint = 'Also accepts off / 0 / cancel',
|
||||
value = { 'script-message-to', mp.get_script_name(), 'medeia-sleep-timer-event', utils.format_json({ type = 'search', query = '0' }) },
|
||||
},
|
||||
}
|
||||
|
||||
local menu_data = {
|
||||
type = SLEEP_PROMPT_MENU_TYPE,
|
||||
title = 'Sleep Timer',
|
||||
search_style = 'palette',
|
||||
search_debounce = 'submit',
|
||||
on_search = { 'script-message-to', mp.get_script_name(), 'medeia-sleep-timer-search' },
|
||||
footnote = 'Enter minutes (30), or use 1h / 1.5h. Enter 0 to cancel.',
|
||||
items = items,
|
||||
}
|
||||
|
||||
if ensure_uosc_loaded() then
|
||||
mp.commandv('script-message-to', 'uosc', 'open-menu', utils.format_json(menu_data))
|
||||
else
|
||||
mp.osd_message('Sleep timer unavailable (uosc not loaded)', 2.0)
|
||||
end
|
||||
end
|
||||
|
||||
local function _apply_sleep_timer_query(query)
|
||||
local minutes = _parse_sleep_minutes(query)
|
||||
if minutes == nil then
|
||||
mp.osd_message('Sleep timer: enter minutes, 1h, or 0 to cancel', 2.0)
|
||||
return
|
||||
end
|
||||
|
||||
if minutes <= 0 then
|
||||
_cancel_sleep_timer(true)
|
||||
pcall(function()
|
||||
mp.commandv('script-message-to', 'uosc', 'close-menu', SLEEP_PROMPT_MENU_TYPE)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
_cancel_sleep_timer(false)
|
||||
|
||||
local seconds = math.max(1, math.floor(minutes * 60))
|
||||
_sleep_timer = mp.add_timeout(seconds, function()
|
||||
_sleep_timer = nil
|
||||
mp.osd_message('Sleep timer: closing mpv', 1.5)
|
||||
mp.commandv('quit')
|
||||
end)
|
||||
|
||||
mp.osd_message(string.format('Sleep timer set: %d min', math.floor(minutes + 0.5)), 1.5)
|
||||
_lua_log('sleep: timer set minutes=' .. tostring(minutes) .. ' seconds=' .. tostring(seconds))
|
||||
|
||||
pcall(function()
|
||||
mp.commandv('script-message-to', 'uosc', 'close-menu', SLEEP_PROMPT_MENU_TYPE)
|
||||
end)
|
||||
end
|
||||
|
||||
local function _handle_sleep_timer_event(json)
|
||||
local ok, ev = pcall(utils.parse_json, json)
|
||||
if not ok or type(ev) ~= 'table' then
|
||||
_lua_log('sleep: invalid event payload=' .. tostring(json))
|
||||
return
|
||||
end
|
||||
|
||||
if ev.type ~= 'search' then
|
||||
return
|
||||
end
|
||||
|
||||
_apply_sleep_timer_query(ev.query)
|
||||
end
|
||||
|
||||
mp.register_script_message('medeia-sleep-timer', function()
|
||||
_open_sleep_timer_prompt()
|
||||
end)
|
||||
|
||||
mp.register_script_message('medeia-sleep-timer-event', function(json)
|
||||
_handle_sleep_timer_event(json)
|
||||
end)
|
||||
|
||||
mp.register_script_message('medeia-sleep-timer-search', function(query)
|
||||
_apply_sleep_timer_query(query)
|
||||
end)
|
||||
|
||||
local function _bind_image_key(key, name, fn, opts)
|
||||
opts = opts or {}
|
||||
if ImageControl.binding_names[name] then
|
||||
@@ -2680,37 +2889,12 @@ local function _start_trim_with_range(range)
|
||||
_lua_log('=== TRIM START: range=' .. tostring(range))
|
||||
mp.osd_message('Trimming...', 10)
|
||||
|
||||
-- Load the trim module for direct FFmpeg trimming
|
||||
local script_dir = mp.get_script_directory()
|
||||
_lua_log('trim: script_dir=' .. tostring(script_dir))
|
||||
|
||||
-- Try multiple locations for trim.lua
|
||||
local trim_paths = {}
|
||||
if script_dir and script_dir ~= '' then
|
||||
table.insert(trim_paths, script_dir .. '/trim.lua')
|
||||
table.insert(trim_paths, script_dir .. '/LUA/trim.lua') -- if called from parent
|
||||
table.insert(trim_paths, script_dir .. '/../trim.lua')
|
||||
end
|
||||
|
||||
-- Also try absolute path
|
||||
table.insert(trim_paths, '/medios/Medios-Macina/MPV/LUA/trim.lua')
|
||||
table.insert(trim_paths, 'C:/medios/Medios-Macina/MPV/LUA/trim.lua')
|
||||
|
||||
local trim_module = nil
|
||||
local trim_path = nil
|
||||
local load_err = nil
|
||||
local ok_trim = false
|
||||
|
||||
for _, trim_path in ipairs(trim_paths) do
|
||||
_lua_log('trim: trying path=' .. trim_path)
|
||||
local ok, result = pcall(loadfile, trim_path)
|
||||
if ok and result then
|
||||
trim_module = result()
|
||||
_lua_log('trim: loaded successfully from ' .. trim_path)
|
||||
break
|
||||
else
|
||||
load_err = tostring(result or 'unknown error')
|
||||
_lua_log('trim: failed to load from ' .. trim_path .. ' (' .. load_err .. ')')
|
||||
end
|
||||
end
|
||||
ok_trim, trim_module, trim_path, load_err = _load_lua_chunk_from_candidates('trim', 'trim.lua')
|
||||
|
||||
if not trim_module or not trim_module.trim_file then
|
||||
mp.osd_message('ERROR: Could not load trim module from any path', 3)
|
||||
@@ -2718,6 +2902,10 @@ local function _start_trim_with_range(range)
|
||||
return
|
||||
end
|
||||
|
||||
if ok_trim and trim_path then
|
||||
_lua_log('trim: using module at ' .. tostring(trim_path))
|
||||
end
|
||||
|
||||
range = trim(tostring(range or ''))
|
||||
_lua_log('trim: after_trim range=' .. tostring(range))
|
||||
|
||||
@@ -3200,6 +3388,7 @@ mp.add_timeout(0, function()
|
||||
pcall(ensure_mpv_ipc_server)
|
||||
pcall(_lua_log, 'medeia-lua loaded version=' .. MEDEIA_LUA_VERSION)
|
||||
|
||||
local ok_helper, helper_err = pcall(function()
|
||||
attempt_start_pipeline_helper_async(function(success)
|
||||
if success then
|
||||
_lua_log('helper-auto-start succeeded')
|
||||
@@ -3207,6 +3396,10 @@ mp.add_timeout(0, function()
|
||||
_lua_log('helper-auto-start failed')
|
||||
end
|
||||
end)
|
||||
end)
|
||||
if not ok_helper then
|
||||
_lua_log('helper-auto-start raised: ' .. tostring(helper_err))
|
||||
end
|
||||
|
||||
-- Try to re-register right-click after UOSC loads (might override its binding)
|
||||
mp.add_timeout(1.0, function()
|
||||
@@ -3218,25 +3411,6 @@ mp.add_timeout(0, function()
|
||||
end, {repeatable=false})
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Load optional modules (kept in separate files).
|
||||
pcall(function()
|
||||
local script_dir = mp.get_script_directory() or ''
|
||||
local candidates = {}
|
||||
if script_dir ~= '' then
|
||||
table.insert(candidates, script_dir .. '/sleep_timer.lua')
|
||||
table.insert(candidates, script_dir .. '/LUA/sleep_timer.lua')
|
||||
table.insert(candidates, script_dir .. '/../sleep_timer.lua')
|
||||
end
|
||||
table.insert(candidates, 'C:/medios/Medios-Macina/MPV/LUA/sleep_timer.lua')
|
||||
for _, p in ipairs(candidates) do
|
||||
local ok, chunk = pcall(loadfile, p)
|
||||
if ok and chunk then
|
||||
pcall(chunk)
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
return M
|
||||
|
||||
@@ -1208,6 +1208,8 @@ def run_auto_overlay(
|
||||
autofetch_enabled = bool(cfg.get("lyric_autofetch", True))
|
||||
now = time.time()
|
||||
if (
|
||||
not lrc_text
|
||||
and
|
||||
autofetch_enabled
|
||||
and state.key != state.fetch_attempt_key
|
||||
and (now - state.fetch_attempt_at) > 2.0
|
||||
|
||||
Reference in New Issue
Block a user