Tolimo commited on
Commit
7dd0d49
·
verified ·
1 Parent(s): 4bdf495

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +90 -81
main.py CHANGED
@@ -1,5 +1,3 @@
1
- import yt_dlp
2
- from fastapi import FastAPI, HTTPException, Query, BackgroundTasks, Body
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from fastapi.responses import FileResponse
5
  from starlette.background import BackgroundTask
@@ -41,117 +39,128 @@ def clean_fb_url(url: str):
41
  except: pass
42
  return urllib.parse.unquote(url).replace('&', '&')
43
 
 
 
 
 
 
 
 
 
 
 
44
  @app.get("/")
45
  def root():
46
- return {"message": "Bumiz FB Pro: Real HQ Engine Active"}
 
47
 
48
- # --- ၁။ ANALYZE: QUALITY အစုံရှာခြင်း (Duplicate Filter ပါဝင်သည်) ---
49
- @app.post("/analyze-private")
50
- async def analyze_private_fb(payload: dict = Body(...)):
51
  html_source = payload.get("html", "")
52
- if not html_source:
53
- return {"success": False, "error": "Source is empty"}
54
 
55
- # Video Representations ရှာဖွေခြင်း
56
- video_matches = re.findall(r'"height":(\d+),.*?"base_url":"([^"]+)"', html_source)
57
 
58
- unique_qualities = {}
59
- for height, url in video_matches:
60
- h = int(height)
61
- u = clean_fb_url(url)
62
- if u and "fbcdn.net" in u:
63
- # တူညီတဲ့ height တွေကို တစ်ခုပဲ ယူမယ် (အကြည်ဆုံး link ကိုပဲ သိမ်းမယ်)
64
- if h not in unique_qualities:
65
- unique_qualities[h] = u
66
-
67
- # Result ပြန်ပို့ရန် format ပြင်ခြင်း
68
- final_qualities = []
69
- for h in sorted(unique_qualities.keys(), reverse=True):
70
- final_qualities.append({
71
- "label": f"{h}p Quality",
72
- "url": unique_qualities[h],
73
- "height": h,
74
- "type": "hd" if h >= 720 else "sd"
75
- })
76
-
77
- # Audio Link ရှာဖွေခြင်း (အသံသီးသန့် အကွက်ထဲမှာ အရင်ရှာမယ်)
78
  audio_url = None
79
- # Method A: DASH Manifest Audio
80
- a_match = re.search(r'"mime_type":"audio/[^"]+","base_url":"([^"]+)"', html_source)
81
- if a_match:
82
- audio_url = clean_fb_url(a_match.group(1))
83
- else:
84
- # Method B: Alternative Audio key
85
- a_match_alt = re.search(r'"audio":\[\{"url":"([^"]+)"', html_source)
86
- if a_match_alt:
87
- audio_url = clean_fb_url(a_match_alt.group(1))
88
-
89
- if not final_qualities:
90
- return {"success": False, "error": "No valid video streams found."}
91
-
92
- return {"success": True, "qualities": final_qualities, "audio_url": audio_url}
93
-
94
- # --- ၂။ PROCESS: အကြည်ဆုံး ရအောင် ပေါင်းစပ်ခြင်း ---
95
- @app.post("/process-private")
96
- async def process_private_fb(background_tasks: BackgroundTasks, payload: dict = Body(...)):
97
- video_url = payload.get("video_url")
98
- audio_url = payload.get("audio_url")
 
 
 
 
 
 
 
99
 
100
- file_id = str(uuid.uuid4())
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  final_video = os.path.join(TEMP_DIR, f"{file_id}.mp4")
 
 
 
 
 
102
 
 
103
  try:
104
  v_tmp = os.path.join(TEMP_DIR, f"{uuid.uuid4()}_v.mp4")
105
  a_tmp = os.path.join(TEMP_DIR, f"{uuid.uuid4()}_a.mp3")
