added mhtml support and fixed some bugs in the process

This commit is contained in:
2026-04-22 21:19:55 -07:00
parent 90787bd0a2
commit 67c272db4b
9 changed files with 564 additions and 66 deletions
+111 -15
View File
@@ -1996,6 +1996,37 @@ function M._suspicious_ytdl_format_reason(fmt, url, raw)
end
end
if fmt:match('^%d+%-%d+$') and type(raw) == 'table' and type(raw.formats) == 'table' then
for _, item in ipairs(raw.formats) do
if type(item) == 'table' and trim(tostring(item.format_id or '')) == fmt then
local protocol = trim(tostring(item.protocol or '')):lower()
local size_bytes = item.filesize or item.filesize_approx
local vcodec = tostring(item.vcodec or 'none')
local acodec = tostring(item.acodec or 'none')
if (protocol == 'm3u8' or protocol == 'm3u8_native')
and not size_bytes
and vcodec ~= 'none'
and acodec ~= 'none' then
return 'format is transient hls variant selector'
end
break
end
end
end
if fmt:match('^%d+%-%w+$') and type(raw) == 'table' and type(raw.formats) == 'table' then
for _, item in ipairs(raw.formats) do
if type(item) == 'table' and trim(tostring(item.format_id or '')) == fmt then
local vcodec = tostring(item.vcodec or 'none')
local acodec = tostring(item.acodec or 'none')
if vcodec == 'none' and acodec ~= 'none' then
return 'format is unstable audio variant selector'
end
break
end
end
end
return nil
end
@@ -4485,11 +4516,62 @@ local function _is_browseable_raw_format(fmt)
return false
end
local protocol = trim(tostring(fmt.protocol or '')):lower()
local size_bytes = fmt.filesize or fmt.filesize_approx
if protocol ~= ''
and (protocol == 'm3u8' or protocol == 'm3u8_native')
and format_id:match('^%d+%-%d+$')
and not size_bytes then
local hls_vcodec = tostring(fmt.vcodec or 'none')
local hls_acodec = tostring(fmt.acodec or 'none')
if hls_vcodec ~= 'none' and hls_acodec ~= 'none' then
return false
end
end
local vcodec = tostring(fmt.vcodec or 'none')
local acodec = tostring(fmt.acodec or 'none')
return not (vcodec == 'none' and acodec == 'none')
end
function M._raw_format_display_id(fmt)
local format_id = trim(tostring(fmt and fmt.format_id or ''))
if format_id == '' then
return ''
end
local vcodec = tostring(fmt and fmt.vcodec or 'none')
local acodec = tostring(fmt and fmt.acodec or 'none')
if vcodec == 'none' and acodec ~= 'none' then
local base = format_id:match('^(%d+)%-%w+$')
if base and base ~= '' then
return base
end
end
return format_id
end
function M._raw_format_selection_id(fmt)
local display_id = M._raw_format_display_id(fmt)
if display_id == '' then
return ''
end
local vcodec = tostring(fmt and fmt.vcodec or 'none')
local acodec = tostring(fmt and fmt.acodec or 'none')
if vcodec ~= 'none' and acodec == 'none' then
return display_id .. '+ba'
end
return display_id
end
function M._raw_format_picker_score(fmt)
local note = trim(tostring(fmt and (fmt.format_note or fmt.format) or '')):lower()
local format_id = trim(tostring(fmt and fmt.format_id or '')):lower()
local prefers_original = (note:find('original', 1, true) or note:find('default', 1, true)) and 1 or 0
local avoids_drc = (format_id:find('-drc', 1, true) or note:find('drc', 1, true)) and 0 or 1
local magnitude = tonumber(fmt and (fmt.filesize or fmt.filesize_approx or fmt.abr or fmt.tbr) or 0) or 0
return prefers_original * 1000000000000 + avoids_drc * 1000000000 + magnitude
end
local function _build_formats_table_from_raw_info(url, raw)
if raw == nil then
raw = mp.get_property_native('ytdl-raw-info')
@@ -4505,10 +4587,12 @@ local function _build_formats_table_from_raw_info(url, raw)
local rows = {}
local browseable_count = 0
local seen_selection_ids = {}
for _, fmt in ipairs(formats) do
if _is_browseable_raw_format(fmt) then
browseable_count = browseable_count + 1
local format_id = trim(tostring(fmt.format_id or ''))
local display_id = M._raw_format_display_id(fmt)
local resolution = trim(tostring(fmt.resolution or ''))
if resolution == '' then
local width = tonumber(fmt.width)
@@ -4522,25 +4606,37 @@ local function _build_formats_table_from_raw_info(url, raw)
local ext = trim(tostring(fmt.ext or ''))
local size = _format_bytes_compact(fmt.filesize or fmt.filesize_approx)
local vcodec = tostring(fmt.vcodec or 'none')
local acodec = tostring(fmt.acodec or 'none')
local selection_id = format_id
if vcodec ~= 'none' and acodec == 'none' then
selection_id = format_id .. '+ba'
local selection_id = M._raw_format_selection_id(fmt)
if selection_id ~= '' then
local candidate = {
columns = {
{ name = 'ID', value = display_id ~= '' and display_id or format_id },
{ name = 'Resolution', value = resolution },
{ name = 'Ext', value = ext },
{ name = 'Size', value = size },
},
selection_args = { '-format', selection_id },
_picker_score = M._raw_format_picker_score(fmt),
}
local existing_index = seen_selection_ids[selection_id]
if existing_index then
local existing = rows[existing_index]
local existing_score = tonumber(existing and existing._picker_score or 0) or 0
if candidate._picker_score > existing_score then
rows[existing_index] = candidate
end
else
rows[#rows + 1] = candidate
seen_selection_ids[selection_id] = #rows
end
end
rows[#rows + 1] = {
columns = {
{ name = 'ID', value = format_id },
{ name = 'Resolution', value = resolution },
{ name = 'Ext', value = ext },
{ name = 'Size', value = size },
},
selection_args = { '-format', selection_id },
}
end
end
for _, row in ipairs(rows) do
row._picker_score = nil
end
if browseable_count == 0 then
return { title = 'Formats', rows = {} }, nil
end
+4 -6
View File
@@ -68,6 +68,7 @@ from SYS.logger import set_debug, debug, set_thread_stream # noqa: E402
from SYS.repl_queue import enqueue_repl_command # noqa: E402
from SYS.utils import format_bytes # noqa: E402
from ProviderCore.registry import get_plugin, get_plugin_class # noqa: E402
from tool.ytdlp import get_display_format_id, get_selection_format_id # noqa: E402
REQUEST_PROP = "user-data/medeia-pipeline-request"
RESPONSE_PROP = "user-data/medeia-pipeline-response"
@@ -1028,6 +1029,7 @@ def _run_op(op: str, data: Any) -> Dict[str, Any]:
format_id = str(fmt.get("format_id") or "").strip()
if not format_id:
continue
display_id = get_display_format_id(fmt) or format_id
# Prefer human-ish resolution.
resolution = str(fmt.get("resolution") or "").strip()
@@ -1045,11 +1047,7 @@ def _run_op(op: str, data: Any) -> Dict[str, Any]:
ext = str(fmt.get("ext") or "").strip()
size = _format_bytes(fmt.get("filesize") or fmt.get("filesize_approx"))
vcodec = str(fmt.get("vcodec") or "none")
acodec = str(fmt.get("acodec") or "none")
selection_id = format_id
if vcodec != "none" and acodec == "none":
selection_id = f"{format_id}+ba"
selection_id = get_selection_format_id(fmt, video_audio_suffix="ba") or format_id
# Build selection args compatible with MPV Lua picker.
# Use -format instead of -query so Lua can extract the ID easily.
@@ -1060,7 +1058,7 @@ def _run_op(op: str, data: Any) -> Dict[str, Any]:
"columns": [
{
"name": "ID",
"value": format_id
"value": display_id
},
{
"name": "Resolution",