mirror of
https://github.com/Viren070/mediaflow-proxy.git
synced 2025-12-01 23:22:12 +01:00
95843cc3c9
Added LiveTVExtractor for extracting M3U8 and MPD streams. Enhanced error handling by introducing ExtractorError and updated existing extractors to use this new error class. Removed support for unused request headers and integrated caching for extractor results.
88 lines
3.1 KiB
Python
88 lines
3.1 KiB
Python
import re
|
|
from urllib import parse
|
|
|
|
from mediaflow_proxy.utils.crypto_utils import encryption_handler
|
|
from mediaflow_proxy.utils.http_utils import encode_mediaflow_proxy_url, get_original_scheme
|
|
|
|
|
|
class M3U8Processor:
|
|
def __init__(self, request, key_url: str = None):
|
|
"""
|
|
Initializes the M3U8Processor with the request and URL prefix.
|
|
|
|
Args:
|
|
request (Request): The incoming HTTP request.
|
|
key_url (HttpUrl, optional): The URL of the key server. Defaults to None.
|
|
"""
|
|
self.request = request
|
|
self.key_url = parse.urlparse(key_url) if key_url else None
|
|
self.mediaflow_proxy_url = str(
|
|
request.url_for("hls_manifest_proxy").replace(scheme=get_original_scheme(request))
|
|
)
|
|
|
|
async def process_m3u8(self, content: str, base_url: str) -> str:
|
|
"""
|
|
Processes the m3u8 content, proxying URLs and handling key lines.
|
|
|
|
Args:
|
|
content (str): The m3u8 content to process.
|
|
base_url (str): The base URL to resolve relative URLs.
|
|
|
|
Returns:
|
|
str: The processed m3u8 content.
|
|
"""
|
|
lines = content.splitlines()
|
|
processed_lines = []
|
|
for line in lines:
|
|
if "URI=" in line:
|
|
processed_lines.append(await self.process_key_line(line, base_url))
|
|
elif not line.startswith("#") and line.strip():
|
|
processed_lines.append(await self.proxy_url(line, base_url))
|
|
else:
|
|
processed_lines.append(line)
|
|
return "\n".join(processed_lines)
|
|
|
|
async def process_key_line(self, line: str, base_url: str) -> str:
|
|
"""
|
|
Processes a key line in the m3u8 content, proxying the URI.
|
|
|
|
Args:
|
|
line (str): The key line to process.
|
|
base_url (str): The base URL to resolve relative URLs.
|
|
|
|
Returns:
|
|
str: The processed key line.
|
|
"""
|
|
uri_match = re.search(r'URI="([^"]+)"', line)
|
|
if uri_match:
|
|
original_uri = uri_match.group(1)
|
|
uri = parse.urlparse(original_uri)
|
|
if self.key_url:
|
|
uri = uri._replace(scheme=self.key_url.scheme, netloc=self.key_url.netloc)
|
|
new_uri = await self.proxy_url(uri.geturl(), base_url)
|
|
line = line.replace(f'URI="{original_uri}"', f'URI="{new_uri}"')
|
|
return line
|
|
|
|
async def proxy_url(self, url: str, base_url: str) -> str:
|
|
"""
|
|
Proxies a URL, encoding it with the MediaFlow proxy URL.
|
|
|
|
Args:
|
|
url (str): The URL to proxy.
|
|
base_url (str): The base URL to resolve relative URLs.
|
|
|
|
Returns:
|
|
str: The proxied URL.
|
|
"""
|
|
full_url = parse.urljoin(base_url, url)
|
|
query_params = dict(self.request.query_params)
|
|
has_encrypted = query_params.pop("has_encrypted", False)
|
|
|
|
return encode_mediaflow_proxy_url(
|
|
self.mediaflow_proxy_url,
|
|
"",
|
|
full_url,
|
|
query_params=dict(self.request.query_params),
|
|
encryption_handler=encryption_handler if has_encrypted else None,
|
|
)
|