106
-
107
- headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}
108
-
109
- # Download Video
110
- v_res = requests.get(video_url, headers=headers, timeout=60)
111
- with open(v_tmp, 'wb') as f: f.write(v_res.content)
112
 
113
- # Download Audio
114
- has_audio = False
 
115
  if audio_url:
116
- a_res = requests.get(audio_url, headers=headers, timeout=60)
117
- if a_res.status_code == 200:
118
- with open(a_tmp, 'wb') as f: f.write(a_res.content)
119
- if os.path.getsize(a_tmp) > 1000:
120
- has_audio = True
121
 
122
- # FFmpeg Merging (Ultra High Quality Settings)
123
  cmd = ['ffmpeg', '-y', '-i', v_tmp]
124
- if has_audio:
125
  cmd += ['-i', a_tmp, '-map', '0:v:0', '-map', '1:a:0']
126
 
127
- # -crf 18 က Original နဲ့ တစ်ထပ်တည်း ရုပ်ထွက်ကို ပေးပါတယ်
128
- cmd += [
129
- '-c:v', 'libx264', '-crf', '18', '-preset', 'superfast',
130
- '-c:a', 'aac', '-b:a', '192k', '-movflags', '+faststart', final_video
131
- ]
132
 
133
  subprocess.run(cmd, check=True, capture_output=True)
134
 
135
  if os.path.exists(v_tmp): os.remove(v_tmp)
136
  if os.path.exists(a_tmp): os.remove(a_tmp)
137
 
138
- space_id = os.getenv('SPACE_ID', '').replace("/", "-")
139
  return {
140
- "success": True,
141
- "video_url": f"https://{space_id}.hf.space/get_file?id={file_id}.mp4",
 
142
  "size": os.path.getsize(final_video)
143
  }
144
  except Exception as e:
 
 
145
  return {"success": False, "error": str(e)}
146
 
147
  @app.get("/get_file")
148
  async def get_file(id: str):
149
  file_path = os.path.join(TEMP_DIR, id)
150
  if os.path.exists(file_path):
151
- return FileResponse(file_path, media_type="video/mp4", filename=f"fb_hq_download.mp4", background=BackgroundTask(cleanup, file_path))
152
- raise HTTPException(status_code=404)
153
-
154
- @app.get("/download")
155
- async def download_public(url: str = Query(...)):
156
- # Public link fallback
157
- return {"success": False, "error": "Please use Private Mode for HQ results."}
 
 
 
1
  from fastapi.middleware.cors import CORSMiddleware
2
  from fastapi.responses import FileResponse
3
  from starlette.background import BackgroundTask
 
39
  except: pass
40
  return urllib.parse.unquote(url).replace('&', '&')
41
 
42
+ def get_ffprobe_info(file_path):
43
+
44
+
45
+ try:
46
+ cmd = ['ffprobe', '-v', 'error', '-show_entries', 'stream=codec_type', '-of', 'json', file_path]
47
+ result = subprocess.run(cmd, capture_output=True, text=True)
48
+ data = json.loads(result.stdout)
49
+ return [s['codec_type'] for s in data.get('streams', [])]
50
+ except: return []
51
+
52
  @app.get("/")
53
  def root():
54
+ return {"message": "Bumiz Facebook Pro API Active"}
55
+
56
 
57
+ @app.post("/download-private")
58
+ async def download_private_fb(payload: dict = Body(...)):
 
59
  html_source = payload.get("html", "")
60
+ target_quality = payload.get("quality", "original") # original, 720, 480, 240
61
+
62
 
 
 
63
 
64
+ if not html_source:
65
+ return {"success": False, "error": "HTML Source is empty."}
66
+
67
+
68
+
69
+
70
+
71
+ # Video & Audio Extraction Logic
72
+ video_url = None
 
 
 
 
 
 
 
 
 
 
 
73
  audio_url = None
