feat: Added video quality source options

This commit is contained in:
axtrat
2025-08-25 15:07:38 +02:00
parent c158d3fb99
commit 01432a0fec
3 changed files with 32 additions and 20 deletions

View File

@@ -4,8 +4,11 @@ ANIMEUNITY = "animeunity.so"
ANIMEUNITY_BASE = f"https://www.{ANIMEUNITY}"
MAX_TIMEOUT = 10
TOKEN_REGEX = re.compile(r'<meta.*?name="csrf-token".*?content="([^"]*)".*?>')
REPLACEMENT_WORDS = {"Season ": "", "Cour": "Part"}
TOKEN_REGEX = re.compile(r'<meta.*?name="csrf-token".*?content="([^"]*)".*?>')
# Server Specific
AVAILABLE_VIDEO_QUALITY = ["1080", "720", "480"]
VIDEO_INFO_REGEX = re.compile(r"window.video\s*=\s*(\{[^\}]*\})")
DOWNLOAD_URL_REGEX = re.compile(r"window.downloadUrl\s*=\s*'([^']*)'")

View File

@@ -5,11 +5,13 @@ from ..types import (
AnimeEpisodeInfo,
AnimeEpisodes,
EpisodeStream,
MediaTranslationType,
PageInfo,
SearchResult,
SearchResults,
Server,
)
from .constants import AVAILABLE_VIDEO_QUALITY
def map_to_search_results(
@@ -47,11 +49,7 @@ def map_to_search_result(
else []
),
),
# other_titles=[title for title in [result["title_eng"], result["title_it"]] if title],
media_type=data["type"],
score=data["score"],
status=data["status"],
# season=result["season"],
poster=data["imageurl"],
year=data["date"],
)
@@ -87,13 +85,21 @@ def map_to_anime_result(data: list, search_result: SearchResult) -> Anime:
)
def map_to_server(episode: AnimeEpisodeInfo, download_url: str) -> Server:
def map_to_server(
episode: AnimeEpisodeInfo, info: dict, translation_type: Literal["sub", "dub"]
) -> Server:
return Server(
name="vixcloud",
links=[
EpisodeStream(
link=download_url,
link=info["link"].replace(str(info["quality"]), str(quality)),
title=info["name"],
quality=str(quality), # type: ignore
translation_type=MediaTranslationType(translation_type),
mp4=True,
)
for quality in AVAILABLE_VIDEO_QUALITY
if quality <= info["quality"]
],
episode_title=episode.title,
)

View File

@@ -12,6 +12,7 @@ from .constants import (
MAX_TIMEOUT,
REPLACEMENT_WORDS,
TOKEN_REGEX,
VIDEO_INFO_REGEX,
)
from .mappers import (
map_to_anime_result,
@@ -141,29 +142,31 @@ class AnimeUnity(BaseAnimeProvider):
return episode
@debug_provider
def episode_streams(self, params):
episode = self._get_episode_info(params)
if not episode:
def episode_streams(self, params: EpisodeStreamsParams):
if not (episode := self._get_episode_info(params)):
logger.error(
f"Episode {params.episode} doesn't exist for anime {params.anime_id}"
)
return
# Get the Server url
response = self.client.get(
url=f"{ANIMEUNITY_BASE}/embed-url/{episode.id}",
timeout=MAX_TIMEOUT,
url=f"{ANIMEUNITY_BASE}/embed-url/{episode.id}", timeout=MAX_TIMEOUT
)
response.raise_for_status()
# The embed URL is returned as plain text
iframe_src = response.text.strip()
# Fetch the video page
video_response = self.client.get(iframe_src, timeout=MAX_TIMEOUT)
# Fetch the Server page
video_response = self.client.get(url=response.text.strip(), timeout=MAX_TIMEOUT)
video_response.raise_for_status()
video_info = VIDEO_INFO_REGEX.search(video_response.text)
download_url_match = DOWNLOAD_URL_REGEX.search(video_response.text)
if download_url_match:
yield map_to_server(episode, download_url_match.group(1))
return None
if not (download_url_match and video_info):
logger.error(f"Failed to extract video info for episode {episode.id}")
return None
info = eval(video_info.group(1).replace("null", "None"))
info["link"] = download_url_match.group(1)
yield map_to_server(episode, info, params.translation_type)
if __name__ == "__main__":