From 3fa81d485052ac1bea6e73541b493138db81e02e Mon Sep 17 00:00:00 2001 From: UrloMythus Date: Tue, 2 Jun 2026 20:49:18 +0200 Subject: [PATCH] Vidxgo fix --- Src/API/extractors/vidxgo.py | 58 ++++++++++++++---- Src/API/extractors/vixcloud.py | 6 +- Src/API/vidxgoalta.py | 6 +- Src/Utilities/manifest.py | 104 +++++++++++++++++++++++++++++++++ run.py | 11 +++- 5 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 Src/Utilities/manifest.py diff --git a/Src/API/extractors/vidxgo.py b/Src/API/extractors/vidxgo.py index 12c5149..cbf62cb 100644 --- a/Src/API/extractors/vidxgo.py +++ b/Src/API/extractors/vidxgo.py @@ -9,11 +9,32 @@ from fake_headers import Headers random_headers = Headers() import logging from Src.Utilities.config import setup_logging +from base64 import b64encode,b64decode level = config.LEVEL logger = setup_logging(level) import base64 from bs4 import BeautifulSoup,SoupStrainer VD_DOMAIN = config.VD_DOMAIN +from curl_cffi.requests import AsyncSession +VD_PROXY = config.VD_PROXY +proxies = {} +if VD_PROXY == "1": + PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS') + proxy_list = json.loads(PROXY_CREDENTIALS) + proxy = random.choice(proxy_list) + if proxy == "": + proxies = {} + else: + proxies = { + "http": proxy, + "https": proxy + } +VD_ForwardProxy = config.VD_ForwardProxy +if VD_ForwardProxy == "1": + ForwardProxy = env_vars.get('ForwardProxy') +else: + ForwardProxy = "" +VD_DOMAIN = config.VD_DOMAIN headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0', @@ -34,13 +55,31 @@ headers = { 'Priority': 'u=0, i', } +headers2 = { + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0', + 'Accept': '*/*', + 'Accept-Language': 'en-US,en;q=0.9', + 'Referer': 'https://v.vidxgo.co/tt34437972', + 'Sec-GPC': '1', + 'Connection': 'keep-alive', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-origin', + 'DNT': '1', + 'Priority': 'u=4', +} +async def vidxgo_refresh(link,id): + async with AsyncSession() as client: + headers['Referer'] = f'{VD_DOMAIN}/t/{id}' + response = await client.get(ForwardProxy + f'{VD_DOMAIN}/t/{id}', allow_redirects=True, headers = headers2, proxies = proxies) + return response.json()['url'].replace('\\','') -async def vidxgo(link,client,streams,proxies,ForwardProxy): +async def vidxgo(link,client,streams,instance_url): #headers = random_headers.generate() - response = await client.get(link, allow_redirects=True, headers = headers) + response = await client.get(ForwardProxy + link, allow_redirects=True, headers = headers, proxies = proxies) soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('script')) scripts = soup.find_all('script') - text = scripts[5] + text = scripts[6] match = re.search(r"var .+'(.*)',d=atob\('(.*)'",text.text) if match: key = match.group(1) @@ -51,12 +90,11 @@ async def vidxgo(link,client,streams,proxies,ForwardProxy): u[i] = decoded[i] ^ ord(key[i % len(key)]) decrypted_code = u.decode('utf-8') - - match = re.search(r'currentSrc.+"(https:[^";]+)',decrypted_code) - if match: - url = match.group(1).replace("\\","") - streams['streams'].append({'name': f"{Name}",'title': f'{Icon}Vidxgo\n ▶️ Vidxgo', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',"Accept": "*/*", "Accept-Language":"en-US,en;q=0.9","Referer":VD_DOMAIN+"/","Origin":VD_DOMAIN,"Sec-GPC": "1","Connection": "keep-alive","Sec-Fetch-Dest":"empty","Sec-Fetch-Mode":"cors","Sec-Fetch-Site":"cross-site","DNT": "1","Priority":"u=0"}}, 'notWebReady': True, 'bingeGroup': f'vidxgo'}}) - logger.info(f"Vidxgo found results for the current ID") + match = re.search(r'currentSrc.+"(https:[^";]+)',decrypted_code) + if match: + url = match.group(1).replace("\\","") + streams['streams'].append({'name': f"{Name}",'title': f'{Icon}Vidxgo\n ▶️ Vidxgo', 'url': f'{instance_url}/clone/manifest.m3u8?d={b64encode(url.encode("utf-8")).decode("utf-8")}', 'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',"Accept": "*/*", "Accept-Language":"en-US,en;q=0.9","Referer":VD_DOMAIN+"/","Origin":VD_DOMAIN,"Sec-GPC": "1","Connection": "keep-alive","Sec-Fetch-Dest":"empty","Sec-Fetch-Mode":"cors","Sec-Fetch-Site":"cross-site","DNT": "1","Priority":"u=0"}}, 'notWebReady': True, 'bingeGroup': f'vidxgo'}}) + logger.info(f"Vidxgo found results for the current ID") return streams @@ -64,7 +102,7 @@ async def vidxgo(link,client,streams,proxies,ForwardProxy): async def test_vidxgo(): from curl_cffi.requests import AsyncSession async with AsyncSession() as client: - results = await vidsrc("https://v.vidxgo.co/tt34437972/1/1",client,{'streams': []}, "Vidxgo", {}) + results = await vidxgo("https://v.vidxgo.co/tt34437972/1/1",client,{'streams': []}) print(results) if __name__ == "__main__": import asyncio diff --git a/Src/API/extractors/vixcloud.py b/Src/API/extractors/vixcloud.py index 7237e2f..1aede99 100644 --- a/Src/API/extractors/vixcloud.py +++ b/Src/API/extractors/vixcloud.py @@ -30,9 +30,9 @@ async def vixcloud(link,client,MFP,MFP_CREDENTIALS,streams,site_name,proxies,For headers['user-agent'] = User_Agent # I will get real link from API parts = link.split(SC_DOMAIN) - response = await client.get(SC_DOMAIN + '/api' + parts[1]) + response = await client.get(ForwardProxy + SC_DOMAIN + '/api' + parts[1],proxies=proxies) link = SC_DOMAIN + '/' + response.json()['src'] - response = await client.get(link,headers=headers) + response = await client.get(ForwardProxy + link,headers=headers, proxies = proxies) if response.status_code != 200: logger.warning(f"Failed to extract URL components from VixSRC, Invalid Request: {response.status_code}") soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer("body")) @@ -73,7 +73,7 @@ async def vixcloud(link,client,MFP,MFP_CREDENTIALS,streams,site_name,proxies,For async def test_vixcloud(): from curl_cffi.requests import AsyncSession async with AsyncSession() as client: - results = await vixcloud("https://vixsrc.to/tv/204082/1/3/",client,"0",['',''],{'streams': []},'guardoserie.live', {},'') + results = await vixcloud("https://vixsrc.to/tv/76479/5/6/",client,"0",['',''],{'streams': []},'guardoserie.live', {},'') print(results) if __name__ == "__main__": import asyncio diff --git a/Src/API/vidxgoalta.py b/Src/API/vidxgoalta.py index 004572f..8df99e4 100644 --- a/Src/API/vidxgoalta.py +++ b/Src/API/vidxgoalta.py @@ -21,7 +21,7 @@ if VD_PROXY == "1": "http": proxy, "https": proxy } -VD_ForwardProxy = config.GH_ForwardProxy +VD_ForwardProxy = config.VD_ForwardProxy if VD_ForwardProxy == "1": ForwardProxy = env_vars.get('ForwardProxy') else: @@ -30,7 +30,7 @@ VD_DOMAIN = config.VD_DOMAIN -async def vidxgoalta(streams,id,client): +async def vidxgoalta(streams,id,client,instance_url): try: general = await is_movie(id) ismovie = general[0] @@ -44,7 +44,7 @@ async def vidxgoalta(streams,id,client): link = f'{VD_DOMAIN}/{clean_id}/{season}/{episode}' elif ismovie == 1: link = f'{VD_DOMAIN}/{clean_id}' - streams = await vidxgo(link,client,streams,proxies,ForwardProxy) + streams = await vidxgo(link,client,streams,instance_url) return streams except Exception as e: logger.info("Vidxgo failed due to ") diff --git a/Src/Utilities/manifest.py b/Src/Utilities/manifest.py new file mode 100644 index 0000000..0d9e3c3 --- /dev/null +++ b/Src/Utilities/manifest.py @@ -0,0 +1,104 @@ + +from fastapi import APIRouter, HTTPException, Response, Request +from fastapi.responses import RedirectResponse +from curl_cffi.requests import AsyncSession +from urllib.parse import urlparse, parse_qs,unquote,quote +from base64 import b64decode,b64encode +import re +from Src.API.extractors.vidxgo import vidxgo_refresh +import time +import Src.Utilities.config as config +from Src.Utilities.config import setup_logging +level = config.LEVEL +logger = setup_logging(level) + + +VD_DOMAIN = config.VD_DOMAIN +router = APIRouter() +headers = { + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0', + 'Accept': '*/*', + 'Accept-Language': 'en-US,en;q=0.9', + 'Referer': f'{VD_DOMAIN}/', + 'Origin': VD_DOMAIN, + 'Sec-GPC': '1', + 'Connection': 'keep-alive', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'cross-site', + 'DNT': '1', +} +async def fetch_m3u8(url): + """Fetch the M3U8 file from the URL and store it in memory.""" + async with AsyncSession() as client: + response = await client.get(url,headers = headers) + return response.text,response.status_code + +@router.get("/clone/manifest.m3u8") +async def clone_m3u8(d: str = None): + if d: + try: + url = b64decode(d).decode('utf-8') + m3u8_content,status = await fetch_m3u8(url) + if status != 200: + match = re.search(r'hls\/\w*\/([\d\w//]*)\/master',url) + if match: + id = match.group(1) + url = await vidxgo_refresh("",id) + + m3u8_content,status =await fetch_m3u8(url) + m3u8_content = re.sub(r'(&b=\d+)',rf'\1&base={d}',m3u8_content) + return Response(content=m3u8_content, media_type='application/vnd.apple.mpegurl') + except Exception as e: + logger.info(f"Failed to fetch M3U8 file: {e}") + raise HTTPException(status_code=404, detail="M3U8 content not found") + +@router.get("/clone/index{suffix}") +async def index_route(suffix: str, base: str): + try: + text2 = b64decode(base).decode('utf-8') + text = text2.replace("master.m3u8",f'index{suffix}') + + m3u8_content,status = await fetch_m3u8(text) + match = re.search(r'hls\/\w*\/([\d\w//]*)\/master',text2) + if match: + id = match.group(1) + else: + raise HTTPException(status_code=502, detail="ID not found") + + if status != 200: + text = await vidxgo_refresh("",id) + text = text.replace("master.m3u8",f'index{suffix}') + m3u8_content,status =await fetch_m3u8(text) + + current_date = time.strftime('%Y-%m-%d %H:%M') + m3u8_content = re.sub(r'(b=\d+)', rf'\1&id={b64encode(id.encode("utf-8")).decode("utf-8")}&date={b64encode(current_date.encode("utf-8")).decode("utf-8")}', m3u8_content) + return Response(content=m3u8_content, media_type='application/vnd.apple.mpegurl') + except Exception as e: + logger.info(f"Failed to fetch M3U8 file: {e}") + raise HTTPException(status_code=502, detail="M3U8 content not found") + + +@router.get("/clone/seg{suffix}") +async def ts_route(suffix:str,id:str,date: str,t:str,e:str,b:str): + try: + url = await vidxgo_refresh("",b64decode(id).decode('utf-8')) + parsed = urlparse(url) + params = parse_qs(parsed.query) + url = url.split("?")[0] + text = url.replace("master.m3u8",f'seg{suffix}?t={params["t"][0]}&e={params["e"][0]}&b={b}') + return RedirectResponse(text,headers=headers) + except Exception as e: + logger.info(f"Failed to redirect TS file: {e}") + raise HTTPException(status_code=502, detail="Failed to redirect TS file") + +async def test_fetch(): + from curl_cffi.requests import AsyncSession + async with AsyncSession() as client: + results = await clone_m3u8('aHR0cHM6Ly9tZWRpYS00OTguZDJiLnlvdTo4NDQzL3Byb3h5L21lZGlhLTc0Mi9obHMvdHYvMzQ0Mzc5NzIvMS8xL21hc3Rlci5tM3U4P3Q9Yzc1Nzg2ZjUzYTQyM2Y4OSZlPTE3ODA0MDE1Nzg0ODImYj0xNjIx') + print(results) + + +if __name__ == "__main__": + import asyncio + asyncio.run(test_fetch()) \ No newline at end of file diff --git a/run.py b/run.py index efddacd..7f76eb5 100644 --- a/run.py +++ b/run.py @@ -34,6 +34,7 @@ level = config.LEVEL logger = setup_logging(level) from Src.Utilities.loadenv import load_env env_vars = load_env() +from Src.Utilities.manifest import router as clone #Configure Env Vars Global_Proxy = config.Global_Proxy @@ -66,8 +67,8 @@ if env_vars.get('PORT_ENV'): PORT = int(env_vars.get('PORT_ENV')) Icon = config.Icon Name = config.Name - #Cool code to set the hugging face if the service is hosted there. app = FastAPI() +app.include_router(clone) limiter = Limiter(key_func=get_remote_address) app.state.limiter = limiter app.add_middleware(SlowAPIMiddleware) @@ -277,6 +278,10 @@ async def addon_stream(request: Request,config, type, id,): else: MFP = "0" MFP_CREDENTIALS = ['',''] + #Get instance URL to pass it to vidxgo + forwarded_proto = request.headers.get("x-forwarded-proto") + scheme = forwarded_proto if forwarded_proto else request.url.scheme + instance_url = f"{scheme}://{request.url.netloc}" async with AsyncSession(proxies = proxies) as client: if type == "tv": for channel in STREAM["channels"]: @@ -308,6 +313,7 @@ async def addon_stream(request: Request,config, type, id,): else: SC_MFP = '0' streams = await streaming_community(streams,id,client,SC_MFP,MFP_CREDENTIALS) + if provider_maps['CB01'] == "1" and CB == "1": streams = await cb01(streams,id,MFP,MFP_CREDENTIALS,client) if provider_maps['GUARDASERIE'] == "1" and GS == "1": @@ -327,7 +333,8 @@ async def addon_stream(request: Request,config, type, id,): if provider_maps['ONLINESERIETV'] == '1' and OST == '1': streams = await onlineserietv(streams,id,client) if provider_maps['VIDXGO'] == '1' and VD == '1': - streams = await vidxgoalta(streams,id,client) + streams = await vidxgoalta(streams,id,client,instance_url) + return respond_with(streams) if not streams['streams']: raise HTTPException(status_code=404)