mirror of
https://github.com/UrloMythus/UnHided.git
synced 2026-04-11 11:50:51 +00:00
New version
This commit is contained in:
@@ -43,7 +43,7 @@ class DLHDExtractor(BaseExtractor):
|
||||
channel_headers = {
|
||||
"referer": player_origin + "/",
|
||||
"origin": player_origin,
|
||||
"user-agent": self.base_headers["user-agent"]
|
||||
"user-agent": self.base_headers["user-agent"],
|
||||
}
|
||||
|
||||
channel_response = await self._make_request(channel_url, headers=channel_headers)
|
||||
@@ -52,15 +52,21 @@ class DLHDExtractor(BaseExtractor):
|
||||
if not player_url:
|
||||
raise ExtractorError("Could not extract player URL from channel page")
|
||||
|
||||
# Check if this is a vecloud URL
|
||||
if "vecloud" in player_url:
|
||||
if not re.search(r"/stream/([a-zA-Z0-9-]+)", player_url):
|
||||
iframe_player_url = await self._handle_playnow(player_url, player_origin)
|
||||
player_origin = self._get_origin(player_url)
|
||||
player_url = iframe_player_url
|
||||
|
||||
try:
|
||||
return await self._handle_vecloud(player_url, player_origin + "/")
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
# Get player page to extract authentication information
|
||||
player_headers = {
|
||||
"referer": player_origin + "/",
|
||||
"origin": player_origin,
|
||||
"user-agent": self.base_headers["user-agent"]
|
||||
"user-agent": self.base_headers["user-agent"],
|
||||
}
|
||||
|
||||
player_response = await self._make_request(player_url, headers=player_headers)
|
||||
@@ -89,16 +95,18 @@ class DLHDExtractor(BaseExtractor):
|
||||
raise ExtractorError("Could not determine auth URL base")
|
||||
|
||||
# Construct auth URL
|
||||
auth_url = (f"{auth_url_base}/auth.php?channel_id={auth_data['channel_key']}"
|
||||
f"&ts={auth_data['auth_ts']}&rnd={auth_data['auth_rnd']}"
|
||||
f"&sig={quote(auth_data['auth_sig'])}")
|
||||
auth_url = (
|
||||
f"{auth_url_base}/auth.php?channel_id={auth_data['channel_key']}"
|
||||
f"&ts={auth_data['auth_ts']}&rnd={auth_data['auth_rnd']}"
|
||||
f"&sig={quote(auth_data['auth_sig'])}"
|
||||
)
|
||||
|
||||
# Make auth request
|
||||
player_origin = self._get_origin(player_url)
|
||||
auth_headers = {
|
||||
"referer": player_origin + "/",
|
||||
"origin": player_origin,
|
||||
"user-agent": self.base_headers["user-agent"]
|
||||
"user-agent": self.base_headers["user-agent"],
|
||||
}
|
||||
|
||||
auth_response = await self._make_request(auth_url, headers=auth_headers)
|
||||
@@ -113,14 +121,14 @@ class DLHDExtractor(BaseExtractor):
|
||||
lookup_url_base=player_origin,
|
||||
auth_url_base=auth_url_base,
|
||||
auth_data=auth_data,
|
||||
headers=auth_headers
|
||||
headers=auth_headers,
|
||||
)
|
||||
|
||||
# Set up the final stream headers
|
||||
stream_headers = {
|
||||
"referer": player_url,
|
||||
"origin": player_origin,
|
||||
"user-agent": self.base_headers["user-agent"]
|
||||
"user-agent": self.base_headers["user-agent"],
|
||||
}
|
||||
|
||||
# Return the stream URL with headers
|
||||
@@ -144,12 +152,17 @@ class DLHDExtractor(BaseExtractor):
|
||||
"""
|
||||
try:
|
||||
# Extract stream ID from vecloud URL
|
||||
stream_id_match = re.search(r'/stream/([a-zA-Z0-9-]+)', player_url)
|
||||
stream_id_match = re.search(r"/stream/([a-zA-Z0-9-]+)", player_url)
|
||||
if not stream_id_match:
|
||||
raise ExtractorError("Could not extract stream ID from vecloud URL")
|
||||
|
||||
stream_id = stream_id_match.group(1)
|
||||
|
||||
response = await self._make_request(
|
||||
player_url, headers={"referer": channel_referer, "user-agent": self.base_headers["user-agent"]}
|
||||
)
|
||||
player_url = str(response.url)
|
||||
|
||||
# Construct API URL
|
||||
player_parsed = urlparse(player_url)
|
||||
player_domain = player_parsed.netloc
|
||||
@@ -161,13 +174,10 @@ class DLHDExtractor(BaseExtractor):
|
||||
"referer": player_url,
|
||||
"origin": player_origin,
|
||||
"user-agent": self.base_headers["user-agent"],
|
||||
"content-type": "application/json"
|
||||
"content-type": "application/json",
|
||||
}
|
||||
|
||||
api_data = {
|
||||
"r": channel_referer,
|
||||
"d": player_domain
|
||||
}
|
||||
api_data = {"r": channel_referer, "d": player_domain}
|
||||
|
||||
# Make API request
|
||||
api_response = await self._make_request(api_url, method="POST", headers=api_headers, json=api_data)
|
||||
@@ -187,7 +197,7 @@ class DLHDExtractor(BaseExtractor):
|
||||
stream_headers = {
|
||||
"referer": player_origin + "/",
|
||||
"origin": player_origin,
|
||||
"user-agent": self.base_headers["user-agent"]
|
||||
"user-agent": self.base_headers["user-agent"],
|
||||
}
|
||||
|
||||
# Return the stream URL with headers
|
||||
@@ -200,14 +210,24 @@ class DLHDExtractor(BaseExtractor):
|
||||
except Exception as e:
|
||||
raise ExtractorError(f"Vecloud extraction failed: {str(e)}")
|
||||
|
||||
async def _handle_playnow(self, player_iframe: str, channel_origin: str) -> str:
|
||||
"""Handle playnow URLs."""
|
||||
# Set up headers for the playnow request
|
||||
playnow_headers = {"referer": channel_origin + "/", "user-agent": self.base_headers["user-agent"]}
|
||||
|
||||
# Make the playnow request
|
||||
playnow_response = await self._make_request(player_iframe, headers=playnow_headers)
|
||||
player_url = self._extract_player_url(playnow_response.text)
|
||||
if not player_url:
|
||||
raise ExtractorError("Could not extract player URL from playnow response")
|
||||
return player_url
|
||||
|
||||
def _extract_player_url(self, html_content: str) -> Optional[str]:
|
||||
"""Extract player iframe URL from channel page HTML."""
|
||||
try:
|
||||
# Look for iframe with allowfullscreen attribute
|
||||
iframe_match = re.search(
|
||||
r'<iframe[^>]*src=["\']([^"\']+)["\'][^>]*allowfullscreen',
|
||||
html_content,
|
||||
re.IGNORECASE
|
||||
r'<iframe[^>]*src=["\']([^"\']+)["\'][^>]*allowfullscreen', html_content, re.IGNORECASE
|
||||
)
|
||||
|
||||
if not iframe_match:
|
||||
@@ -215,7 +235,7 @@ class DLHDExtractor(BaseExtractor):
|
||||
iframe_match = re.search(
|
||||
r'<iframe[^>]*src=["\']([^"\']+(?:premiumtv|daddylivehd|vecloud)[^"\']*)["\']',
|
||||
html_content,
|
||||
re.IGNORECASE
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
if iframe_match:
|
||||
@@ -225,17 +245,16 @@ class DLHDExtractor(BaseExtractor):
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
async def _lookup_server(self, lookup_url_base: str, auth_url_base: str, auth_data: Dict[str, str], headers: Dict[str, str]) -> str:
|
||||
async def _lookup_server(
|
||||
self, lookup_url_base: str, auth_url_base: str, auth_data: Dict[str, str], headers: Dict[str, str]
|
||||
) -> str:
|
||||
"""Lookup server information and generate stream URL."""
|
||||
try:
|
||||
# Construct server lookup URL
|
||||
server_lookup_url = f"{lookup_url_base}/server_lookup.php?channel_id={quote(auth_data['channel_key'])}"
|
||||
|
||||
# Make server lookup request
|
||||
server_response = await self._make_request(
|
||||
server_lookup_url,
|
||||
headers=headers
|
||||
)
|
||||
server_response = await self._make_request(server_lookup_url, headers=headers)
|
||||
|
||||
server_data = server_response.json()
|
||||
server_key = server_data.get("server_key")
|
||||
@@ -244,13 +263,13 @@ class DLHDExtractor(BaseExtractor):
|
||||
raise ExtractorError("Failed to get server key")
|
||||
|
||||
# Extract domain parts from auth URL for constructing stream URL
|
||||
auth_domain_parts = urlparse(auth_url_base).netloc.split('.')
|
||||
domain_suffix = '.'.join(auth_domain_parts[1:]) if len(auth_domain_parts) > 1 else auth_domain_parts[0]
|
||||
auth_domain_parts = urlparse(auth_url_base).netloc.split(".")
|
||||
domain_suffix = ".".join(auth_domain_parts[1:]) if len(auth_domain_parts) > 1 else auth_domain_parts[0]
|
||||
|
||||
# Generate the m3u8 URL based on server response pattern
|
||||
if '/' in server_key:
|
||||
if "/" in server_key:
|
||||
# Handle special case like "top1/cdn"
|
||||
parts = server_key.split('/')
|
||||
parts = server_key.split("/")
|
||||
return f"https://{parts[0]}.{domain_suffix}/{server_key}/{auth_data['channel_key']}/mono.m3u8"
|
||||
else:
|
||||
# Handle normal case
|
||||
@@ -278,7 +297,7 @@ class DLHDExtractor(BaseExtractor):
|
||||
"channel_key": channel_key_match.group(1),
|
||||
"auth_ts": auth_ts_match.group(1),
|
||||
"auth_rnd": auth_rnd_match.group(1),
|
||||
"auth_sig": auth_sig_match.group(1)
|
||||
"auth_sig": auth_sig_match.group(1),
|
||||
}
|
||||
except Exception:
|
||||
return {}
|
||||
@@ -287,21 +306,15 @@ class DLHDExtractor(BaseExtractor):
|
||||
"""Extract auth URL base from player page script content."""
|
||||
try:
|
||||
# Look for auth URL or domain in fetchWithRetry call or similar patterns
|
||||
auth_url_match = re.search(
|
||||
r'fetchWithRetry\([\'"]([^\'"]*/auth\.php)',
|
||||
html_content
|
||||
)
|
||||
auth_url_match = re.search(r'fetchWithRetry\([\'"]([^\'"]*/auth\.php)', html_content)
|
||||
|
||||
if auth_url_match:
|
||||
auth_url = auth_url_match.group(1)
|
||||
# Extract base URL up to the auth.php part
|
||||
return auth_url.split('/auth.php')[0]
|
||||
return auth_url.split("/auth.php")[0]
|
||||
|
||||
# Try finding domain directly
|
||||
domain_match = re.search(
|
||||
r'[\'"]https://([^/\'\"]+)(?:/[^\'\"]*)?/auth\.php',
|
||||
html_content
|
||||
)
|
||||
domain_match = re.search(r'[\'"]https://([^/\'\"]+)(?:/[^\'\"]*)?/auth\.php', html_content)
|
||||
|
||||
if domain_match:
|
||||
return f"https://{domain_match.group(1)}"
|
||||
@@ -320,13 +333,13 @@ class DLHDExtractor(BaseExtractor):
|
||||
try:
|
||||
# Typical pattern is to use a subdomain for auth domain
|
||||
parsed = urlparse(player_domain)
|
||||
domain_parts = parsed.netloc.split('.')
|
||||
domain_parts = parsed.netloc.split(".")
|
||||
|
||||
# Get the top-level domain and second-level domain
|
||||
if len(domain_parts) >= 2:
|
||||
base_domain = '.'.join(domain_parts[-2:])
|
||||
base_domain = ".".join(domain_parts[-2:])
|
||||
# Try common subdomains for auth
|
||||
for prefix in ['auth', 'api', 'cdn']:
|
||||
for prefix in ["auth", "api", "cdn"]:
|
||||
potential_auth_domain = f"https://{prefix}.{base_domain}"
|
||||
return potential_auth_domain
|
||||
|
||||
|
||||
Reference in New Issue
Block a user