74
+
75
+ # HD သို့မဟုတ် Progressive Link ကို အရင်ရှာခြင်း
76
+ hd_match = re.search(r'"browser_native_hd_url":"([^"]+)"', html_source)
77
+ sd_match = re.search(r'"browser_native_sd_url":"([^"]+)"', html_source)
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
 
102
+ if hd_match: video_url = clean_fb_url(hd_match.group(1))
103
+ elif sd_match: video_url = clean_fb_url(sd_match.group(1))
104
+
105
+ # Separate Streams ရှာဖွေခြင်း
106
+ v_matches = re.findall(r'"mime_type":"video[^"]+".*?"base_url":"([^"]+)"', html_source)
107
+ a_matches = re.findall(r'"mime_type":"audio[^"]+".*?"base_url":"([^"]+)"', html_source)
108
+
109
+ if not video_url and v_matches: video_url = clean_fb_url(v_matches[0])
110
+ if a_matches: audio_url = clean_fb_url(a_matches[0])
111
+
112
+ if not video_url:
113
+ return {"success": False, "error": "Video link not found in source."}
114
+
115
+ file_id = hashlib.md5(f"{video_url}_{target_quality}".encode()).hexdigest()
116
  final_video = os.path.join(TEMP_DIR, f"{file_id}.mp4")
117
+
118
+ # Cache Check
119
+ if os.path.exists(final_video):
120
+ os.utime(final_video, None)
121
+ return {"success": True, "method": "Cache", "video_url": f"get_file?id={file_id}.mp4", "size": os.path.getsize(final_video)}
122
 
123
+ # Processing
124
  try:
125
  v_tmp = os.path.join(TEMP_DIR, f"{uuid.uuid4()}_v.mp4")
126
  a_tmp = os.path.join(TEMP_DIR, f"{uuid.uuid4()}_a.mp3")
 
 
 
 
 
 
127
 
128
+ # Download streams
129
+ headers = {'User-Agent': 'Mozilla/5.0'}
130
+ with open(v_tmp, 'wb') as f: f.write(requests.get(video_url, headers=headers).content)
131
  if audio_url:
132
+ with open(a_tmp, 'wb') as f: f.write(requests.get(audio_url, headers=headers).content)
 
 
 
 
133
 
134
+ # Build FFmpeg Command (Force H.264 & AAC)
135
  cmd = ['ffmpeg', '-y', '-i', v_tmp]
136
+ if os.path.exists(a_tmp) and os.path.getsize(a_tmp) > 1000:
137
  cmd += ['-i', a_tmp, '-map', '0:v:0', '-map', '1:a:0']
138
 
139
+ # Quality Scaling if needed
140
+ if target_quality != "original":
141
+ cmd += ['-vf', f"scale=w='trunc(oh*a/2)*2':h={target_quality}"]
142
+
143
+ cmd += ['-c:v', 'libx264', '-preset', 'ultrafast', '-crf', '23', '-c:a', 'aac', '-b:a', '128k', '-movflags', '+faststart', final_video]
144
 
145
  subprocess.run(cmd, check=True, capture_output=True)
146
 
147
  if os.path.exists(v_tmp): os.remove(v_tmp)
148
  if os.path.exists(a_tmp): os.remove(a_tmp)
149
 
 
150
  return {
151
+ "success": True,
152
+ "method": "Bumiz Engine",
153
+ "video_url": f"get_file?id={file_id}.mp4",
154
  "size": os.path.getsize(final_video)
155
  }
156
  except Exception as e:
157
+
158
+
159
  return {"success": False, "error": str(e)}
160
 
161
  @app.get("/get_file")
162
  async def get_file(id: str):
163
  file_path = os.path.join(TEMP_DIR, id)
164
  if os.path.exists(file_path):
165
+ return FileResponse(file_path, media_type="video/mp4", filename=f"fb_bumiz_{id}", background=BackgroundTask(cleanup, file_path))
166
+ raise HTTPException(status_code=404)