This commit is contained in:
2026-03-16 04:43:46 -07:00
parent 11f03cae3e
commit 4106822a0f
2 changed files with 158 additions and 59 deletions

View File

@@ -52,6 +52,7 @@ local _sleep_timer = nil
local PIPELINE_REQ_PROP = 'user-data/medeia-pipeline-request'
local PIPELINE_RESP_PROP = 'user-data/medeia-pipeline-response'
local PIPELINE_READY_PROP = 'user-data/medeia-pipeline-ready'
local CURRENT_WEB_URL_PROP = 'user-data/medeia-current-web-url'
-- Dedicated Lua log: write directly to logs.db database for unified logging
-- Fallback to stderr if database unavailable
@@ -1885,6 +1886,21 @@ function FileState.new()
}, FileState)
end
function FileState:set_url(url)
local normalized = trim(tostring(url or ''))
if normalized == '' then
self.url = nil
self.formats = nil
self.formats_table = nil
return
end
if self.url ~= normalized then
self.url = normalized
self.formats = nil
self.formats_table = nil
end
end
function FileState:has_formats()
return type(self.formats) == 'table'
and type(self.formats.rows) == 'table'
@@ -1892,7 +1908,7 @@ function FileState:has_formats()
end
function FileState:set_formats(url, tbl)
self.url = url
self:set_url(url)
self.formats = tbl
self.formats_table = tbl
end
@@ -1903,6 +1919,7 @@ M.file = M.file or FileState.new()
local _formats_cache = {}
local _formats_inflight = {}
local _formats_waiters = {}
local _get_cached_formats_table
local _ipc_async_busy = false
local _ipc_async_queue = {}
@@ -1983,6 +2000,70 @@ local function _is_ytdlp_url(u)
return false
end
local function _set_current_web_url(url)
local normalized = trim(tostring(url or ''))
if normalized ~= '' and _is_http_url(normalized) then
pcall(mp.set_property, CURRENT_WEB_URL_PROP, normalized)
if type(M.file) == 'table' and M.file.set_url then
M.file:set_url(normalized)
end
return normalized
end
pcall(mp.set_property, CURRENT_WEB_URL_PROP, '')
if type(M.file) == 'table' and M.file.set_url then
M.file:set_url(nil)
end
return nil
end
local function _get_current_web_url()
local current = trim(tostring(mp.get_property(CURRENT_WEB_URL_PROP) or ''))
if current ~= '' and _is_http_url(current) then
return current
end
return nil
end
local function _current_url_for_web_actions()
local current = _get_current_web_url()
if current and current ~= '' then
return current
end
local target = _current_target()
if not target or target == '' then
return nil
end
return tostring(target)
end
local function _sync_current_web_url_from_playback()
local target = _current_target()
local target_str = trim(tostring(target or ''))
if target_str ~= '' and _extract_store_hash(target_str) then
_set_current_web_url(nil)
return
end
if target_str ~= '' and _is_http_url(target_str) and _is_ytdlp_url(target_str) then
_set_current_web_url(target_str)
return
end
local current = _get_current_web_url()
if current and current ~= '' then
local raw = mp.get_property_native('ytdl-raw-info')
if type(raw) == 'table' then
if type(M.file) == 'table' and M.file.set_url then
M.file:set_url(current)
end
return
end
end
if target_str == '' or not _is_http_url(target_str) then
_set_current_web_url(nil)
end
end
local function _cache_formats_for_url(url, tbl)
if type(url) ~= 'string' or url == '' then
return
@@ -2000,7 +2081,7 @@ local function _cache_formats_for_url(url, tbl)
end
end
local function _get_cached_formats_table(url)
_get_cached_formats_table = function(url)
if type(url) ~= 'string' or url == '' then
return nil
end
@@ -2111,8 +2192,13 @@ local function _prefetch_formats_for_url(url)
if url == '' or not _is_http_url(url) then
return
end
_set_current_web_url(url)
if type(M.file) == 'table' then
if M.file.set_url then
M.file:set_url(url)
else
M.file.url = url
end
if M.file.fetch_formats then
M.file:fetch_formats(nil)
end
@@ -2307,8 +2393,11 @@ local function _apply_ytdl_format_and_reload(url, fmt)
local pos = mp.get_property_number('time-pos')
local paused = mp.get_property_native('pause') and true or false
_lua_log('change-format: setting options/ytdl-format=' .. tostring(fmt))
_lua_log('change-format: setting ytdl format=' .. tostring(fmt))
_set_current_web_url(url)
pcall(mp.set_property, 'options/ytdl-format', tostring(fmt))
pcall(mp.set_property, 'file-local-options/ytdl-format', tostring(fmt))
pcall(mp.set_property, 'ytdl-format', tostring(fmt))
if pos and pos > 0 then
mp.commandv('loadfile', url, 'replace', 'start=' .. tostring(pos))
@@ -2322,7 +2411,7 @@ local function _apply_ytdl_format_and_reload(url, fmt)
end
local function _start_download_flow_for_current()
local target = _current_target()
local target = _current_url_for_web_actions() or _current_target()
if not target or target == '' then
mp.osd_message('No current item', 2)
return
@@ -2371,7 +2460,7 @@ mp.register_script_message('medios-download-current', function()
end)
mp.register_script_message('medios-change-format-current', function()
local target = _current_target()
local target = _current_url_for_web_actions() or _current_target()
if not target or target == '' then
mp.osd_message('No current item', 2)
return
@@ -2384,15 +2473,22 @@ mp.register_script_message('medios-change-format-current', function()
end
local url = tostring(target)
_set_current_web_url(url)
-- Ensure file state is tracking the current URL.
if type(M.file) == 'table' then
if M.file.set_url then
M.file:set_url(url)
else
M.file.url = url
end
end
-- If formats were already prefetched for this URL, open instantly.
local cached_tbl = nil
if type(M.file) == 'table' and type(M.file.formats) == 'table' then
if type(M.file) == 'table'
and M.file.url == url
and type(M.file.formats) == 'table' then
cached_tbl = M.file.formats
else
cached_tbl = _get_cached_formats_table(url)
@@ -2506,7 +2602,8 @@ end)
-- Prefetch formats for yt-dlp-supported URLs on load so Change Format is instant.
mp.register_event('file-loaded', function()
local target = _current_target()
_sync_current_web_url_from_playback()
local target = _current_url_for_web_actions() or _current_target()
if not target or target == '' then
return
end
@@ -3188,6 +3285,7 @@ mp.register_script_message('medios-load-url-event', function(json)
mp.osd_message('Loading URL...', 1)
_log_all('INFO', 'Load URL started: ' .. url)
_lua_log('[LOAD-URL] Starting to load: ' .. url)
_set_current_web_url(url)
local function close_menu()
_lua_log('[LOAD-URL] Closing menu')
@@ -3199,16 +3297,21 @@ mp.register_script_message('medios-load-url-event', function(json)
end
end
-- Close the URL prompt immediately once the user submits. Playback may still
-- take time to resolve, but the modal should not stay stuck on screen.
close_menu()
-- First, always try direct loadfile. This is the fastest path.
local can_direct = _url_can_direct_load(url)
local prefer_direct = can_direct or _is_ytdlp_url(url)
_lua_log('[LOAD-URL] Checking if URL can be loaded directly: ' .. tostring(can_direct))
_lua_log('[LOAD-URL] Prefer direct load: ' .. tostring(prefer_direct))
local direct_ok, direct_loaded = _try_direct_loadfile(url, false)
local direct_ok, direct_loaded = _try_direct_loadfile(url, prefer_direct)
if direct_ok and direct_loaded then
_lua_log('[LOAD-URL] Direct loadfile command sent successfully (forced)')
_log_all('INFO', 'Load URL succeeded via direct load')
mp.osd_message('URL loaded', 2)
close_menu()
return
end
if direct_ok then
@@ -3223,33 +3326,12 @@ mp.register_script_message('medios-load-url-event', function(json)
local helper_ready = ensure_pipeline_helper_running()
_lua_log('[LOAD-URL] Pipeline helper ready: ' .. tostring(helper_ready))
if not helper_ready then
_lua_log('[LOAD-URL] Pipeline helper not available, attempting to start...')
_log_all('WARN', 'Pipeline helper not running, attempting auto-start')
mp.osd_message('Starting pipeline helper...', 2)
-- Attempt to start the helper asynchronously
attempt_start_pipeline_helper_async(function(success)
if success then
_lua_log('[LOAD-URL] Helper started successfully, retry Load URL from menu')
_log_all('INFO', 'Pipeline helper started successfully')
mp.osd_message('Helper started! Try Load URL again', 2)
else
_lua_log('[LOAD-URL] Failed to start helper')
_log_all('ERROR', 'Failed to start pipeline helper')
mp.osd_message('Could not start pipeline helper', 3)
end
close_menu()
end)
return
end
local function start_pipeline_load()
-- Use pipeline to download/prepare the URL
local pipeline_cmd = '.mpv -url ' .. quote_pipeline_arg(url) .. ' -play'
_lua_log('[LOAD-URL] Sending to pipeline: ' .. pipeline_cmd)
_lua_log('[LOAD-URL] Pipeline helper ready: ' .. tostring(_is_pipeline_helper_ready()))
-- Add a timeout message after a delay to give user feedback
local timeout_timer = nil
timeout_timer = mp.add_timeout(5, function()
if timeout_timer then
@@ -3270,23 +3352,42 @@ mp.register_script_message('medios-load-url-event', function(json)
_lua_log('[LOAD-URL] Pipeline error: ' .. tostring(err))
_log_all('ERROR', 'Load URL pipeline failed: ' .. tostring(err))
mp.osd_message('Load URL failed: ' .. tostring(err), 3)
close_menu()
return
end
_lua_log('[LOAD-URL] URL loaded successfully')
_log_all('INFO', 'Load URL succeeded')
mp.osd_message('URL loaded', 2)
-- Prefetch formats for yt-dlp URLs so "Change Format" menu is instant
if _is_ytdlp_url(url) then
_lua_log('[LOAD-URL] URL is yt-dlp compatible, prefetching formats in background')
mp.add_timeout(0.5, function()
_prefetch_formats_for_url(url)
end)
end
close_menu()
end)
end
if not helper_ready then
_lua_log('[LOAD-URL] Pipeline helper not available, attempting to start...')
_log_all('WARN', 'Pipeline helper not running, attempting auto-start')
mp.osd_message('Starting pipeline helper...', 2)
-- Attempt to start the helper asynchronously
attempt_start_pipeline_helper_async(function(success)
if success then
_lua_log('[LOAD-URL] Helper started successfully, continuing load')
_log_all('INFO', 'Pipeline helper started successfully')
start_pipeline_load()
else
_lua_log('[LOAD-URL] Failed to start helper')
_log_all('ERROR', 'Failed to start pipeline helper')
mp.osd_message('Could not start pipeline helper', 3)
end
end)
return
end
start_pipeline_load()
end)
-- Menu integration with UOSC

View File

@@ -1679,8 +1679,6 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
if save_mode:
# Avoid `shell=True` / `date /t` on Windows (can flash a cmd.exe window).
# Use Python's datetime instead.
from datetime import datetime
playlist_name = index_arg or f"Playlist {datetime.now().strftime('%Y-%m-%d')}"
# If index_arg was used for name, clear it so it doesn't trigger index logic
if index_arg: