Files
script.service.ultimate/lib/streaming_providers/providers/joyn/models.py
T
2025-10-29 20:23:50 +01:00

203 lines
6.0 KiB
Python

# streaming_providers/providers/joyn/models.py
from dataclasses import dataclass, field
from typing import Dict, Optional
import json
from ...base.models import StreamingChannel
class PlaybackRestrictedException(Exception):
"""
Exception raised when content playback is restricted
"""
pass
@dataclass
class JoynChannel:
"""
Represents a Joyn channel with all necessary streaming data
"""
# Core identification
name: str
channel_id: str
# Visual elements
logo_url: Optional[str] = None
# Streaming configuration
mode: str = "live" # "live" or "vod"
session_manifest: bool = False
manifest: Optional[str] = None
manifest_script: Optional[str] = None
# CDM (Content Decryption Module) settings
cdm_type: Optional[str] = None
use_cdm: bool = True
cdm: Optional[str] = None # Usually "pid={pid}"
cdm_mode: str = 'external'
# Video settings
video: str = 'best'
on_demand: bool = True
speed_up: bool = True
# Additional metadata
content_type: str = 'LIVE' # 'LIVE' or 'VOD'
description: Optional[str] = None
genre: Optional[str] = None
language: str = 'de'
country: str = 'DE'
# Streaming data
license_url: Optional[str] = None
certificate_url: Optional[str] = None
streaming_format: Optional[str] = None
# Internal tracking
raw_data: Dict = field(default_factory=dict)
@classmethod
def from_api_data(cls, api_data: Dict, **kwargs) -> 'JoynChannel':
"""
Create JoynChannel from API response data
Args:
api_data: Raw API response data
**kwargs: Additional parameters to override defaults
Returns:
JoynChannel instance
"""
channel = cls(
name=api_data.get('title', 'Unknown Channel'),
channel_id=api_data.get('id', ''),
content_type=api_data.get('type', 'LIVE'),
raw_data=api_data.copy()
)
# Apply any additional parameters
for key, value in kwargs.items():
if hasattr(channel, key):
setattr(channel, key, value)
return channel
def set_streaming_data(self, manifest: str, cdm_type: str = None,
pid: str = None, license_url: str = None,
certificate_url: str = None, streaming_format: str = None) -> None:
"""
Configure streaming-specific data
Args:
manifest: Manifest URL for streaming
cdm_type: Content decryption module type
pid: Program ID for CDM
license_url: License URL for DRM
certificate_url: Certificate URL for DRM
streaming_format: Streaming format (e.g., 'dash')
"""
self.manifest = manifest
if cdm_type:
self.cdm_type = cdm_type
if pid:
self.cdm = f"pid={pid}"
if license_url:
self.license_url = license_url
if certificate_url:
self.certificate_url = certificate_url
if streaming_format:
self.streaming_format = streaming_format
def set_logo(self, logo_url: str) -> None:
"""Set channel logo URL"""
self.logo_url = logo_url
def set_metadata(self, description: str = None, genre: str = None) -> None:
"""Set additional metadata"""
if description:
self.description = description
if genre:
self.genre = genre
def is_live(self) -> bool:
"""Check if channel is live TV"""
return self.content_type == 'LIVE' and self.mode == 'live'
def is_vod(self) -> bool:
"""Check if channel is video on demand"""
return self.content_type == 'VOD' or self.mode == 'vod'
def to_streaming_channel(self, provider_name: str = 'joyn') -> StreamingChannel:
"""
Convert to generic StreamingChannel object
Args:
provider_name: Provider name to set
Returns:
StreamingChannel instance
"""
return StreamingChannel(
name=self.name,
channel_id=self.channel_id,
provider=provider_name,
logo_url=self.logo_url,
mode=self.mode,
session_manifest=self.session_manifest,
manifest=self.manifest,
manifest_script=self.manifest_script,
cdm_type=self.cdm_type,
use_cdm=self.use_cdm,
cdm=self.cdm,
cdm_mode=self.cdm_mode,
video=self.video,
on_demand=self.on_demand,
speed_up=self.speed_up,
content_type=self.content_type,
description=self.description,
genre=self.genre,
language=self.language,
country=self.country,
license_url=self.license_url,
certificate_url=self.certificate_url,
streaming_format=self.streaming_format
)
def to_dict(self) -> Dict:
"""
Convert to dictionary format matching your output specification
Returns:
Dictionary in the format expected by your application
"""
return {
'Name': self.name,
'LogoUrl': self.logo_url,
'Mode': self.mode,
'SessionManifest': self.session_manifest,
'Manifest': self.manifest,
'ManifestScript': self.manifest_script,
'CdmType': self.cdm_type,
'UseCdm': self.use_cdm,
'Cdm': self.cdm,
'CdmMode': self.cdm_mode,
'Video': self.video,
'OnDemand': self.on_demand,
'SpeedUp': self.speed_up
}
def to_json(self, indent: int = 2) -> str:
"""Convert to JSON string"""
return json.dumps(self.to_dict(), indent=indent, ensure_ascii=False)
def __str__(self) -> str:
return f"JoynChannel(name='{self.name}', id='{self.channel_id}', type='{self.content_type}')"
def __repr__(self) -> str:
return self.__str__()