Files
script.service.ultimate/lib/streaming_providers/providers/joyn/models.py
T
2026-01-16 12:24:41 +01:00

214 lines
6.0 KiB
Python

# streaming_providers/providers/joyn/models.py
import json
from dataclasses import dataclass, field
from typing import Dict, Optional
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__()