k
This commit is contained in:
200
MPV/LUA/main.lua
200
MPV/LUA/main.lua
@@ -961,6 +961,14 @@ local function _get_selected_store_conf_path()
|
||||
return utils.join_path(dir, 'medeia.conf')
|
||||
end
|
||||
|
||||
function M._get_selected_store_state_path()
|
||||
local dir = _get_script_opts_dir()
|
||||
if not dir then
|
||||
return nil
|
||||
end
|
||||
return utils.join_path(dir, 'medeia-selected-store.json')
|
||||
end
|
||||
|
||||
function M._get_store_cache_path()
|
||||
local dir = _get_script_opts_dir()
|
||||
if not dir then
|
||||
@@ -1030,6 +1038,25 @@ function M._prime_store_cache_from_disk()
|
||||
end
|
||||
|
||||
local function _load_selected_store_from_disk()
|
||||
local state_path = M._get_selected_store_state_path()
|
||||
if state_path then
|
||||
local fh = io.open(state_path, 'r')
|
||||
if fh then
|
||||
local raw = fh:read('*a')
|
||||
fh:close()
|
||||
raw = trim(tostring(raw or ''))
|
||||
if raw ~= '' then
|
||||
local ok, payload = pcall(utils.parse_json, raw)
|
||||
if ok and type(payload) == 'table' then
|
||||
local value = _normalize_store_name(payload.store)
|
||||
if value ~= '' then
|
||||
return value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local path = _get_selected_store_conf_path()
|
||||
if not path then
|
||||
return nil
|
||||
@@ -1054,7 +1081,7 @@ local function _load_selected_store_from_disk()
|
||||
end
|
||||
|
||||
local function _save_selected_store_to_disk(store)
|
||||
local path = _get_selected_store_conf_path()
|
||||
local path = M._get_selected_store_state_path()
|
||||
if not path then
|
||||
return false
|
||||
end
|
||||
@@ -1062,8 +1089,7 @@ local function _save_selected_store_to_disk(store)
|
||||
if not fh then
|
||||
return false
|
||||
end
|
||||
fh:write('# Medeia MPV script options\n')
|
||||
fh:write('store=' .. tostring(store or '') .. '\n')
|
||||
fh:write(utils.format_json({ store = _normalize_store_name(store) }))
|
||||
fh:close()
|
||||
return true
|
||||
end
|
||||
@@ -1095,6 +1121,42 @@ local function _ensure_selected_store_loaded()
|
||||
if disk ~= '' then
|
||||
pcall(mp.set_property, SELECTED_STORE_PROP, disk)
|
||||
end
|
||||
pcall(function()
|
||||
local legacy_path = _get_selected_store_conf_path()
|
||||
if not legacy_path then
|
||||
return
|
||||
end
|
||||
local fh = io.open(legacy_path, 'r')
|
||||
if not fh then
|
||||
return
|
||||
end
|
||||
local raw = fh:read('*a')
|
||||
fh:close()
|
||||
raw = tostring(raw or '')
|
||||
if raw == '' or not raw:lower():find('store%s*=') then
|
||||
return
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
for line in raw:gmatch('[^\r\n]+') do
|
||||
local s = trim(tostring(line or ''))
|
||||
local k = s:match('^([%w_%-]+)%s*=')
|
||||
if not (k and k:lower() == 'store') then
|
||||
lines[#lines + 1] = line
|
||||
end
|
||||
end
|
||||
|
||||
local out = table.concat(lines, '\n')
|
||||
if out ~= '' then
|
||||
out = out .. '\n'
|
||||
end
|
||||
local writer = io.open(legacy_path, 'w')
|
||||
if not writer then
|
||||
return
|
||||
end
|
||||
writer:write(out)
|
||||
writer:close()
|
||||
end)
|
||||
pcall(M._prime_store_cache_from_disk)
|
||||
end
|
||||
|
||||
@@ -3662,7 +3724,7 @@ function M._build_web_ytdl_raw_options()
|
||||
extra[#extra + 1] = 'write-auto-subs='
|
||||
end
|
||||
if not lower:find('sub%-langs=', 1) then
|
||||
extra[#extra + 1] = 'sub-langs=[all,-live_chat]'
|
||||
extra[#extra + 1] = 'sub-langs=[en.*,en,-live_chat]'
|
||||
end
|
||||
|
||||
if #extra == 0 then
|
||||
@@ -3697,35 +3759,115 @@ function M._find_subtitle_track_candidate()
|
||||
return nil, nil, false
|
||||
end
|
||||
|
||||
local first_id = nil
|
||||
local default_id = nil
|
||||
local selected_id = nil
|
||||
local function subtitle_track_blob(track)
|
||||
local parts = {}
|
||||
local fields = { 'lang', 'title', 'name', 'external-filename' }
|
||||
for _, key in ipairs(fields) do
|
||||
local value = ''
|
||||
if type(track) == 'table' then
|
||||
value = trim(tostring(track[key] or '')):lower()
|
||||
end
|
||||
if value ~= '' then
|
||||
parts[#parts + 1] = value
|
||||
end
|
||||
end
|
||||
return table.concat(parts, ' ')
|
||||
end
|
||||
|
||||
local function subtitle_track_is_english(track, blob)
|
||||
local lang = ''
|
||||
if type(track) == 'table' then
|
||||
lang = trim(tostring(track.lang or '')):lower()
|
||||
end
|
||||
if lang == 'en' or lang == 'eng' or lang:match('^en[-_]') or lang:match('^eng[-_]') then
|
||||
return true
|
||||
end
|
||||
local text = blob or subtitle_track_blob(track)
|
||||
if text:match('%f[%a]english%f[%A]') then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function subtitle_track_is_autogenerated(track, blob)
|
||||
local text = blob or subtitle_track_blob(track)
|
||||
local markers = {
|
||||
'auto-generated',
|
||||
'auto generated',
|
||||
'autogenerated',
|
||||
'automatic captions',
|
||||
'automatic subtitles',
|
||||
'generated automatically',
|
||||
'asr',
|
||||
}
|
||||
for _, marker in ipairs(markers) do
|
||||
if text:find(marker, 1, true) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local best_id = nil
|
||||
local best_source = nil
|
||||
local best_selected = false
|
||||
local best_score = nil
|
||||
|
||||
for _, track in ipairs(tracks) do
|
||||
if type(track) == 'table' and tostring(track.type or '') == 'sub' and not track.albumart then
|
||||
local id = tonumber(track.id)
|
||||
if id then
|
||||
if first_id == nil then
|
||||
first_id = id
|
||||
local blob = subtitle_track_blob(track)
|
||||
local selected = track.selected and true or false
|
||||
local source = 'fallback'
|
||||
local score = 100
|
||||
|
||||
if blob:find('medeia-sub', 1, true) then
|
||||
source = 'medeia-note'
|
||||
score = 1000
|
||||
else
|
||||
local english = subtitle_track_is_english(track, blob)
|
||||
local autogenerated = subtitle_track_is_autogenerated(track, blob)
|
||||
if english and not autogenerated then
|
||||
source = 'english-manual'
|
||||
score = 800
|
||||
elseif english and autogenerated then
|
||||
source = 'english-auto'
|
||||
score = 700
|
||||
elseif selected then
|
||||
source = 'selected'
|
||||
score = 300
|
||||
elseif track.default then
|
||||
source = 'default'
|
||||
score = 200
|
||||
else
|
||||
source = 'first'
|
||||
score = 100
|
||||
end
|
||||
end
|
||||
if track.selected then
|
||||
selected_id = id
|
||||
|
||||
if selected then
|
||||
score = score + 50
|
||||
end
|
||||
if default_id == nil and track.default then
|
||||
default_id = id
|
||||
if track.default then
|
||||
score = score + 25
|
||||
end
|
||||
if type(track.external) == 'boolean' and track.external then
|
||||
score = score + 10
|
||||
end
|
||||
|
||||
if best_score == nil or score > best_score then
|
||||
best_score = score
|
||||
best_id = id
|
||||
best_source = source
|
||||
best_selected = selected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if selected_id ~= nil then
|
||||
return selected_id, 'selected', true
|
||||
end
|
||||
if default_id ~= nil then
|
||||
return default_id, 'default', false
|
||||
end
|
||||
if first_id ~= nil then
|
||||
return first_id, 'first', false
|
||||
if best_id ~= nil then
|
||||
return best_id, best_source, best_selected
|
||||
end
|
||||
return nil, nil, false
|
||||
end
|
||||
@@ -4302,6 +4444,12 @@ function FileState:fetch_formats(cb)
|
||||
return
|
||||
end
|
||||
|
||||
if not _is_ytdlp_url(url) then
|
||||
_lua_log('fetch-formats: skipped (yt-dlp unsupported)')
|
||||
if cb then cb(false, 'yt-dlp unsupported url') end
|
||||
return
|
||||
end
|
||||
|
||||
local cached = _get_cached_formats_table(url)
|
||||
if type(cached) == 'table' then
|
||||
_lua_log('fetch-formats: using cached table')
|
||||
@@ -4373,6 +4521,11 @@ local function _prefetch_formats_for_url(url, attempt)
|
||||
if url == '' or not _is_http_url(url) then
|
||||
return
|
||||
end
|
||||
if not _is_ytdlp_url(url) then
|
||||
_formats_prefetch_retries[url] = nil
|
||||
_lua_log('prefetch-formats: skipped (yt-dlp unsupported) url=' .. url)
|
||||
return
|
||||
end
|
||||
attempt = tonumber(attempt or 1) or 1
|
||||
|
||||
local cached = _get_cached_formats_table(url)
|
||||
@@ -5795,6 +5948,11 @@ mp.register_script_message('medios-load-url-event', function(json)
|
||||
_log_all('INFO', 'Load URL started: ' .. url)
|
||||
_lua_log('[LOAD-URL] Starting to load: ' .. url)
|
||||
_set_current_web_url(url)
|
||||
_pending_format_change = nil
|
||||
pcall(mp.set_property, 'options/ytdl-format', '')
|
||||
pcall(mp.set_property, 'file-local-options/ytdl-format', '')
|
||||
pcall(mp.set_property, 'ytdl-format', '')
|
||||
_lua_log('load-url: cleared stale ytdl format reason=load-url')
|
||||
|
||||
local function close_menu()
|
||||
_lua_log('[LOAD-URL] Closing menu and resetting input state')
|
||||
|
||||
Reference in New Issue
Block a user