Fix get_manifest

This commit is contained in:
Nirvana
2025-11-18 15:25:40 +01:00
parent 4a968f2840
commit 96a79aec83
2 changed files with 101 additions and 3 deletions
@@ -0,0 +1,84 @@
# streaming_providers/providers/magenta2/concurrency.py
import urllib.parse
from ...base.network import HTTPManager
from ...base.utils.logger import logger
def extract_and_release_lock(smil_content: str, http_manager: HTTPManager,
client_id: str, user_agent: str) -> bool:
"""
Extract concurrency lock from SMIL and immediately release it
Returns True if lock was found and released, False otherwise
Args:
smil_content: SMIL XML content
http_manager: HTTP manager for making requests
client_id: The client ID used in SMIL request (will be formatted as player_{client_id})
user_agent: Platform-specific user agent
"""
try:
import xml.etree.ElementTree as ET
# Parse SMIL XML
root = ET.fromstring(smil_content)
# Extract head metadata
head = root.find('{http://www.w3.org/2005/SMIL21/Language}head')
if head is None:
return False
# Extract lock parameters
lock_params = {}
for meta in head.findall('{http://www.w3.org/2005/SMIL21/Language}meta'):
name = meta.get('name')
content = meta.get('content')
if name and content:
lock_params[name] = content
# Check if we have all required lock parameters
required_params = ['concurrencyInstance', 'concurrencyServiceUrl', 'lockId', 'lockSequenceToken', 'lock']
if not all(param in lock_params for param in required_params):
logger.debug("SMIL doesn't contain complete concurrency lock")
return False
# Build release URL with the same client_id formatted as player_{client_id}
base_url = lock_params['concurrencyServiceUrl'].rstrip('/') + "/web/Concurrency/release"
formatted_client_id = f"player_{client_id}"
params = {
'schema': '1.0',
'form': 'json',
'_clientId': formatted_client_id, # Use player_{smil_client_id}
'_id': lock_params['lockId'],
'_sequenceToken': urllib.parse.quote(lock_params['lockSequenceToken']),
'_encryptedLock': urllib.parse.quote(lock_params['lock'])
}
param_string = '&'.join([f"{k}={v}" for k, v in params.items()])
release_url = f"{base_url}?{param_string}"
logger.debug(f"Releasing concurrency lock: {lock_params['lockId']} with client: {formatted_client_id}")
headers = {
'User-Agent': user_agent, # Use platform-specific user agent
'Accept': 'application/json'
}
# Release the lock immediately
response = http_manager.get(
release_url,
operation='concurrency_release',
headers=headers,
timeout=10
)
if response.status_code == 200:
logger.info(f"✓ Concurrency lock released successfully with client: {formatted_client_id}")
return True
else:
logger.warning(f"Concurrency lock release failed: {response.status_code}")
return False
except Exception as e:
logger.warning(f"Error releasing concurrency lock: {e}")
return False
@@ -1187,8 +1187,10 @@ class Magenta2Provider(StreamingProvider):
logger.error(f"Error getting SMIL data for channel {channel_id}: {e}")
return None
# In provider.py - update _get_smil_content method
def _get_smil_content(self, channel_id: str) -> Optional[str]:
"""Get SMIL content for a channel to extract releasePid"""
"""Get SMIL content for a channel to extract releasePid and release concurrency lock"""
try:
# Reuse the same logic as get_manifest but return the raw SMIL content
self._ensure_authenticated()
@@ -1204,12 +1206,13 @@ class Magenta2Provider(StreamingProvider):
if not account_pid:
return None
# Use the same client_id as in the original SMIL request
client_id = "a8198f31-b406-4177-8dee-f6216c356c75"
smil_url = f"{selector_service}{account_pid}/media/{channel_id}?format=smil&formats=MPEG-DASH&tracking=true&clientId={client_id}"
headers = {
'Authorization': f'Basic {self.persona_token}',
'User-Agent': self.platform_config['user_agent'],
'User-Agent': self.platform_config['user_agent'], # Platform user agent
'Accept': 'application/smil+xml, application/xml;q=0.9, */*;q=0.8'
}
@@ -1221,7 +1224,18 @@ class Magenta2Provider(StreamingProvider):
)
if response.status_code == 200:
return response.text
smil_content = response.text
# RELEASE CONCURRENCY LOCK IMMEDIATELY AFTER GETTING SMIL
from .concurrency import extract_and_release_lock
extract_and_release_lock(
smil_content,
self.http_manager,
client_id=client_id, # Use the same client_id as SMIL request
user_agent=self.platform_config['user_agent'] # Platform user agent
)
return smil_content
else:
logger.error(f"Failed to get SMIL content for DRM: {response.status_code}")
return None