diff --git a/db/config.py b/db/config.py index a462efa..2530f67 100644 --- a/db/config.py +++ b/db/config.py @@ -36,6 +36,7 @@ class Settings(BaseSettings): sport_video_scheduler_crontab: str = "20 * * * *" streamed_scheduler_crontab: str = "*/15 * * * *" meta_cache_ttl: int = 1800 # 30 minutes + validate_m3u8_urls_liveness: bool = True class Config: env_file = ".env" diff --git a/docs/configuration.md b/docs/configuration.md index 48ff60b..1470be1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -22,6 +22,7 @@ This guide describes the environment variables available in MediaFusion for conf - **is_scrap_from_torrentio** (default: `False`): Enable or disable scraping from Torrentio. - **enable_rate_limit** (default: `True`): Enable or disable rate limiting. - **meta_cache_ttl** (default: `1800`): The time-to-live (TTL) for cached metadata, in seconds. +- **validate_m3u8_urls_liveness** (default: `True`): Enable or disable the validation of M3U8 URLs for liveness. If enabled, the URLs are checked for liveness before returning them. #### Security and Authentication diff --git a/utils/parser.py b/utils/parser.py index 32a366e..4c3e744 100644 --- a/utils/parser.py +++ b/utils/parser.py @@ -48,6 +48,7 @@ from streaming_providers.torbox.utils import ( ) from utils import const from utils.network import get_redirector_url +from utils.validation_helper import validate_m3u8_url ia = Cinemagoer() ADULT_CONTENT_KEYWORDS = re.compile( @@ -325,7 +326,13 @@ async def parse_tv_stream_data(tv_streams: list[TVStreams]) -> list[Stream]: if stream_link is None: continue stream.url = stream_link + elif settings.validate_m3u8_urls_liveness: + is_working, _ = await validate_m3u8_url(stream.url, stream.behaviorHints) + if not is_working: + continue + country_info = f"\n🌐 {stream.country}" if stream.country else "" + stream_list.append( Stream( name="MediaFusion", diff --git a/utils/validation_helper.py b/utils/validation_helper.py index be1bc26..fb2e0a9 100644 --- a/utils/validation_helper.py +++ b/utils/validation_helper.py @@ -32,8 +32,10 @@ async def validate_image_url(url: str) -> bool: return await is_valid_url(url) and await does_url_exist(url) -async def validate_m3u8_url(url: str, behaviour_hint: dict) -> (bool, bool): - if not await is_valid_url(url): +async def validate_m3u8_url( + url: str, behaviour_hint: dict, validate_url: bool = False +) -> (bool, bool): + if validate_url and not await is_valid_url(url): return False, False headers = behaviour_hint.get("proxyHeaders", {}).get("request", {}) @@ -101,6 +103,7 @@ async def validate_tv_metadata(metadata: schemas.TVMetaData) -> list[schemas.TVS stream.behaviorHints.model_dump(exclude_none=True) if stream.behaviorHints else {}, + validate_url=True, ) ) elif stream.ytId: