dev: YouTube HD via inputstream.adaptive, DokuStreams Suche fix
This commit is contained in:
@@ -135,7 +135,7 @@ def _videos_from_search_data(data: dict) -> List[str]:
|
||||
|
||||
def _search_with_ytdlp(query: str, count: int = 20) -> List[str]:
|
||||
"""Sucht YouTube-Videos via yt-dlp ytsearch-Extraktor."""
|
||||
if not _ensure_ytdlp_in_path():
|
||||
if not ensure_ytdlp_in_path():
|
||||
return []
|
||||
try:
|
||||
from yt_dlp import YoutubeDL # type: ignore
|
||||
@@ -174,95 +174,7 @@ def _fetch_search_videos(url: str) -> List[str]:
|
||||
return []
|
||||
|
||||
|
||||
def _fix_strptime() -> None:
|
||||
"""Kodi-Workaround: datetime.strptime ist manchmal None."""
|
||||
import datetime as _dt
|
||||
import time as _time
|
||||
if not callable(getattr(_dt.datetime, "strptime", None)):
|
||||
_dt.datetime.strptime = lambda s, f: _dt.datetime(*(_time.strptime(s, f)[0:6]))
|
||||
|
||||
|
||||
def _ensure_ytdlp_in_path() -> bool:
|
||||
"""Fuegt script.module.yt-dlp/lib zum sys.path hinzu falls noetig."""
|
||||
_fix_strptime()
|
||||
try:
|
||||
import yt_dlp # type: ignore # noqa: F401
|
||||
return True
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import sys, os
|
||||
import xbmcvfs # type: ignore
|
||||
lib_path = xbmcvfs.translatePath("special://home/addons/script.module.yt-dlp/lib")
|
||||
if lib_path and os.path.isdir(lib_path) and lib_path not in sys.path:
|
||||
sys.path.insert(0, lib_path)
|
||||
import yt_dlp # type: ignore # noqa: F401
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def _get_quality_format() -> str:
|
||||
"""Liest YouTube-Qualitaet aus den Addon-Einstellungen."""
|
||||
_QUALITY_MAP = {
|
||||
"0": "best[ext=mp4]/best",
|
||||
"1": "bestvideo[height<=1080][ext=mp4]+bestaudio[ext=m4a]/best[height<=1080][ext=mp4]/best",
|
||||
"2": "bestvideo[height<=720][ext=mp4]+bestaudio[ext=m4a]/best[height<=720][ext=mp4]/best",
|
||||
"3": "bestvideo[height<=480][ext=mp4]+bestaudio[ext=m4a]/best[height<=480][ext=mp4]/best",
|
||||
"4": "bestvideo[height<=360][ext=mp4]+bestaudio[ext=m4a]/best[height<=360][ext=mp4]/best",
|
||||
}
|
||||
try:
|
||||
import xbmcaddon # type: ignore
|
||||
val = xbmcaddon.Addon().getSetting("youtube_quality") or "0"
|
||||
return _QUALITY_MAP.get(val, _QUALITY_MAP["0"])
|
||||
except Exception:
|
||||
return _QUALITY_MAP["0"]
|
||||
|
||||
|
||||
def _resolve_with_ytdlp(video_id: str) -> Optional[str]:
|
||||
"""Loest Video-ID via yt-dlp zu direkter Stream-URL auf."""
|
||||
if not _ensure_ytdlp_in_path():
|
||||
_log("[YouTube] yt-dlp nicht verfuegbar (script.module.yt-dlp fehlt)")
|
||||
try:
|
||||
import xbmcgui
|
||||
xbmcgui.Dialog().notification(
|
||||
"yt-dlp fehlt",
|
||||
"Bitte yt-dlp in den ViewIT-Einstellungen installieren.",
|
||||
xbmcgui.NOTIFICATION_ERROR,
|
||||
5000,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
try:
|
||||
from yt_dlp import YoutubeDL # type: ignore
|
||||
except ImportError:
|
||||
return None
|
||||
url = f"https://www.youtube.com/watch?v={video_id}"
|
||||
fmt = _get_quality_format()
|
||||
ydl_opts: Dict[str, Any] = {
|
||||
"format": fmt,
|
||||
"quiet": True,
|
||||
"no_warnings": True,
|
||||
"extract_flat": False,
|
||||
}
|
||||
try:
|
||||
with YoutubeDL(ydl_opts) as ydl:
|
||||
info = ydl.extract_info(url, download=False)
|
||||
if not info:
|
||||
return None
|
||||
# Einzelnes Video
|
||||
direct = info.get("url")
|
||||
if direct:
|
||||
return direct
|
||||
# Formatauswahl
|
||||
formats = info.get("formats", [])
|
||||
if formats:
|
||||
return formats[-1].get("url")
|
||||
except Exception as exc:
|
||||
_log(f"[YouTube] yt-dlp Fehler fuer {video_id}: {exc}")
|
||||
return None
|
||||
from ytdlp_helper import ensure_ytdlp_in_path, resolve_youtube_url
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -306,7 +218,7 @@ class YoutubePlugin(BasisPlugin):
|
||||
video_id = _decode_id(episode) or _decode_id(title)
|
||||
if not video_id:
|
||||
return None
|
||||
return _resolve_with_ytdlp(video_id)
|
||||
return resolve_youtube_url(video_id)
|
||||
|
||||
def resolve_stream_link(self, link: str) -> Optional[str]:
|
||||
return link # bereits direkte URL
|
||||
|
||||
Reference in New Issue
Block a user