mirror of
https://github.com/nirvana-7777/script.service.ultimate.git
synced 2026-09-18 23:22:38 +02:00
129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
# streaming_providers/base/models/channel.py
|
|
from dataclasses import dataclass
|
|
from typing import Dict, List, Optional
|
|
|
|
from .content import Content
|
|
from .quality import Quality
|
|
from ..utils.logger import logger
|
|
|
|
|
|
@dataclass
|
|
class Channel(Content):
|
|
"""
|
|
Represents a continuously available live channel or VOD stream.
|
|
"""
|
|
|
|
channel_number: Optional[int] = None
|
|
is_radio: bool = False
|
|
catchup_hours: Optional[int] = None
|
|
|
|
def __post_init__(self):
|
|
self._validate_fields()
|
|
if self.is_radio and self.content_type == "LIVE":
|
|
self.content_type = "RADIO"
|
|
self.quality = "AUDIO"
|
|
|
|
def _validate_fields(self):
|
|
if self.mode == "vod" and self.content_type == "LIVE":
|
|
logger.warning(
|
|
f"Channel {self.name} ({self.content_id}): "
|
|
f"VOD mode with LIVE content_type - consider changing to VOD"
|
|
)
|
|
if self.session_manifest and self.manifest:
|
|
logger.warning(
|
|
f"Channel {self.name} ({self.content_id}): "
|
|
f"session_manifest=True but manifest URL is set - manifest will be ignored"
|
|
)
|
|
|
|
# Backward compatibility alias
|
|
@property
|
|
def channel_id(self) -> str:
|
|
return self.content_id
|
|
|
|
@channel_id.setter
|
|
def channel_id(self, value: str):
|
|
self.content_id = value
|
|
|
|
def to_dict(self) -> Dict:
|
|
result = super().to_dict()
|
|
result["ChannelNumber"] = self.channel_number
|
|
result["IsRadio"] = self.is_radio
|
|
result["CatchupHours"] = self.catchup_hours
|
|
return result
|
|
|
|
def is_audio_content(self) -> bool:
|
|
return self.is_radio
|
|
|
|
def detect_and_set_radio(self) -> None:
|
|
if self.is_radio:
|
|
return
|
|
radio_indicators = [
|
|
self.name.lower().startswith("radio"),
|
|
"radio" in self.name.lower(),
|
|
self.quality in ["audio", "aac", "mp3", "AUDIO"],
|
|
self.description and "radio" in self.description.lower(),
|
|
self.genre and "radio" in self.genre.lower(),
|
|
]
|
|
if any(radio_indicators):
|
|
self.is_radio = True
|
|
if not self.quality or self.quality.upper() not in [q for q in vars(Quality).values() if isinstance(q, str)]:
|
|
self.quality = "AUDIO"
|
|
if self.content_type == "LIVE":
|
|
self.content_type = "RADIO"
|
|
|
|
def validate(self) -> List[str]:
|
|
warnings = []
|
|
if not self.manifest and not self.manifest_script:
|
|
warnings.append("No manifest URL or manifest script provided")
|
|
if self.license_url and not self.drm_config:
|
|
warnings.append("License URL provided but no DRM configuration")
|
|
if self.mode == "vod" and self.content_type == "LIVE":
|
|
warnings.append("VOD mode should not have LIVE content_type")
|
|
if self.is_radio and self.quality not in ["AUDIO", "audio", None]:
|
|
warnings.append(f"Radio channel has video quality setting: {self.quality}")
|
|
return warnings
|
|
|
|
# Factory methods
|
|
@classmethod
|
|
def create_live_channel(
|
|
cls, name: str, channel_id: str, provider: str, **kwargs
|
|
) -> "Channel":
|
|
return cls(
|
|
name=name,
|
|
content_id=channel_id,
|
|
provider=provider,
|
|
mode="live",
|
|
content_type="LIVE",
|
|
**kwargs,
|
|
)
|
|
|
|
@classmethod
|
|
def create_vod_channel(
|
|
cls, name: str, content_id: str, provider: str, **kwargs
|
|
) -> "Channel":
|
|
return cls(
|
|
name=name,
|
|
content_id=content_id,
|
|
provider=provider,
|
|
mode="vod",
|
|
content_type="VOD",
|
|
**kwargs,
|
|
)
|
|
|
|
@classmethod
|
|
def create_radio_channel(
|
|
cls, name: str, channel_id: str, provider: str, **kwargs
|
|
) -> "Channel":
|
|
return cls(
|
|
name=name,
|
|
content_id=channel_id,
|
|
provider=provider,
|
|
is_radio=True,
|
|
content_type="RADIO",
|
|
quality="AUDIO",
|
|
**kwargs,
|
|
)
|
|
|
|
|
|
# Backward compatibility alias — all existing code using StreamingChannel continues to work
|
|
StreamingChannel = Channel |