Add hdplayer

This commit is contained in:
Lovi 2025-04-29 22:03:06 +02:00
parent 94d884267e
commit d872921c23
12 changed files with 131 additions and 15 deletions

View File

@ -797,13 +797,27 @@ Contributions are welcome! Steps:
4. Push to branch (`git push origin feature/AmazingFeature`)
5. Open Pull Request
# Disclaimer
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
## Useful Project
### 🎯 [Unit3Dup](https://github.com/31December99/Unit3Dup)
Bot in Python per la generazione e l'upload automatico di torrent su tracker basati su Unit3D.
### 🇮🇹 [MammaMia](https://github.com/UrloMythus/MammaMia)
Addon per Stremio che consente lo streaming HTTPS di film, serie, anime e TV in diretta in lingua italiana.
### 🧩 [streamingcommunity-unofficialapi](https://github.com/Blu-Tiger/streamingcommunity-unofficialapi)
API non ufficiale per accedere ai contenuti del sito italiano StreamingCommunity.
### 🎥 [stream-buddy](https://github.com/Bbalduzz/stream-buddy)
Tool per guardare o scaricare film dalla piattaforma StreamingCommunity.
## Contributors
<a href="https://github.com/Arrowar/StreamingCommunity/graphs/contributors" alt="View Contributors">
<img src="https://contrib.rocks/image?repo=Arrowar/StreamingCommunity&max=1000&columns=10" alt="Contributors" />
</a>
</a>

View File

@ -0,0 +1,101 @@
# 29.04.25
import re
import logging
# External libraries
import httpx
from bs4 import BeautifulSoup
# Internal utilities
from StreamingCommunity.Util.config_json import config_manager
from StreamingCommunity.Util.headers import get_userAgent
# Variable
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
class VideoSource:
def __init__(self, url: str):
"""
Sets up the video source with the provided URL.
Parameters:
- url (str): The URL of the video.
"""
self.url = url
self.iframe_url = None
self.m3u8_url = None
self.headers = {
'accept': '*/*',
'accept-language': 'en-US,en;q=0.9',
'user-agent': get_userAgent(),
'referer': url
}
def extract_iframe_sources(self, response) -> str:
"""Extract iframe source from the page."""
try:
soup = BeautifulSoup(response.content, 'html.parser')
iframes = soup.select("iframe[data-lazy-src]")
if not iframes:
iframes = soup.select("iframe[src]")
if iframes:
iframe_url = iframes[0].get('data-lazy-src') or iframes[0].get('src')
self.iframe_url = iframe_url
logging.info(f"Iframe URL found: {iframe_url}")
return iframe_url
logging.error("No iframes found in the page")
return None
except Exception as e:
logging.error(f"Error extracting iframe: {e}")
raise
def get_m3u8_url(self) -> str:
"""
Extract m3u8 URL from hdPlayer page.
"""
try:
# First request to get iframe
response = httpx.get(self.url, headers=self.headers, timeout=MAX_TIMEOUT)
response.raise_for_status()
iframe_url = self.extract_iframe_sources(response)
if not iframe_url:
raise ValueError("No iframe URL found")
# Update headers for iframe request
self.headers['referer'] = iframe_url
# Request to iframe page
logging.info(f"Making request to hdPlayer: {iframe_url}")
response = httpx.get(iframe_url, headers=self.headers, timeout=MAX_TIMEOUT)
response.raise_for_status()
# Find m3u8 in the script
soup = BeautifulSoup(response.text, 'html.parser')
scripts = soup.find_all("script")
for script in scripts:
if not script.string:
continue
match = re.search(r'sources:\s*\[\{\s*file:\s*"([^"]+)"', script.string)
if match:
self.m3u8_url = match.group(1)
logging.info(f"Found m3u8 URL: {self.m3u8_url}")
return self.m3u8_url
logging.error("No m3u8 URL found in scripts")
return None
except Exception as e:
logging.error(f"Error getting m3u8 URL: {e}")
raise

View File

@ -52,7 +52,7 @@ def title_search(query: str) -> int:
response.raise_for_status()
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
return 0
# Create soup and find table

View File

@ -55,7 +55,7 @@ def title_search(query: str) -> int:
response.raise_for_status()
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
if site_constant.TELEGRAM_BOT:
bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None)
return 0

View File

@ -119,7 +119,8 @@ def title_search(query: str) -> int:
process_results(response1.json()['records'], seen_titles, media_search_manager, choices)
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, livesearch error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
return 0
# Second API call - archivio
try:

View File

@ -78,7 +78,7 @@ def title_search(query: str) -> int:
)
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
return 0
# Create soup istance

View File

@ -53,7 +53,7 @@ def title_search(query: str) -> int:
response.raise_for_status()
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
return 0
# Create soup and find table

View File

@ -54,7 +54,7 @@ def title_search(query: str) -> int:
response.raise_for_status()
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
return 0
# Create soup and find table

View File

@ -26,7 +26,7 @@ console = Console()
media_search_manager = MediaManager()
table_show_manager = TVShowManager()
max_timeout = config_manager.get_int("REQUESTS", "timeout")
MAX_THREADS = 4
MAX_THREADS = 12
def determine_media_type(title):
@ -134,7 +134,7 @@ def title_search(query: str) -> int:
response.raise_for_status()
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
return 0
# Limit to only 15 results for performance

View File

@ -55,7 +55,7 @@ def title_search(query: str) -> int:
response.raise_for_status()
except Exception as e:
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
if site_constant.TELEGRAM_BOT:
bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None)
return 0

View File

@ -41,8 +41,8 @@ def download_film(select_title: MediaItem) -> str:
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
# Get master playlists
video_source = VideoSource()
master_playlist = video_source.get_m3u8_url(select_title.url)
video_source = VideoSource(select_title.url)
master_playlist = video_source.get_m3u8_url()
# Define the filename and path for the downloaded film
title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4"

View File

@ -60,8 +60,8 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
mp4_path = os.path.join(site_constant.SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}")
# Retrieve scws and if available master playlist
video_source = VideoSource()
master_playlist = video_source.get_m3u8_url(obj_episode.url)
video_source = VideoSource(obj_episode.url)
master_playlist = video_source.get_m3u8_url()
# Download the episode
r_proc = HLS_Downloader(