mirror of
https://github.com/nirvana-7777/script.service.ultimate.git
synced 2026-10-19 06:12:32 +02:00
Reformat
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
# streaming_providers/base/drm/plugin_manager.py
|
||||
"""
|
||||
Manager for DRM configuration plugins with two-phase processing.
|
||||
Handles plugin registration, discovery, and processing of DRM configs with PSSH data.
|
||||
"""
|
||||
|
||||
import traceback
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
@@ -11,7 +16,9 @@ class DRMPluginManager:
|
||||
"""
|
||||
Manager for DRM configuration plugins.
|
||||
|
||||
Handles plugin registration, discovery, and processing of DRM configs with PSSH data.
|
||||
Supports two-phase processing:
|
||||
- Phase 1: GENERIC plugins (config generators, run before provider)
|
||||
- Phase 2: System-specific plugins (config transformers, run after provider)
|
||||
"""
|
||||
|
||||
def __init__(self, auto_discover: bool = True):
|
||||
@@ -51,15 +58,15 @@ class DRMPluginManager:
|
||||
if drm_system in self.plugins:
|
||||
existing_plugin = self.plugins[drm_system].plugin_name
|
||||
logger.warning(
|
||||
f"DRMPluginManager: Registration failed - DRM system {drm_system} already has plugin '{existing_plugin}' registered"
|
||||
)
|
||||
raise ValueError(
|
||||
f"DRM system {drm_system} already has plugin '{existing_plugin}' registered"
|
||||
f"DRMPluginManager: Overwriting existing plugin '{existing_plugin}' "
|
||||
f"with '{plugin_name}' for DRM system {drm_system}"
|
||||
)
|
||||
|
||||
self.plugins[drm_system] = plugin
|
||||
logger.debug(
|
||||
f"DRMPluginManager: Successfully registered plugin '{plugin_name}' for DRM system {drm_system}"
|
||||
phase = "1-GENERIC" if drm_system == DRMSystem.GENERIC else "2-System-specific"
|
||||
logger.info(
|
||||
f"DRMPluginManager: Successfully registered plugin '{plugin_name}' "
|
||||
f"for DRM system {drm_system} (Phase: {phase})"
|
||||
)
|
||||
|
||||
def discover_plugins(self) -> List[str]:
|
||||
@@ -105,9 +112,9 @@ class DRMPluginManager:
|
||||
|
||||
# Only process Python files (not directories or other files)
|
||||
if (
|
||||
filename.endswith(".py")
|
||||
and not filename.startswith("__")
|
||||
and os.path.isfile(file_path)
|
||||
filename.endswith(".py")
|
||||
and not filename.startswith("__")
|
||||
and os.path.isfile(file_path)
|
||||
):
|
||||
|
||||
scanned_files.append(filename)
|
||||
@@ -134,9 +141,9 @@ class DRMPluginManager:
|
||||
for name, obj in inspect.getmembers(module, inspect.isclass):
|
||||
# Check if it's a DRMPlugin subclass (but not DRMPlugin itself)
|
||||
if (
|
||||
issubclass(obj, DRMPlugin)
|
||||
and obj is not DRMPlugin
|
||||
and obj.__module__ == module.__name__
|
||||
issubclass(obj, DRMPlugin)
|
||||
and obj is not DRMPlugin
|
||||
and obj.__module__ == module.__name__
|
||||
):
|
||||
plugin_classes.append((name, obj))
|
||||
|
||||
@@ -193,8 +200,8 @@ class DRMPluginManager:
|
||||
|
||||
# Log final discovery results
|
||||
if registered:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: Filesystem autodiscovery completed successfully - {len(registered)} plugins registered: {registered}"
|
||||
logger.info(
|
||||
f"DRMPluginManager: Filesystem autodiscovery completed - {len(registered)} plugins registered: {registered}"
|
||||
)
|
||||
else:
|
||||
logger.debug(
|
||||
@@ -208,13 +215,221 @@ class DRMPluginManager:
|
||||
|
||||
return registered
|
||||
|
||||
def process_drm_configs(
|
||||
self, drm_configs: List[DRMConfig], pssh_data_list: List[PSSHData], **kwargs
|
||||
def has_generic_plugins(self) -> bool:
|
||||
"""Check if any GENERIC plugins are registered"""
|
||||
return DRMSystem.GENERIC in self.plugins
|
||||
|
||||
def has_system_specific_plugins(self) -> bool:
|
||||
"""Check if any system-specific (non-GENERIC) plugins are registered"""
|
||||
return any(sys != DRMSystem.GENERIC for sys in self.plugins.keys())
|
||||
|
||||
def process_generic_plugins(
|
||||
self,
|
||||
dummy_configs: List[DRMConfig],
|
||||
pssh_data_list: List[PSSHData],
|
||||
**kwargs
|
||||
) -> List[DRMConfig]:
|
||||
"""
|
||||
Process a list of DRM configs through registered plugins using PSSH data.
|
||||
Generic plugins are processed first, and if any ClearKey config is found,
|
||||
only that config is returned.
|
||||
PHASE 1: Process through GENERIC plugins only.
|
||||
|
||||
GENERIC plugins can CREATE configs from PSSH data.
|
||||
They receive a dummy config (DRMSystem.NONE) and PSSH data,
|
||||
and should return valid DRM configs or None.
|
||||
|
||||
Args:
|
||||
dummy_configs: List with dummy config [DRMConfig(system=DRMSystem.NONE)]
|
||||
pssh_data_list: PSSH data extracted from manifest
|
||||
**kwargs: Additional context
|
||||
|
||||
Returns:
|
||||
List of generated DRM configs, or empty list if generation failed
|
||||
"""
|
||||
if not self.has_generic_plugins():
|
||||
logger.debug("Phase 1: No GENERIC plugins registered")
|
||||
return []
|
||||
|
||||
if not pssh_data_list:
|
||||
logger.debug("Phase 1: No PSSH data available for GENERIC plugins")
|
||||
return []
|
||||
|
||||
plugin = self.plugins[DRMSystem.GENERIC]
|
||||
logger.debug(f"Phase 1: Processing with GENERIC plugin '{plugin.plugin_name}'")
|
||||
|
||||
generated_configs = []
|
||||
|
||||
try:
|
||||
# Process each PSSH data entry
|
||||
for pssh_data in pssh_data_list:
|
||||
logger.debug(
|
||||
f"Phase 1: Processing PSSH for system {pssh_data.system_id} "
|
||||
f"with plugin '{plugin.plugin_name}'"
|
||||
)
|
||||
|
||||
# Pass dummy config - plugin should return real config(s) or None
|
||||
result = plugin.process_drm_config(
|
||||
dummy_configs[0], # Dummy config
|
||||
pssh_data,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
if result:
|
||||
generated_configs.append(result)
|
||||
logger.debug(
|
||||
f"Phase 1: Plugin '{plugin.plugin_name}' generated "
|
||||
f"{result.system.value} config"
|
||||
)
|
||||
|
||||
# If ClearKey found, return immediately
|
||||
if result.system == DRMSystem.CLEARKEY:
|
||||
logger.info(
|
||||
f"Phase 1: ClearKey config found from GENERIC plugin, "
|
||||
f"returning immediately"
|
||||
)
|
||||
return [result]
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Phase 1: GENERIC plugin '{plugin.plugin_name}' failed: {e}",
|
||||
exc_info=True
|
||||
)
|
||||
return []
|
||||
|
||||
if generated_configs:
|
||||
logger.info(
|
||||
f"Phase 1: GENERIC plugin generated {len(generated_configs)} configs"
|
||||
)
|
||||
else:
|
||||
logger.debug("Phase 1: GENERIC plugin generated no configs")
|
||||
|
||||
return generated_configs
|
||||
|
||||
def process_system_specific_plugins(
|
||||
self,
|
||||
drm_configs: List[DRMConfig],
|
||||
pssh_data_list: List[PSSHData],
|
||||
**kwargs
|
||||
) -> List[DRMConfig]:
|
||||
"""
|
||||
PHASE 2: Process through system-specific plugins (EXCLUDE GENERIC).
|
||||
|
||||
System-specific plugins TRANSFORM existing configs from the provider.
|
||||
GENERIC plugins are explicitly excluded from this phase.
|
||||
|
||||
Args:
|
||||
drm_configs: DRM configs from the provider
|
||||
pssh_data_list: PSSH data extracted from manifest
|
||||
**kwargs: Additional context
|
||||
|
||||
Returns:
|
||||
List of transformed DRM configs
|
||||
"""
|
||||
if not drm_configs:
|
||||
logger.debug("Phase 2: No DRM configs to process")
|
||||
return []
|
||||
|
||||
# Get system-specific plugins only (exclude GENERIC)
|
||||
system_plugins = {
|
||||
sys: plugin for sys, plugin in self.plugins.items()
|
||||
if sys != DRMSystem.GENERIC
|
||||
}
|
||||
|
||||
if not system_plugins:
|
||||
logger.debug("Phase 2: No system-specific plugins registered, returning provider configs")
|
||||
return drm_configs
|
||||
|
||||
logger.debug(
|
||||
f"Phase 2: Processing {len(drm_configs)} configs through "
|
||||
f"{len(system_plugins)} system-specific plugins"
|
||||
)
|
||||
|
||||
# Create a mapping of DRM system to PSSH data for quick lookup
|
||||
pssh_by_system = {}
|
||||
for pssh_data in pssh_data_list:
|
||||
if pssh_data.drm_system:
|
||||
pssh_by_system[pssh_data.drm_system] = pssh_data
|
||||
logger.debug(
|
||||
f"Phase 2: Mapped PSSH data for DRM system: {pssh_data.drm_system}"
|
||||
)
|
||||
|
||||
processed_configs = []
|
||||
|
||||
# Process each config through matching plugin
|
||||
for config in drm_configs:
|
||||
logger.debug(f"Phase 2: Processing DRM config for system: {config.system}")
|
||||
|
||||
if config.system in system_plugins:
|
||||
plugin = system_plugins[config.system]
|
||||
pssh_data = pssh_by_system.get(config.system)
|
||||
|
||||
if pssh_data:
|
||||
logger.debug(
|
||||
f"Phase 2: Using PSSH data for DRM system {config.system}"
|
||||
)
|
||||
else:
|
||||
logger.debug(
|
||||
f"Phase 2: No PSSH data available for DRM system {config.system}"
|
||||
)
|
||||
|
||||
try:
|
||||
logger.debug(
|
||||
f"Phase 2: Processing with plugin '{plugin.plugin_name}'"
|
||||
)
|
||||
|
||||
result = plugin.process_drm_config(config, pssh_data, **kwargs)
|
||||
|
||||
if result is not None:
|
||||
# Check for ClearKey and return immediately if found
|
||||
if result.system == DRMSystem.CLEARKEY:
|
||||
logger.info(
|
||||
f"Phase 2: ClearKey config found from plugin "
|
||||
f"'{plugin.plugin_name}', returning immediately"
|
||||
)
|
||||
return [result]
|
||||
|
||||
processed_configs.append(result)
|
||||
logger.debug(
|
||||
f"Phase 2: Plugin '{plugin.plugin_name}' successfully "
|
||||
f"processed config"
|
||||
)
|
||||
else:
|
||||
logger.debug(
|
||||
f"Phase 2: Plugin '{plugin.plugin_name}' filtered out config "
|
||||
f"(returned None)"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Phase 2: Plugin '{plugin.plugin_name}' failed to process "
|
||||
f"config: {str(e)}"
|
||||
)
|
||||
# On error, keep original config
|
||||
processed_configs.append(config)
|
||||
logger.debug(f"Phase 2: Using original config as fallback")
|
||||
else:
|
||||
# No plugin for this system, keep original
|
||||
logger.debug(
|
||||
f"Phase 2: No plugin registered for DRM system {config.system}, "
|
||||
f"passing through unchanged"
|
||||
)
|
||||
processed_configs.append(config)
|
||||
|
||||
logger.info(
|
||||
f"Phase 2: Processed {len(drm_configs)} configs → {len(processed_configs)} configs"
|
||||
)
|
||||
return processed_configs
|
||||
|
||||
def process_drm_configs(
|
||||
self,
|
||||
drm_configs: List[DRMConfig],
|
||||
pssh_data_list: List[PSSHData],
|
||||
**kwargs
|
||||
) -> List[DRMConfig]:
|
||||
"""
|
||||
Legacy method: Process configs through all plugins (generic first, then specific).
|
||||
|
||||
This maintains backward compatibility but uses single-phase processing.
|
||||
For new code using two-phase flow, use process_generic_plugins() and
|
||||
process_system_specific_plugins() separately via DRMOperations.
|
||||
|
||||
Args:
|
||||
drm_configs: List of DRM configs to process
|
||||
@@ -229,7 +444,8 @@ class DRMPluginManager:
|
||||
return drm_configs
|
||||
|
||||
logger.debug(
|
||||
f"DRMPluginManager: Processing {len(drm_configs)} DRM configs with {len(pssh_data_list)} PSSH data entries"
|
||||
f"DRMPluginManager: Processing {len(drm_configs)} DRM configs with "
|
||||
f"{len(pssh_data_list)} PSSH data entries (legacy single-phase mode)"
|
||||
)
|
||||
|
||||
# Create a mapping of DRM system to PSSH data for quick lookup
|
||||
@@ -271,8 +487,9 @@ class DRMPluginManager:
|
||||
# Check for ClearKey and return immediately if found
|
||||
for config in temp_configs:
|
||||
if config.system == DRMSystem.CLEARKEY:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: ClearKey config found, returning immediately"
|
||||
logger.info(
|
||||
f"DRMPluginManager: ClearKey config found from generic plugin, "
|
||||
f"returning immediately"
|
||||
)
|
||||
return [config]
|
||||
|
||||
@@ -292,9 +509,10 @@ class DRMPluginManager:
|
||||
# Find specific plugin for this DRM system
|
||||
plugin = self.plugins.get(config.system)
|
||||
|
||||
if plugin:
|
||||
if plugin and plugin.supported_drm_system != DRMSystem.GENERIC:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: Found plugin '{plugin.plugin_name}' for DRM system {config.system}"
|
||||
f"DRMPluginManager: Found plugin '{plugin.plugin_name}' for "
|
||||
f"DRM system {config.system}"
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -305,36 +523,42 @@ class DRMPluginManager:
|
||||
)
|
||||
else:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: No PSSH data available for DRM system {config.system}"
|
||||
f"DRMPluginManager: No PSSH data available for "
|
||||
f"DRM system {config.system}"
|
||||
)
|
||||
|
||||
processed_config = plugin.process_drm_config(config, pssh_data, **kwargs)
|
||||
if processed_config is not None:
|
||||
# Check for ClearKey and return immediately if found
|
||||
if processed_config.system == DRMSystem.CLEARKEY:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: ClearKey config found, returning immediately"
|
||||
logger.info(
|
||||
f"DRMPluginManager: ClearKey config found from plugin "
|
||||
f"'{plugin.plugin_name}', returning immediately"
|
||||
)
|
||||
return [processed_config]
|
||||
|
||||
final_configs.append(processed_config)
|
||||
logger.debug(
|
||||
f"DRMPluginManager: Plugin '{plugin.plugin_name}' successfully processed config"
|
||||
f"DRMPluginManager: Plugin '{plugin.plugin_name}' successfully "
|
||||
f"processed config"
|
||||
)
|
||||
else:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: Plugin '{plugin.plugin_name}' filtered out config (returned None)"
|
||||
f"DRMPluginManager: Plugin '{plugin.plugin_name}' filtered out "
|
||||
f"config (returned None)"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"DRMPluginManager: Plugin '{plugin.plugin_name}' failed to process config: {str(e)}"
|
||||
f"DRMPluginManager: Plugin '{plugin.plugin_name}' failed to process "
|
||||
f"config: {str(e)}"
|
||||
)
|
||||
final_configs.append(config)
|
||||
logger.debug(f"DRMPluginManager: Using original config as fallback")
|
||||
else:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: No plugin registered for DRM system {config.system}, passing through unchanged"
|
||||
f"DRMPluginManager: No plugin registered for DRM system {config.system}, "
|
||||
f"passing through unchanged"
|
||||
)
|
||||
final_configs.append(config)
|
||||
|
||||
@@ -356,21 +580,27 @@ class DRMPluginManager:
|
||||
plugin = self.plugins.get(drm_system)
|
||||
if plugin:
|
||||
logger.debug(
|
||||
f"DRMPluginManager: Retrieved plugin '{plugin.plugin_name}' for DRM system {drm_system}"
|
||||
f"DRMPluginManager: Retrieved plugin '{plugin.plugin_name}' for "
|
||||
f"DRM system {drm_system}"
|
||||
)
|
||||
else:
|
||||
logger.debug(f"DRMPluginManager: No plugin found for DRM system {drm_system}")
|
||||
return plugin
|
||||
|
||||
def list_plugins(self) -> Dict[DRMSystem, str]:
|
||||
def list_plugins(self) -> Dict:
|
||||
"""
|
||||
List all registered plugins.
|
||||
List all registered plugins with phase information.
|
||||
|
||||
Returns:
|
||||
Dictionary mapping DRM systems to plugin names
|
||||
Dictionary mapping DRM system values to plugin info
|
||||
"""
|
||||
plugin_list = {
|
||||
drm_system: plugin.plugin_name for drm_system, plugin in self.plugins.items()
|
||||
drm_system.value: {
|
||||
"name": plugin.plugin_name,
|
||||
"system": drm_system.value,
|
||||
"phase": "1-GENERIC" if drm_system == DRMSystem.GENERIC else "2-System-specific"
|
||||
}
|
||||
for drm_system, plugin in self.plugins.items()
|
||||
}
|
||||
logger.debug(f"DRMPluginManager: Currently registered plugins: {plugin_list}")
|
||||
return plugin_list
|
||||
@@ -379,4 +609,4 @@ class DRMPluginManager:
|
||||
"""Clear all registered plugins"""
|
||||
plugin_count = len(self.plugins)
|
||||
self.plugins.clear()
|
||||
logger.debug(f"DRMPluginManager: Cleared {plugin_count} registered plugins")
|
||||
logger.info(f"DRMPluginManager: Cleared {plugin_count} registered plugins")
|
||||
@@ -2,6 +2,7 @@
|
||||
# streaming_providers/base/drm_operations.py
|
||||
"""
|
||||
DRM-related operations with caching and optimized PSSH extraction.
|
||||
Two-phase plugin processing: GENERIC plugins first, then system-specific.
|
||||
"""
|
||||
|
||||
import time
|
||||
@@ -9,7 +10,7 @@ from threading import Lock
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from .drm import DRMPluginManager
|
||||
from .models import DRMSystem
|
||||
from .models import DRMSystem, DRMConfig
|
||||
from .utils.logger import logger
|
||||
|
||||
|
||||
@@ -82,68 +83,136 @@ class DRMOperations:
|
||||
self.registry = registry
|
||||
self.drm_plugin_manager = DRMPluginManager()
|
||||
self.pssh_cache = PSSHCache(ttl_seconds=cache_ttl)
|
||||
self.drm_config_cache = DRMConfigCache() # New: ClearKey config cache
|
||||
logger.debug("DRMOperations: Initialized with caching")
|
||||
self.drm_config_cache = DRMConfigCache()
|
||||
logger.debug("DRMOperations: Initialized with two-phase plugin processing")
|
||||
|
||||
def get_channel_drm_configs(self, provider_name: str, channel_id: str, **kwargs) -> List:
|
||||
"""Get DRM configurations for a channel."""
|
||||
"""
|
||||
Get DRM configurations for a channel with two-phase plugin processing.
|
||||
|
||||
Phase 1: GENERIC plugins (pre-provider) - can generate configs from PSSH
|
||||
Phase 2: System-specific plugins (post-provider) - transform provider configs
|
||||
"""
|
||||
cache_key = f"{provider_name}:{channel_id}"
|
||||
|
||||
# Check DRM config cache first (ClearKey configs)
|
||||
# Step 1: Check DRM config cache (ClearKey configs)
|
||||
cached_configs = self.drm_config_cache.get(cache_key)
|
||||
if cached_configs is not None:
|
||||
logger.info(f"Using cached DRM configs for '{channel_id}'")
|
||||
return cached_configs
|
||||
|
||||
# Cache miss - get from provider
|
||||
# Step 2: PHASE 1 - Try GENERIC plugins first (if registered)
|
||||
if DRMSystem.GENERIC in self.drm_plugin_manager.plugins:
|
||||
logger.debug(f"Phase 1: Attempting GENERIC plugin processing for '{channel_id}'")
|
||||
|
||||
generic_configs = self._try_generic_plugins(provider_name, channel_id, cache_key, **kwargs)
|
||||
|
||||
if generic_configs: # Plugin successfully generated configs
|
||||
logger.info(f"Phase 1: GENERIC plugin generated {len(generic_configs)} configs for '{channel_id}'")
|
||||
|
||||
# Cache if contains ClearKey
|
||||
if self._has_clearkey_config(generic_configs):
|
||||
logger.info(f"Caching ClearKey DRM configs from GENERIC plugin for '{channel_id}'")
|
||||
self.drm_config_cache.set(cache_key, generic_configs)
|
||||
|
||||
return generic_configs
|
||||
else:
|
||||
logger.debug(f"Phase 1: GENERIC plugin returned no configs, proceeding to provider")
|
||||
|
||||
# Step 3: Get configs from provider (GENERIC plugins didn't provide configs)
|
||||
provider = self.registry.get_provider(provider_name)
|
||||
if not provider:
|
||||
raise ValueError(f"Provider '{provider_name}' not found or disabled")
|
||||
|
||||
drm_configs = provider.get_drm(channel_id, **kwargs)
|
||||
|
||||
# Extract PSSH if needed
|
||||
# Step 4: PHASE 2 - Extract PSSH if needed for system-specific plugins
|
||||
pssh_data_list = []
|
||||
if drm_configs and self.drm_plugin_manager.plugins:
|
||||
if drm_configs and self.drm_plugin_manager.has_system_specific_plugins():
|
||||
if self._needs_pssh_extraction(drm_configs):
|
||||
# Try PSSH cache FIRST before fetching manifest
|
||||
# Try PSSH cache first (might have been fetched in Phase 1)
|
||||
pssh_data_list = self.pssh_cache.get(cache_key)
|
||||
|
||||
if pssh_data_list is None:
|
||||
# Cache miss - now fetch manifest and extract
|
||||
logger.debug(f"PSSH cache miss for {cache_key}, fetching manifest")
|
||||
# Cache miss - fetch manifest and extract
|
||||
logger.debug(f"Phase 2: PSSH cache miss for {cache_key}, fetching manifest")
|
||||
manifest_url = provider.get_manifest(channel_id, **kwargs)
|
||||
if manifest_url:
|
||||
pssh_data_list = self._extract_pssh_from_manifest(manifest_url)
|
||||
if pssh_data_list:
|
||||
self.pssh_cache.set(cache_key, pssh_data_list)
|
||||
else:
|
||||
logger.debug(f"Using cached PSSH for {cache_key}")
|
||||
logger.debug(f"Phase 2: Using cached PSSH for {cache_key}")
|
||||
|
||||
# Process through plugins
|
||||
processed = self.drm_plugin_manager.process_drm_configs(
|
||||
# Step 5: PHASE 2 - Process through system-specific plugins (EXCLUDE GENERIC)
|
||||
processed = self.drm_plugin_manager.process_system_specific_plugins(
|
||||
drm_configs, pssh_data_list, **kwargs
|
||||
)
|
||||
|
||||
# Cache if contains ClearKey config
|
||||
# Step 6: Cache if contains ClearKey config
|
||||
if self._has_clearkey_config(processed):
|
||||
logger.info(f"Caching ClearKey DRM configs for '{channel_id}'")
|
||||
logger.info(f"Caching ClearKey DRM configs from provider for '{channel_id}'")
|
||||
self.drm_config_cache.set(cache_key, processed)
|
||||
|
||||
logger.info(f"Processed DRM for '{channel_id}': {len(processed)} configs")
|
||||
return processed
|
||||
|
||||
def _try_generic_plugins(
|
||||
self,
|
||||
provider_name: str,
|
||||
channel_id: str,
|
||||
cache_key: str,
|
||||
**kwargs
|
||||
) -> Optional[List[DRMConfig]]:
|
||||
"""
|
||||
Try to generate configs using GENERIC plugins.
|
||||
Returns configs if successful, None otherwise.
|
||||
"""
|
||||
# Get PSSH data (from cache or manifest)
|
||||
pssh_data_list = self.pssh_cache.get(cache_key)
|
||||
|
||||
if pssh_data_list is None:
|
||||
logger.debug(f"GENERIC plugin: Fetching PSSH for '{channel_id}'")
|
||||
provider = self.registry.get_provider(provider_name)
|
||||
if not provider:
|
||||
logger.warning(f"Provider '{provider_name}' not found for GENERIC plugin")
|
||||
return None
|
||||
|
||||
manifest_url = provider.get_manifest(channel_id, **kwargs)
|
||||
if manifest_url:
|
||||
pssh_data_list = self._extract_pssh_from_manifest(manifest_url)
|
||||
if pssh_data_list:
|
||||
self.pssh_cache.set(cache_key, pssh_data_list)
|
||||
|
||||
if not pssh_data_list:
|
||||
logger.debug(f"GENERIC plugin: No PSSH data available for '{channel_id}'")
|
||||
return None
|
||||
|
||||
# Create a dummy config to pass to GENERIC plugin
|
||||
dummy_configs = [DRMConfig(system=DRMSystem.NONE, priority=0)]
|
||||
|
||||
# Let GENERIC plugins try to generate configs
|
||||
generic_configs = self.drm_plugin_manager.process_generic_plugins(
|
||||
dummy_configs, pssh_data_list, **kwargs
|
||||
)
|
||||
|
||||
return generic_configs if generic_configs else None
|
||||
|
||||
@staticmethod
|
||||
def _has_clearkey_config(drm_configs: List) -> bool:
|
||||
"""Check if any config is a ClearKey config"""
|
||||
return any(config.system == DRMSystem.CLEARKEY for config in drm_configs)
|
||||
|
||||
def _needs_pssh_extraction(self, drm_configs) -> bool:
|
||||
"""Check if PSSH extraction is needed."""
|
||||
"""Check if PSSH extraction is needed for system-specific plugins."""
|
||||
config_systems = {config.system for config in drm_configs}
|
||||
plugin_systems = set(self.drm_plugin_manager.plugins.keys())
|
||||
# Exclude GENERIC from this check (it's handled separately)
|
||||
plugin_systems = {
|
||||
sys for sys in self.drm_plugin_manager.plugins.keys()
|
||||
if sys != DRMSystem.GENERIC
|
||||
}
|
||||
|
||||
return bool(config_systems & plugin_systems or DRMSystem.GENERIC in plugin_systems)
|
||||
return bool(config_systems & plugin_systems)
|
||||
|
||||
@staticmethod
|
||||
def _extract_pssh_from_manifest(manifest_url: str) -> List:
|
||||
|
||||
@@ -209,18 +209,18 @@ class Sam3Client:
|
||||
# Store refresh token if provided
|
||||
if "refresh_token" in data:
|
||||
new_rt = data["refresh_token"]
|
||||
logger.debug(f"✅ Refresh token received from {operation}")
|
||||
logger.debug(f" New refresh_token: {new_rt}")
|
||||
logger.debug(f" Length: {len(new_rt)} chars")
|
||||
# logger.debug(f"✅ Refresh token received from {operation}")
|
||||
# logger.debug(f" New refresh_token: {new_rt}")
|
||||
# logger.debug(f" Length: {len(new_rt)} chars")
|
||||
|
||||
# Compare with old refresh token if we had one
|
||||
if hasattr(self, 'refresh_token') and self.refresh_token:
|
||||
if self.refresh_token == new_rt:
|
||||
logger.debug(f" ℹ️ Same as previous refresh_token")
|
||||
else:
|
||||
logger.debug(f" 🔄 Different from previous refresh_token")
|
||||
logger.debug(f" Old: {self.refresh_token[:30]}...")
|
||||
logger.debug(f" New: {new_rt[:30]}...")
|
||||
# if hasattr(self, 'refresh_token') and self.refresh_token:
|
||||
# if self.refresh_token == new_rt:
|
||||
# logger.debug(f" ℹ️ Same as previous refresh_token")
|
||||
# else:
|
||||
# logger.debug(f" 🔄 Different from previous refresh_token")
|
||||
# logger.debug(f" Old: {self.refresh_token[:30]}...")
|
||||
# logger.debug(f" New: {new_rt[:30]}...")
|
||||
|
||||
self.refresh_token = new_rt
|
||||
|
||||
|
||||
Reference in New Issue
Block a user