This commit is contained in:
2026-02-10 23:00:30 -08:00
parent c2449d0ba7
commit 5323b7c76f
6 changed files with 192 additions and 104 deletions

View File

@@ -253,76 +253,6 @@ class PlaywrightTool:
)
def config_schema() -> List[Dict[str, Any]]:
"""Return a schema describing editable Playwright tool defaults for the config UI.
Notes:
- `user_agent` is a dropdown with a `custom` option; put the real UA in
`user_agent_custom` when choosing `custom`.
- Viewport dimensions are offered as convenient choices.
- `ffmpeg_path` intentionally defaults to empty; Playwright will consult
a global `FFMPEG_PATH` environment variable (or fallback to bundled/system).
"""
_defaults = PlaywrightDefaults()
browser_choices = ["chromium", "firefox", "webkit"]
viewport_width_choices = [1920, 1366, 1280, 1024, 800]
viewport_height_choices = [1080, 900, 768, 720, 600]
return [
{
"key": "browser",
"label": "Playwright browser",
"default": _defaults.browser,
"choices": browser_choices,
},
{
"key": "headless",
"label": "Headless",
"default": str(_defaults.headless),
"choices": ["true", "false"],
},
{
"key": "user_agent",
"label": "User Agent",
"default": "default",
"choices": ["default", "native", "custom"],
},
{
"key": "user_agent_custom",
"label": "Custom User Agent (used when User Agent = custom)",
"default": "",
},
{
"key": "viewport_width",
"label": "Viewport width",
"default": _defaults.viewport_width,
"choices": viewport_width_choices,
},
{
"key": "viewport_height",
"label": "Viewport height",
"default": _defaults.viewport_height,
"choices": viewport_height_choices,
},
{
"key": "navigation_timeout_ms",
"label": "Navigation timeout (ms)",
"default": _defaults.navigation_timeout_ms,
},
{
"key": "ignore_https_errors",
"label": "Ignore HTTPS errors",
"default": str(_defaults.ignore_https_errors),
"choices": ["true", "false"],
},
{
"key": "ffmpeg_path",
"label": "FFmpeg path (leave empty to use global/bundled)",
"default": "",
},
]
def require(self) -> None:
"""Ensure Playwright is present; raise a helpful RuntimeError if not."""
try:
@@ -635,3 +565,74 @@ def config_schema() -> List[Dict[str, Any]]:
except Exception:
pass
return None
def config_schema() -> List[Dict[str, Any]]:
"""Return a schema describing editable Playwright tool defaults for the config UI.
Notes:
- `user_agent` is a dropdown with a `custom` option; put the real UA in
`user_agent_custom` when choosing `custom`.
- Viewport dimensions are offered as convenient choices.
- `ffmpeg_path` intentionally defaults to empty; Playwright will consult
a global `FFMPEG_PATH` environment variable (or fallback to bundled/system).
"""
_defaults = PlaywrightDefaults()
browser_choices = ["chromium", "firefox", "webkit"]
viewport_width_choices = [1920, 1366, 1280, 1024, 800]
viewport_height_choices = [1080, 900, 768, 720, 600]
return [
{
"key": "browser",
"label": "Playwright browser",
"default": _defaults.browser,
"choices": browser_choices,
},
{
"key": "headless",
"label": "Headless",
"default": str(_defaults.headless),
"choices": ["true", "false"],
},
{
"key": "user_agent",
"label": "User Agent",
"default": "default",
"choices": ["default", "native", "custom"],
},
{
"key": "user_agent_custom",
"label": "Custom User Agent (used when User Agent = custom)",
"default": "",
},
{
"key": "viewport_width",
"label": "Viewport width",
"default": _defaults.viewport_width,
"choices": viewport_width_choices,
},
{
"key": "viewport_height",
"label": "Viewport height",
"default": _defaults.viewport_height,
"choices": viewport_height_choices,
},
{
"key": "navigation_timeout_ms",
"label": "Navigation timeout (ms)",
"default": _defaults.navigation_timeout_ms,
},
{
"key": "ignore_https_errors",
"label": "Ignore HTTPS errors",
"default": str(_defaults.ignore_https_errors),
"choices": ["true", "false"],
},
{
"key": "ffmpeg_path",
"label": "FFmpeg path (leave empty to use global/bundled)",
"default": "",
},
]

View File

@@ -770,8 +770,8 @@ class YtDlpTool:
"""Resolve numeric heights (720, 1080p) to yt-dlp height selectors.
Examples:
"720" -> "bv*[height<=720]+ba"
"1080p" -> "bv*[height<=1080]+ba"
"720" -> "bestvideo[height<=720]+bestaudio/best[height<=720]"
"1080p" -> "bestvideo[height<=1080]+bestaudio/best[height<=1080]"
"""
if not format_str or not isinstance(format_str, str):
return None
@@ -783,10 +783,33 @@ class YtDlpTool:
# Strip trailing 'p' if present (e.g. 720p -> 720)
if s.endswith('p'):
s = s[:-1]
# Heuristic: 240/360/480/720/1080/1440/2160 are common height inputs
# But small IDs like 18, 22, 137 are format IDs.
# YouTube Format IDs are usually 2-3 digits.
# Heights are also 3-4 digits.
# "240" is ambiguous (Format 240 vs Height 240).
# We assume common video heights are intended as heights.
if s.isdigit():
height = int(s)
if height >= 144:
return f"bv*[height<={height}]+ba"
val = int(s)
# Common video heights that overlap with format IDs:
# - None currently overlap with common legacy itag IDs (17,18,22,34-38,43-46)
# or dash video IDs (133-137, 160, 242-248, 264, 271, 278, 298-315...).
# - 240, 360, 480, 720, 1080, 1440, 2160
#
# Format 240 is likely not a thing (242, 243, ... exist).
# Format 480 ... none in common lists.
# Format 720 ... none.
# So if it looks like a standard resolution, treat as height constraint.
if val in {144, 240, 360, 480, 540, 720, 1080, 1440, 2160, 2880, 4320}:
return f"bestvideo[height<={val}]+bestaudio/best[height<={val}]"
# If user types something like 500, we can also treat as height constraint if > 100
if val >= 100 and val not in {133, 134, 135, 136, 137, 160, 242, 243, 244, 247, 248, 278, 394, 395, 396, 397, 398, 399}:
return f"bestvideo[height<={val}]+bestaudio/best[height<={val}]"
return None
def _load_defaults(self) -> YtDlpDefaults: