From efe4044f404730c905503ef1c977932ad4b6c6ae Mon Sep 17 00:00:00 2001 From: Nirvana Date: Fri, 27 Feb 2026 18:37:16 +0100 Subject: [PATCH] Add discovery --- .../providers/rtlplus/constants.py | 30 ++++++++++++++++++- .../providers/rtlplus/provider.py | 4 +-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/streaming_providers/providers/rtlplus/constants.py b/lib/streaming_providers/providers/rtlplus/constants.py index 955c87d..3338804 100644 --- a/lib/streaming_providers/providers/rtlplus/constants.py +++ b/lib/streaming_providers/providers/rtlplus/constants.py @@ -21,6 +21,13 @@ class RTLPlusDefaults: # User Agent components USER_AGENT = f"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{CHROME_VERSION} Safari/537.36" + # PlayReady-specific user agent (Edge/Windows as seen in license acquisition requests) + PLAYREADY_EDGE_VERSION = "145.0.0.0" + PLAYREADY_USER_AGENT = f"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{PLAYREADY_EDGE_VERSION} Safari/537.36 Edg/{PLAYREADY_EDGE_VERSION}" + + # PlayReady SOAP action for license acquisition + PLAYREADY_SOAP_ACTION = "http://schemas.microsoft.com/DRM/2007/03/protocols/AcquireLicense" + # API endpoints AUTH_BASE_URL = "https://auth.rtl.de/auth/realms/rtlplus/protocol/openid-connect" AUTH_ENDPOINT = f"{AUTH_BASE_URL}/token" @@ -104,7 +111,7 @@ class RTLPlusHeaders: @staticmethod def get_drm_headers(access_token: str, device_id: str = None, user_agent: str = None) -> dict: - """Get headers for DRM license requests""" + """Get headers for Widevine/FairPlay DRM license requests""" return { "X-Auth-Token": access_token, "X-Device-Id": device_id or RTLPlusDefaults.DEVICE_ID, @@ -114,6 +121,20 @@ class RTLPlusHeaders: "Referer": RTLPlusDefaults.BASE_WEBSITE, } + @staticmethod + def get_playready_drm_headers(access_token: str, device_id: str = None) -> dict: + """Get headers for PlayReady DRM license acquisition (SOAP/XML)""" + return { + "Content-Type": "text/xml; charset=UTF-8", + "Origin": RTLPlusDefaults.BASE_WEBSITE.rstrip("/"), + "Referer": RTLPlusDefaults.BASE_WEBSITE, + "SOAPAction": RTLPlusDefaults.PLAYREADY_SOAP_ACTION, + "User-Agent": RTLPlusDefaults.PLAYREADY_USER_AGENT, + "X-Auth-Token": access_token, + "X-Device-Id": device_id or RTLPlusDefaults.DEVICE_ID, + "X-Device-Name": RTLPlusDefaults.DEVICE_NAME, + } + class RTLPlusConfig: """Configuration class that can be customized per instance""" @@ -168,3 +189,10 @@ class RTLPlusConfig: device_id=self.device_id, user_agent=self.user_agent, ) + + def get_playready_drm_headers(self, access_token: str) -> dict: + """Get PlayReady-specific DRM headers (Edge UA, SOAP content-type)""" + return RTLPlusHeaders.get_playready_drm_headers( + access_token=access_token, + device_id=self.device_id, + ) \ No newline at end of file diff --git a/lib/streaming_providers/providers/rtlplus/provider.py b/lib/streaming_providers/providers/rtlplus/provider.py index b3121ad..a40719e 100644 --- a/lib/streaming_providers/providers/rtlplus/provider.py +++ b/lib/streaming_providers/providers/rtlplus/provider.py @@ -388,7 +388,7 @@ class RTLPlusProvider(StreamingProvider): DRMSystem.PLAYREADY, 2, license_url, - self.rtl_config.get_drm_headers(access_token), + self.rtl_config.get_playready_drm_headers(access_token), ) ) elif license_info.get("type") == "FAIRPLAY": @@ -428,4 +428,4 @@ class RTLPlusProvider(StreamingProvider): if drm_configs: # Return the first license URL found return drm_configs[0].license.server_url - return None + return None \ No newline at end of file