Compare commits

..

2 Commits

Author SHA1 Message Date
Type-Delta
7f4a1f265a fix: animepahe unable to stream/download 2025-12-28 19:20:46 +07:00
Benexl
12ef447eaf feat: add vlc player which i somehow forgot lol 2025-12-28 01:25:18 +03:00
7 changed files with 42 additions and 3 deletions

View File

@@ -132,6 +132,7 @@ APP_SERVICE = "Configuration for the background download service."
APP_FZF = "Settings for the FZF selector interface."
APP_ROFI = "Settings for the Rofi selector interface."
APP_MPV = "Configuration for the MPV media player."
APP_VLC = "Configuration for the VLC media player."
APP_MEDIA_REGISTRY = "Configuration for the media registry."
APP_SESSIONS = "Configuration for sessions."

View File

@@ -534,6 +534,7 @@ class AppConfig(BaseModel):
description=desc.APP_ROFI,
)
mpv: MpvConfig = Field(default_factory=MpvConfig, description=desc.APP_MPV)
vlc: VlcConfig = Field(default_factory=VlcConfig, description=desc.APP_VLC)
media_registry: MediaRegistryConfig = Field(
default_factory=MediaRegistryConfig, description=desc.APP_MEDIA_REGISTRY
)

View File

@@ -30,6 +30,9 @@ class YtDLPDownloader(BaseDownloader):
sub_paths = []
merged_path = None
logger.debug(f"Starting download for URL: {params.url}")
logger.debug(f"Using Headers: {params.headers}")
if TORRENT_REGEX.match(params.url):
from .torrents import download_torrent_with_webtorrent_cli

View File

@@ -41,6 +41,10 @@ class PlayerFactory:
from .mpv.player import MpvPlayer
return MpvPlayer(config.mpv)
elif player_name == "vlc":
from .vlc.player import VlcPlayer
return VlcPlayer(config.vlc)
raise NotImplementedError(
f"Configuration logic for player '{player_name}' not implemented in factory."
)

View File

@@ -3,6 +3,8 @@ import re
ANIMEPAHE = "animepahe.si"
ANIMEPAHE_BASE = f"https://{ANIMEPAHE}"
ANIMEPAHE_ENDPOINT = f"{ANIMEPAHE_BASE}/api"
CDN_PROVIDER = "kwik.cx"
CDN_PROVIDER_BASE = f"https://{CDN_PROVIDER}"
SERVERS_AVAILABLE = ["kwik"]
REQUEST_HEADERS = {
@@ -25,7 +27,7 @@ SERVER_HEADERS = {
"Accept-Encoding": "Utf-8",
"DNT": "1",
"Connection": "keep-alive",
"Referer": "https://animepahe.si/",
"Referer": ANIMEPAHE_BASE + '/',
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "iframe",
"Sec-Fetch-Mode": "navigate",
@@ -33,5 +35,22 @@ SERVER_HEADERS = {
"Priority": "u=4",
"TE": "trailers",
}
STREAM_HEADERS = {
# "Host": "vault-16.owocdn.top", # This will have to be the actual host of the stream (behind Kwik)
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Origin": CDN_PROVIDER_BASE,
"Sec-GPC": "1",
"Connection": "keep-alive",
"Referer": CDN_PROVIDER_BASE + '/',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "cross-site",
"TE": "trailers",
}
JUICY_STREAM_REGEX = re.compile(r"source='(.*)';")
KWIK_RE = re.compile(r"Player\|(.+?)'")

View File

@@ -88,6 +88,7 @@ def map_to_server(
episode: AnimeEpisodeInfo,
translation_type: str,
stream_links: list[tuple[str, str]],
headers: dict[str, str],
) -> Server:
links = [
EpisodeStream(
@@ -97,4 +98,4 @@ def map_to_server(
)
for link in stream_links
]
return Server(name="kwik", links=links, episode_title=episode.title)
return Server(name="kwik", links=links, episode_title=episode.title, headers=headers)

View File

@@ -1,6 +1,7 @@
import logging
from functools import lru_cache
from typing import Iterator, Optional
from urllib.parse import urlparse
from ..base import BaseAnimeProvider
from ..params import AnimeParams, EpisodeStreamsParams, SearchParams
@@ -9,9 +10,11 @@ from ..utils.debug import debug_provider
from .constants import (
ANIMEPAHE_BASE,
ANIMEPAHE_ENDPOINT,
CDN_PROVIDER,
JUICY_STREAM_REGEX,
REQUEST_HEADERS,
SERVER_HEADERS,
STREAM_HEADERS,
)
from .extractor import process_animepahe_embed_page
from .mappers import map_to_anime_result, map_to_search_results, map_to_server
@@ -132,6 +135,7 @@ class AnimePahe(BaseAnimeProvider):
quality = None
translation_type = None
stream_links = []
stream_host = None
# TODO: better document the scraping process
for res_dict in res_dicts:
@@ -170,13 +174,19 @@ class AnimePahe(BaseAnimeProvider):
continue
logger.debug(f"Found juicy stream: {juicy_stream.group(1)}")
juicy_stream = juicy_stream.group(1)
stream_host = urlparse(juicy_stream).hostname
quality = res_dict["resolution"]
logger.debug(f"Found quality: {quality}")
translation_type = data_audio
stream_links.append((quality, juicy_stream))
if translation_type and stream_links:
yield map_to_server(episode, translation_type, stream_links)
headers = {
"User-Agent": self.client.headers["User-Agent"],
"Host": stream_host or CDN_PROVIDER,
**STREAM_HEADERS
}
yield map_to_server(episode, translation_type, stream_links, headers=headers)
@lru_cache()
def _get_episode_info(