diff --git a/lib/streaming_providers/providers/magenta2/config_models.py b/lib/streaming_providers/providers/magenta2/config_models.py index 099b3a4..a87b026 100644 --- a/lib/streaming_providers/providers/magenta2/config_models.py +++ b/lib/streaming_providers/providers/magenta2/config_models.py @@ -147,6 +147,33 @@ class MpxConfig: # Fallback to constructed format return "http://access.auth.theplatform.com/data/Account/2709353023" +@dataclass +class ImageConfig: + """Image scaling configuration from manifest""" + scaling_base_url: Optional[str] = None + scaling_call_parameter: Optional[str] = None + + @classmethod + def from_manifest_data(cls, manifest_data: Dict[str, Any]) -> 'ImageConfig': + """Create ImageConfig from manifest data""" + + def get_param(key: str) -> Optional[str]: + """Helper to get value from parameters array""" + if 'settings' not in manifest_data: + return None + settings = manifest_data['settings'] + if 'parameters' not in settings: + return None + for param in settings['parameters']: + if param.get('key') == key: + value = param.get('value') + return value if value and value != 'unused' else None + return None + + return cls( + scaling_base_url=get_param('imageScalingBasicUrl'), + scaling_call_parameter=get_param('imageScalingCallParameter') + ) @dataclass class DrmConfig: @@ -267,6 +294,7 @@ class ManifestConfig: mpx: MpxConfig drm: DrmConfig tv_hubs: TvHubConfig + image_config: ImageConfig youbora_config: Dict[str, Any] = field(default_factory=dict) npvr_config: Dict[str, Any] = field(default_factory=dict) raw_data: Dict[str, Any] = field(default_factory=dict) @@ -278,6 +306,7 @@ class ManifestConfig: mpx=MpxConfig.from_manifest_data(manifest_data), drm=DrmConfig.from_manifest_data(manifest_data), tv_hubs=TvHubConfig.from_manifest_data(manifest_data), + image_config=ImageConfig.from_manifest_data(manifest_data), youbora_config=manifest_data.get('youbora', {}), npvr_config=manifest_data.get('npvr', {}), raw_data=manifest_data diff --git a/lib/streaming_providers/providers/magenta2/provider.py b/lib/streaming_providers/providers/magenta2/provider.py index a45ea16..ff8de36 100644 --- a/lib/streaming_providers/providers/magenta2/provider.py +++ b/lib/streaming_providers/providers/magenta2/provider.py @@ -622,19 +622,25 @@ class Magenta2Provider(StreamingProvider): continue # Extract logo URLs from station info - logo_url = None + original_logo_url = None if station_info: thumbnails = station_info.get('thumbnails', {}) if 'stationLogo' in thumbnails: - logo_url = thumbnails['stationLogo'].get('url') + original_logo_url = thumbnails['stationLogo'].get('url') elif 'stationLogoColored' in thumbnails: - logo_url = thumbnails['stationLogoColored'].get('url') + original_logo_url = thumbnails['stationLogoColored'].get('url') - # Create channel object with clean title (no channel number, no quality suffix) + # BUILD SCALED LOGO URL + logo_url = None + if original_logo_url: + logo_url = self._build_scaled_image_url(original_logo_url) + logger.debug(f"Logo URL scaled: {original_logo_url} -> {logo_url}") + + # Create channel object with scaled logo URL magenta2_channel = Magenta2Channel( - name=title, # Clean title like "RNF HD" - channel_id=channel_id, # Correct ID from era$mediaPids - logo_url=logo_url, + name=title, + channel_id=channel_id, + logo_url=logo_url, # Use scaled URL mode=MODE_LIVE, content_type=CONTENT_TYPE_LIVE, country=self.country, @@ -687,6 +693,42 @@ class Magenta2Provider(StreamingProvider): logger.warning(f"Error extracting channel ID from entry: {e}") return None + def _build_scaled_image_url(self, original_url: str) -> Optional[str]: + """Build scaled image URL using image scaling service""" + if not original_url: + return None + + if not self.provider_config or not self.provider_config.manifest: + return original_url # Fallback to original URL + + image_config = self.provider_config.manifest.image_config + + # Check if we have the required scaling parameters + if not image_config.scaling_base_url or not image_config.scaling_call_parameter: + return original_url + + # Parse the call parameter (e.g., "client=ftp22") + call_params = {} + for param in image_config.scaling_call_parameter.split('&'): + if '=' in param: + key, value = param.split('=', 1) + call_params[key] = value + + # Build the scaling URL + base_url = image_config.scaling_base_url.rstrip('/') + + # Add required parameters + params = { + **call_params, # client=ftp22 + 'ar': 'keep', # aspect ratio + 'src': original_url # original image URL + } + + # Build query string + query_string = '&'.join([f"{k}={self._url_encode(v)}" for k, v in params.items()]) + + return f"{base_url}/iss?{query_string}" + def fetch_channels(self, time_window_hours: int = DEFAULT_EPG_WINDOW_HOURS, fetch_manifests: bool = False, @@ -715,6 +757,8 @@ class Magenta2Provider(StreamingProvider): if not url: url = "https://feed.entertainment.tv.theplatform.eu/f/mdeprod/mdeprod-channel-stations-main" + url += "?lang=short-de&sort=dt%24displayChannelNumber&range=1-1000" + logger.debug(f"Fetching channels from: {url}") response = self.http_manager.get( url,