updating and refining plugin system refactor
This commit is contained in:
+1
-1
@@ -493,7 +493,7 @@ def _maybe_download_hydrus_file(item: Any,
|
||||
"""
|
||||
try:
|
||||
from SYS.config import get_hydrus_access_key, get_hydrus_url
|
||||
from API.HydrusNetwork import HydrusNetwork as HydrusClient, download_hydrus_file
|
||||
from plugins.hydrusnetwork.api import HydrusNetwork as HydrusClient, download_hydrus_file
|
||||
|
||||
# Prefer per-item Hydrus instance name when it matches a configured instance.
|
||||
store_name = None
|
||||
|
||||
+189
-117
@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
from pathlib import Path
|
||||
from SYS.cmdlet_spec import Cmdlet, CmdletArg, parse_cmdlet_args
|
||||
from ProviderCore.registry import get_plugin_for_url
|
||||
from ProviderCore.registry import get_plugin, get_plugin_for_url
|
||||
from SYS.logger import debug, get_thread_stream, is_debug_enabled, set_debug, set_thread_stream
|
||||
from SYS.result_table import Table
|
||||
from MPV.mpv_ipc import MPV
|
||||
@@ -32,6 +32,13 @@ _IPV4_RE = re.compile(r"^\d+\.\d+\.\d+\.\d+$")
|
||||
_MPD_PATH_RE = re.compile(r"\.mpd($|\?)")
|
||||
|
||||
|
||||
def _get_hydrus_provider(config: Optional[Dict[str, Any]] = None) -> Any:
|
||||
try:
|
||||
return get_plugin("hydrusnetwork", config or {})
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _repo_root() -> Path:
|
||||
try:
|
||||
return Path(__file__).resolve().parent.parent
|
||||
@@ -575,20 +582,51 @@ def _send_ipc_command(command: Dict[str, Any], silent: bool = False, wait: bool
|
||||
return None
|
||||
|
||||
|
||||
def _extract_store_and_hash(item: Any) -> tuple[Optional[str], Optional[str]]:
|
||||
def _extract_store_and_hash(
|
||||
item: Any,
|
||||
*,
|
||||
config: Optional[Dict[str, Any]] = None,
|
||||
) -> tuple[Optional[str], Optional[str]]:
|
||||
store: Optional[str] = None
|
||||
file_hash: Optional[str] = None
|
||||
targets: list[str] = []
|
||||
|
||||
def _add_target(value: Any) -> None:
|
||||
text = str(value or "").strip()
|
||||
if text:
|
||||
targets.append(text)
|
||||
|
||||
try:
|
||||
if isinstance(item, dict):
|
||||
store = item.get("store")
|
||||
file_hash = item.get("hash") or item.get("file_hash")
|
||||
_add_target(item.get("path"))
|
||||
_add_target(item.get("url"))
|
||||
_add_target(item.get("filename"))
|
||||
metadata = item.get("full_metadata") or item.get("metadata")
|
||||
else:
|
||||
store = getattr(item, "store", None)
|
||||
file_hash = getattr(item, "hash", None) or getattr(item, "file_hash", None)
|
||||
_add_target(getattr(item, "path", None))
|
||||
_add_target(getattr(item, "url", None))
|
||||
metadata = getattr(item, "full_metadata", None) or getattr(item, "metadata", None)
|
||||
except Exception:
|
||||
store = None
|
||||
file_hash = None
|
||||
metadata = None
|
||||
|
||||
if isinstance(metadata, dict):
|
||||
try:
|
||||
if not store:
|
||||
store = metadata.get("store")
|
||||
if not file_hash or str(file_hash).strip().lower() in {"unknown", "none", "n/a", "na"}:
|
||||
file_hash = metadata.get("hash") or metadata.get("hash_hex")
|
||||
_add_target(metadata.get("path"))
|
||||
_add_target(metadata.get("url"))
|
||||
_add_target(metadata.get("selection_url"))
|
||||
_add_target(metadata.get("hydrus_url"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
store = str(store).strip() if store else None
|
||||
@@ -600,17 +638,37 @@ def _extract_store_and_hash(item: Any) -> tuple[Optional[str], Optional[str]]:
|
||||
except Exception:
|
||||
file_hash = None
|
||||
|
||||
hydrus_provider = _get_hydrus_provider(config)
|
||||
if hydrus_provider is not None:
|
||||
normalized_store = None
|
||||
try:
|
||||
if store and hydrus_provider.is_store_name(store):
|
||||
normalized_store = store
|
||||
except Exception:
|
||||
normalized_store = None
|
||||
|
||||
for target in targets:
|
||||
try:
|
||||
parsed_store, parsed_hash = hydrus_provider.parse_hydrus_url(target)
|
||||
except Exception:
|
||||
parsed_store, parsed_hash = None, ""
|
||||
if parsed_hash and not file_hash:
|
||||
file_hash = parsed_hash
|
||||
if parsed_store:
|
||||
normalized_store = parsed_store
|
||||
|
||||
if normalized_store:
|
||||
store = normalized_store
|
||||
elif store and store.upper() in {"PATH", "LOCAL", "UNKNOWN"}:
|
||||
store = None
|
||||
|
||||
if not file_hash:
|
||||
try:
|
||||
text = None
|
||||
if isinstance(item, dict):
|
||||
text = item.get("path") or item.get("url") or item.get("filename")
|
||||
else:
|
||||
text = getattr(item, "path", None) or getattr(item, "url", None)
|
||||
if text:
|
||||
for text in targets:
|
||||
m = _SHA256_RE.search(str(text).lower())
|
||||
if m:
|
||||
file_hash = m.group(0)
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -681,6 +739,8 @@ def _prefetch_notes_async(
|
||||
set_notes_prefetch_pending(store, file_hash, True)
|
||||
|
||||
registry = Store(cfg, suppress_debug=True)
|
||||
if not registry.is_available(str(store)):
|
||||
return
|
||||
backend = registry[str(store)]
|
||||
notes = backend.get_note(str(file_hash), config=cfg) or {}
|
||||
store_cached_notes(store, file_hash, notes)
|
||||
@@ -718,7 +778,7 @@ def _schedule_notes_prefetch(items: Sequence[Any], config: Optional[Dict[str, An
|
||||
seen: set[str] = set()
|
||||
scheduled = 0
|
||||
for item in items or []:
|
||||
store, file_hash = _extract_store_and_hash(item)
|
||||
store, file_hash = _extract_store_and_hash(item, config=config)
|
||||
if not store or not file_hash:
|
||||
continue
|
||||
key = f"{store.lower()}:{file_hash}"
|
||||
@@ -789,7 +849,12 @@ def _extract_target_from_memory_uri(text: str) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def _find_hydrus_instance_for_hash(hash_str: str, file_storage: Any) -> Optional[str]:
|
||||
def _find_hydrus_instance_for_hash(
|
||||
hash_str: str,
|
||||
file_storage: Any,
|
||||
*,
|
||||
config: Optional[Dict[str, Any]] = None,
|
||||
) -> Optional[str]:
|
||||
"""Find which Hydrus instance serves a specific file hash.
|
||||
|
||||
Args:
|
||||
@@ -799,27 +864,29 @@ def _find_hydrus_instance_for_hash(hash_str: str, file_storage: Any) -> Optional
|
||||
Returns:
|
||||
Instance name (e.g., 'home') or None if not found
|
||||
"""
|
||||
# Query each Hydrus backend to see if it has this file
|
||||
for backend_name in file_storage.list_backends():
|
||||
backend = file_storage[backend_name]
|
||||
# Check if this is a Hydrus backend by checking class name
|
||||
backend_class = type(backend).__name__
|
||||
if backend_class != "HydrusNetwork":
|
||||
continue
|
||||
hydrus_provider = _get_hydrus_provider(config)
|
||||
if hydrus_provider is None:
|
||||
return None
|
||||
|
||||
try:
|
||||
# Query metadata to see if this instance has the file
|
||||
metadata = backend.get_metadata(hash_str)
|
||||
if metadata:
|
||||
return backend_name
|
||||
except Exception:
|
||||
# This instance doesn't have the file or had an error
|
||||
continue
|
||||
try:
|
||||
for backend_name, _backend in hydrus_provider.iter_backends():
|
||||
try:
|
||||
if hydrus_provider.hash_exists(hash_str, store_name=str(backend_name)):
|
||||
return str(backend_name)
|
||||
except Exception:
|
||||
continue
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _find_hydrus_instance_by_url(url: str, file_storage: Any) -> Optional[str]:
|
||||
def _find_hydrus_instance_by_url(
|
||||
url: str,
|
||||
file_storage: Any,
|
||||
*,
|
||||
config: Optional[Dict[str, Any]] = None,
|
||||
) -> Optional[str]:
|
||||
"""Find which Hydrus instance matches a given URL.
|
||||
|
||||
Args:
|
||||
@@ -829,31 +896,13 @@ def _find_hydrus_instance_by_url(url: str, file_storage: Any) -> Optional[str]:
|
||||
Returns:
|
||||
Instance name (e.g., 'home') or None if not found
|
||||
"""
|
||||
from urllib.parse import urlparse
|
||||
|
||||
parsed_target = urlparse(url)
|
||||
target_netloc = parsed_target.netloc.lower()
|
||||
|
||||
# Check each Hydrus backend's URL
|
||||
for backend_name in file_storage.list_backends():
|
||||
backend = file_storage[backend_name]
|
||||
backend_class = type(backend).__name__
|
||||
if backend_class != "HydrusNetwork":
|
||||
continue
|
||||
|
||||
# Get the backend's base URL from its client
|
||||
try:
|
||||
backend_url = backend._client.base_url
|
||||
parsed_backend = urlparse(backend_url)
|
||||
backend_netloc = parsed_backend.netloc.lower()
|
||||
|
||||
# Match by netloc (host:port)
|
||||
if target_netloc == backend_netloc:
|
||||
return backend_name
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
return None
|
||||
hydrus_provider = _get_hydrus_provider(config)
|
||||
if hydrus_provider is None:
|
||||
return None
|
||||
try:
|
||||
return hydrus_provider.match_store_name_for_url(url)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _normalize_playlist_path(text: Optional[str]) -> Optional[str]:
|
||||
@@ -891,7 +940,8 @@ def _normalize_playlist_path(text: Optional[str]) -> Optional[str]:
|
||||
def _infer_store_from_playlist_item(
|
||||
item: Dict[str,
|
||||
Any],
|
||||
file_storage: Optional[Any] = None
|
||||
file_storage: Optional[Any] = None,
|
||||
config: Optional[Dict[str, Any]] = None,
|
||||
) -> str:
|
||||
"""Infer a friendly store label from an MPV playlist entry.
|
||||
|
||||
@@ -915,7 +965,7 @@ def _infer_store_from_playlist_item(
|
||||
# If we have file_storage, query each Hydrus instance to find which one has this hash
|
||||
if file_storage:
|
||||
hash_str = target.lower()
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage)
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage, config=config)
|
||||
if hydrus_instance:
|
||||
return hydrus_instance
|
||||
return "hydrus"
|
||||
@@ -929,7 +979,7 @@ def _infer_store_from_playlist_item(
|
||||
hash_match = _SHA256_RE.search(target.lower())
|
||||
if hash_match:
|
||||
hash_str = hash_match.group(0)
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage)
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage, config=config)
|
||||
if hydrus_instance:
|
||||
return hydrus_instance
|
||||
return "hydrus"
|
||||
@@ -968,11 +1018,11 @@ def _infer_store_from_playlist_item(
|
||||
hash_match = _HASH_QUERY_RE.search(target.lower())
|
||||
if hash_match:
|
||||
hash_str = hash_match.group(1)
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage)
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage, config=config)
|
||||
if hydrus_instance:
|
||||
return hydrus_instance
|
||||
# If no hash in URL, try matching the base URL to configured instances
|
||||
hydrus_instance = _find_hydrus_instance_by_url(target, file_storage)
|
||||
hydrus_instance = _find_hydrus_instance_by_url(target, file_storage, config=config)
|
||||
if hydrus_instance:
|
||||
return hydrus_instance
|
||||
return "hydrus"
|
||||
@@ -982,10 +1032,10 @@ def _infer_store_from_playlist_item(
|
||||
hash_match = _HASH_QUERY_RE.search(target.lower())
|
||||
if hash_match:
|
||||
hash_str = hash_match.group(1)
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage)
|
||||
hydrus_instance = _find_hydrus_instance_for_hash(hash_str, file_storage, config=config)
|
||||
if hydrus_instance:
|
||||
return hydrus_instance
|
||||
hydrus_instance = _find_hydrus_instance_by_url(target, file_storage)
|
||||
hydrus_instance = _find_hydrus_instance_by_url(target, file_storage, config=config)
|
||||
if hydrus_instance:
|
||||
return hydrus_instance
|
||||
return "hydrus"
|
||||
@@ -1320,6 +1370,16 @@ def _get_playable_path(
|
||||
elif isinstance(item, str):
|
||||
path = item
|
||||
|
||||
if not store or not file_hash or str(file_hash).strip().lower() == "unknown":
|
||||
try:
|
||||
extracted_store, extracted_hash = _extract_store_and_hash(item, config=config)
|
||||
except Exception:
|
||||
extracted_store, extracted_hash = None, None
|
||||
if extracted_store and not store:
|
||||
store = extracted_store
|
||||
if extracted_hash and (not file_hash or str(file_hash).strip().lower() == "unknown"):
|
||||
file_hash = extracted_hash
|
||||
|
||||
# Debug: show incoming values
|
||||
try:
|
||||
debug(f"_get_playable_path: store={store}, path={path}, hash={file_hash}")
|
||||
@@ -1384,6 +1444,7 @@ def _get_playable_path(
|
||||
# - MPV IPC pipe (transport)
|
||||
# - PipeObject (pipeline data)
|
||||
backend_target_resolved = False
|
||||
hydrus_provider = _get_hydrus_provider(config)
|
||||
if store and file_hash and file_hash != "unknown" and file_storage:
|
||||
try:
|
||||
backend = file_storage[store]
|
||||
@@ -1391,18 +1452,14 @@ def _get_playable_path(
|
||||
backend = None
|
||||
|
||||
if backend is not None:
|
||||
backend_class = type(backend).__name__
|
||||
backend_target_resolved = True
|
||||
|
||||
# HydrusNetwork: build a playable API file URL without browser side-effects.
|
||||
if backend_class == "HydrusNetwork":
|
||||
# Hydrus playback should resolve via the provider so store aliases and URL building stay centralized.
|
||||
if hydrus_provider is not None and hydrus_provider.is_backend(backend, str(store)):
|
||||
try:
|
||||
client = getattr(backend, "_client", None)
|
||||
base_url = getattr(client, "url", None)
|
||||
if base_url:
|
||||
base_url = str(base_url).rstrip("/")
|
||||
# Auth is provided via http-header-fields (set in _queue_items).
|
||||
path = f"{base_url}/get_files/file?hash={file_hash}"
|
||||
resolved_path = hydrus_provider.build_file_url(file_hash, store_name=str(store))
|
||||
if resolved_path:
|
||||
path = resolved_path
|
||||
except Exception as e:
|
||||
debug(
|
||||
f"Error building Hydrus URL from store '{store}': {e}",
|
||||
@@ -1570,32 +1627,43 @@ def _queue_items(
|
||||
item_store = None
|
||||
if isinstance(item, dict):
|
||||
item_store = item.get("store")
|
||||
metadata = item.get("full_metadata") or item.get("metadata")
|
||||
else:
|
||||
item_store = getattr(item, "store", None)
|
||||
metadata = getattr(item, "full_metadata", None) or getattr(item, "metadata", None)
|
||||
|
||||
if not item_store and isinstance(metadata, dict):
|
||||
item_store = metadata.get("store")
|
||||
|
||||
if not item_store:
|
||||
item_store, _ = _extract_store_and_hash(item, config=config)
|
||||
|
||||
if item_store:
|
||||
item_store_name = str(item_store).strip() or None
|
||||
|
||||
if item_store and file_storage:
|
||||
try:
|
||||
backend = file_storage[str(item_store)]
|
||||
except Exception:
|
||||
backend = None
|
||||
|
||||
if backend is not None and type(backend).__name__ == "HydrusNetwork":
|
||||
client = getattr(backend, "_client", None)
|
||||
base_url = getattr(client, "url", None)
|
||||
key = getattr(client, "access_key", None)
|
||||
if base_url:
|
||||
effective_hydrus_url = str(base_url).rstrip("/")
|
||||
if key:
|
||||
effective_hydrus_header = (
|
||||
f"Hydrus-Client-API-Access-Key: {str(key).strip()}"
|
||||
)
|
||||
effective_ytdl_opts = _build_ytdl_options(
|
||||
config,
|
||||
effective_hydrus_header
|
||||
if item_store_name and file_storage:
|
||||
hydrus_provider = _get_hydrus_provider(config)
|
||||
if hydrus_provider is not None:
|
||||
try:
|
||||
client = hydrus_provider.get_client(
|
||||
store_name=item_store_name,
|
||||
allow_default=False,
|
||||
)
|
||||
except Exception:
|
||||
client = None
|
||||
if client is not None:
|
||||
base_url = getattr(client, "url", None)
|
||||
key = getattr(client, "access_key", None)
|
||||
if base_url:
|
||||
effective_hydrus_url = str(base_url).rstrip("/")
|
||||
if key:
|
||||
effective_hydrus_header = (
|
||||
f"Hydrus-Client-API-Access-Key: {str(key).strip()}"
|
||||
)
|
||||
effective_ytdl_opts = _build_ytdl_options(
|
||||
config,
|
||||
effective_hydrus_header
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1608,6 +1676,10 @@ def _queue_items(
|
||||
f"{effective_hydrus_url.rstrip('/')}/get_files/file?hash={str(target).strip()}"
|
||||
)
|
||||
|
||||
hydrus_target = bool(
|
||||
effective_hydrus_header and _is_hydrus_path(str(target), effective_hydrus_url)
|
||||
)
|
||||
|
||||
norm_key = _normalize_playlist_path(target) or str(target).strip().lower()
|
||||
if norm_key in existing_targets or norm_key in new_targets:
|
||||
debug(f"Skipping duplicate playlist entry: {title or target}")
|
||||
@@ -1616,10 +1688,11 @@ def _queue_items(
|
||||
|
||||
# Use memory:// M3U hack to pass title to MPV.
|
||||
# Avoid this for probable ytdl URLs because it can prevent the hook from triggering.
|
||||
if title and not _is_probable_ytdl_url(target):
|
||||
safe_title = title.replace("\n", " ").replace("\r", "") if title else None
|
||||
if title and hydrus_target:
|
||||
target_to_send = target
|
||||
elif title and not _is_probable_ytdl_url(target):
|
||||
# Sanitize title for M3U (remove newlines)
|
||||
safe_title = title.replace("\n", " ").replace("\r", "")
|
||||
|
||||
# Carry the store name for hash URLs so MPV.lyric can resolve the backend.
|
||||
# This is especially important for local file-server URLs like /get_files/file?hash=...
|
||||
target_for_m3u = target
|
||||
@@ -1646,15 +1719,14 @@ def _queue_items(
|
||||
# so MPV.lyric can resolve the correct backend for notes.
|
||||
if mode == "replace":
|
||||
try:
|
||||
s, h = _extract_store_and_hash(item)
|
||||
s, h = _extract_store_and_hash(item, config=config)
|
||||
_set_mpv_item_context(s, h)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# If this is a Hydrus path, set header property and yt-dlp headers before loading.
|
||||
# Use the real target (not the memory:// wrapper) for detection.
|
||||
if effective_hydrus_header and _is_hydrus_path(str(target),
|
||||
effective_hydrus_url):
|
||||
if hydrus_target:
|
||||
header_cmd = {
|
||||
"command":
|
||||
["set_property",
|
||||
@@ -1683,10 +1755,18 @@ def _queue_items(
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
load_options: Dict[str, str] = {}
|
||||
if hydrus_target and command_name == "loadfile":
|
||||
load_options["ytdl"] = "no"
|
||||
if safe_title:
|
||||
load_options["force-media-title"] = safe_title
|
||||
|
||||
command_args: List[Any] = [command_name, target_to_send, mode]
|
||||
if load_options:
|
||||
command_args.extend([-1, load_options])
|
||||
|
||||
cmd = {
|
||||
"command": [command_name,
|
||||
target_to_send,
|
||||
mode],
|
||||
"command": command_args,
|
||||
"request_id": 200
|
||||
}
|
||||
try:
|
||||
@@ -2159,7 +2239,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
|
||||
# Prefer the store/hash from the piped item when auto-playing.
|
||||
try:
|
||||
s, h = _extract_store_and_hash(items_to_add[0])
|
||||
s, h = _extract_store_and_hash(items_to_add[0], config=config)
|
||||
_set_mpv_item_context(s, h)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -2293,7 +2373,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
else:
|
||||
# Play item
|
||||
try:
|
||||
s, h = _extract_store_and_hash(item)
|
||||
s, h = _extract_store_and_hash(item, config=config)
|
||||
_set_mpv_item_context(s, h)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -2376,26 +2456,17 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
# Extract the real path/URL from memory:// wrapper if present
|
||||
real_path = _extract_target_from_memory_uri(filename) or filename
|
||||
|
||||
# Try to extract hash from the path/URL
|
||||
file_hash = None
|
||||
store_name = None
|
||||
# Try to extract hash/store from the path/URL via provider-aware normalization.
|
||||
store_name, file_hash = _extract_store_and_hash(
|
||||
{
|
||||
"path": real_path,
|
||||
"title": title,
|
||||
},
|
||||
config=config,
|
||||
)
|
||||
|
||||
# Check if it's a Hydrus URL
|
||||
if "get_files/file" in real_path or "hash=" in real_path:
|
||||
# Extract hash from Hydrus URL
|
||||
hash_match = _HASH_QUERY_RE.search(real_path.lower())
|
||||
if hash_match:
|
||||
file_hash = hash_match.group(1)
|
||||
# Try to find which Hydrus instance has this file
|
||||
if file_storage:
|
||||
store_name = _find_hydrus_instance_for_hash(
|
||||
file_hash,
|
||||
file_storage
|
||||
)
|
||||
if not store_name:
|
||||
store_name = "hydrus"
|
||||
# Check if it's a hash-based local file
|
||||
elif real_path:
|
||||
if not file_hash and real_path:
|
||||
# Try to extract hash from filename (e.g., C:\path\1e8c46...a1b2.mp4)
|
||||
path_obj = Path(real_path)
|
||||
stem = path_obj.stem # filename without extension
|
||||
@@ -2407,7 +2478,8 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
if not store_name:
|
||||
store_name = _infer_store_from_playlist_item(
|
||||
item,
|
||||
file_storage=file_storage
|
||||
file_storage=file_storage,
|
||||
config=config,
|
||||
)
|
||||
|
||||
# Build PipeObject with proper metadata
|
||||
@@ -2651,7 +2723,7 @@ def _start_mpv(
|
||||
# target change (the helper may start before playback begins).
|
||||
try:
|
||||
if items:
|
||||
s, h = _extract_store_and_hash(items[0])
|
||||
s, h = _extract_store_and_hash(items[0], config=config)
|
||||
_set_mpv_item_context(s, h)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user