@@ -23,11 +23,11 @@ async def extract(self, url: str, referer: str = None) -> ExtractResult:
2323 "Sec-Fetch-Dest" : "iframe" ,
2424 })
2525
26- if self .main_url .endswith (".me" ):
27- self .main_url = self .main_url .replace (".me" , ".net" )
26+ if ".me" in url :
2827 url = url .replace (".me" , ".net" )
2928
30- response = await self .httpx .get (url )
29+ # VidMoly bazen redirect ediyor, takip et
30+ response = await self .httpx .get (url , follow_redirects = True )
3131 if "Select number" in response .text :
3232 secici = Selector (response .text )
3333 response = await self .httpx .post (
@@ -39,21 +39,10 @@ async def extract(self, url: str, referer: str = None) -> ExtractResult:
3939 "ts" : secici .css ("input[name='ts']::attr(value)" ).get (),
4040 "nonce" : secici .css ("input[name='nonce']::attr(value)" ).get (),
4141 "ctok" : secici .css ("input[name='ctok']::attr(value)" ).get ()
42- }
42+ },
43+ follow_redirects = True
4344 )
4445
45- script_match = re .search (r"sources:\s*\[(.*?)\]," , response .text , re .DOTALL )
46- script_content = script_match [1 ] if script_match else None
47-
48- if not script_content :
49- raise ValueError ("Gerekli script bulunamadı." )
50-
51- # Video kaynaklarını ayrıştır
52- video_data = self ._add_marks (script_content , "file" )
53- try :
54- video_sources = json .loads (f"[{ video_data } ]" )
55- except json .JSONDecodeError as hata :
56- raise ValueError ("Video kaynakları ayrıştırılamadı." ) from hata
5746
5847 # Altyazı kaynaklarını ayrıştır
5948 subtitles = []
@@ -72,22 +61,49 @@ async def extract(self, url: str, referer: str = None) -> ExtractResult:
7261 for sub in subtitle_sources
7362 if sub .get ("kind" ) == "captions"
7463 ]
75- # İlk video kaynağını al
76- video_url = None
77- for source in video_sources :
78- if file_url := source .get ("file" ):
79- video_url = file_url
80- break
8164
82- if not video_url :
83- raise ValueError ("Video URL bulunamadı." )
84-
85- return ExtractResult (
86- name = self .name ,
87- url = video_url ,
88- referer = self .main_url ,
89- subtitles = subtitles
90- )
65+ script_match = re .search (r"sources:\s*\[(.*?)\]," , response .text , re .DOTALL )
66+ if script_match :
67+ script_content = script_match [1 ]
68+ # Video kaynaklarını ayrıştır
69+ video_data = self ._add_marks (script_content , "file" )
70+ try :
71+ video_sources = json .loads (f"[{ video_data } ]" )
72+ # İlk video kaynağını al
73+ for source in video_sources :
74+ if file_url := source .get ("file" ):
75+ return ExtractResult (
76+ name = self .name ,
77+ url = file_url ,
78+ referer = self .main_url ,
79+ subtitles = subtitles
80+ )
81+ except json .JSONDecodeError :
82+ pass
83+
84+ # Fallback: Doğrudan file regex ile ara (Kotlin mantığı)
85+ # file:"..." veya file: "..."
86+ if file_match := re .search (r'file\s*:\s*["\']([^"\']+\.m3u8[^"\']*)["\']' , response .text ):
87+ return ExtractResult (
88+ name = self .name ,
89+ url = file_match .group (1 ),
90+ referer = self .main_url ,
91+ subtitles = subtitles
92+ )
93+
94+ # Fallback 2: Herhangi bir file (m3u8 olma şartı olmadan ama tercihen)
95+ if file_match := re .search (r'file\s*:\s*["\']([^"\']+)["\']' , response .text ):
96+ url_candidate = file_match .group (1 )
97+ # Resim dosyalarını hariç tut
98+ if not url_candidate .endswith (('.jpg' , '.png' , '.jpeg' )):
99+ return ExtractResult (
100+ name = self .name ,
101+ url = url_candidate ,
102+ referer = self .main_url ,
103+ subtitles = subtitles
104+ )
105+
106+ raise ValueError ("Video URL bulunamadı." )
91107
92108 def _add_marks (self , text : str , field : str ) -> str :
93109 """
0 commit comments