57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
import logging
|
|
|
|
import httpx
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def validate_stream(stream_url: str, stream_type: str) -> bool:
|
|
"""Validate that a stream URL is accessible and returns expected content."""
|
|
try:
|
|
if stream_type == "hls":
|
|
response = httpx.get(stream_url, timeout=10, follow_redirects=True)
|
|
if response.status_code != 200:
|
|
logger.warning(
|
|
"HLS playlist returned status %d for %s",
|
|
response.status_code,
|
|
stream_url,
|
|
)
|
|
return False
|
|
|
|
content = response.text
|
|
if ".m3u8" not in content and "#EXTM3U" not in content:
|
|
logger.warning("HLS playlist does not contain expected m3u8 content")
|
|
return False
|
|
|
|
logger.info("HLS stream validated: %s", stream_url)
|
|
return True
|
|
|
|
elif stream_type == "direct":
|
|
response = httpx.head(stream_url, timeout=10, follow_redirects=True)
|
|
if response.status_code not in (200, 206):
|
|
logger.warning(
|
|
"Direct stream returned status %d for %s",
|
|
response.status_code,
|
|
stream_url,
|
|
)
|
|
return False
|
|
|
|
content_type = response.headers.get("content-type", "")
|
|
if not content_type:
|
|
logger.warning("No content-type header for direct stream")
|
|
return False
|
|
|
|
logger.info(
|
|
"Direct stream validated: %s (type: %s)", stream_url, content_type
|
|
)
|
|
return True
|
|
|
|
return False
|
|
|
|
except httpx.TimeoutException:
|
|
logger.error("Timeout validating stream: %s", stream_url)
|
|
return False
|
|
except httpx.RequestError as e:
|
|
logger.error("Error validating stream %s: %s", stream_url, e)
|
|
return False
|