Hydui commited on
Commit
34c9162
·
verified ·
1 Parent(s): 41c1c4d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -41
app.py CHANGED
@@ -14,7 +14,7 @@ from datetime import datetime
14
  from queue import Queue
15
 
16
  # ========== Global Job Storage ==========
17
- jobs = {} # job_id -> {status, input_file, output_file, timestamp, progress, error, log_queue}
18
 
19
  class UltimateVideoEvader:
20
  def __init__(self):
@@ -56,7 +56,6 @@ class UltimateVideoEvader:
56
 
57
  def build_brutal_command(self, input_file, output_file):
58
  cmd = [self.ffmpeg_path, "-i", input_file]
59
-
60
  cmd.extend(["-map_metadata", "-1"])
61
 
62
  scale = self._random_float(0.6, 1.4)
@@ -118,20 +117,15 @@ class UltimateVideoEvader:
118
 
119
  codec = random.choice(["libx264", "libx265", "libvpx-vp9"])
120
  cmd.extend(["-c:v", codec])
121
-
122
  preset = random.choice(["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow"])
123
  cmd.extend(["-preset", preset])
124
-
125
  crf = random.randint(18, 28)
126
  cmd.extend(["-crf", str(crf)])
127
-
128
  audio_codec = random.choice(["aac", "libmp3lame"])
129
  cmd.extend(["-c:a", audio_codec, "-b:a", "128k"])
130
-
131
  container = random.choice(["mp4", "mkv", "mov"])
132
  base = os.path.splitext(output_file)[0]
133
  output_file = f"{base}.{container}"
134
-
135
  cmd.extend(["-y", output_file])
136
  return cmd, output_file
137
 
@@ -177,7 +171,6 @@ class UltimateVideoEvader:
177
  speed_pattern = re.compile(r'speed=\s*([\d.]+)x')
178
  fps_pattern = re.compile(r'fps=\s*([\d.]+)')
179
  time_pattern = re.compile(r'time=(\d{2}):(\d{2}):(\d{2})\.(\d{2})')
180
- frame_pattern = re.compile(r'frame=\s*(\d+)')
181
 
182
  start_time = time.time()
183
  last_log_time = 0
@@ -186,14 +179,9 @@ class UltimateVideoEvader:
186
  line = process.stderr.readline()
187
  if not line:
188
  break
189
-
190
  line = line.strip()
191
 
192
  if 'frame=' in line or 'time=' in line:
193
- frame_match = frame_pattern.search(line)
194
- if frame_match:
195
- processed_frames = int(frame_match.group(1))
196
-
197
  time_match = time_pattern.search(line)
198
  if time_match:
199
  h, m, s, cs = time_match.groups()
@@ -201,12 +189,10 @@ class UltimateVideoEvader:
201
 
202
  speed_match = speed_pattern.search(line)
203
  speed_val = speed_match.group(1) if speed_match else "?"
204
-
205
  fps_match = fps_pattern.search(line)
206
  fps_val = fps_match.group(1) if fps_match else "?"
207
 
208
  if duration > 0 and time_match and speed_match:
209
- elapsed = time.time() - start_time
210
  if float(speed_val) > 0:
211
  eta = (duration - current_time) / float(speed_val)
212
  eta_min = int(eta // 60)
@@ -325,15 +311,18 @@ class UltimateVideoEvader:
325
  job_list.sort(key=lambda x: x["timestamp"], reverse=True)
326
  return job_list
327
 
328
- def download_job_by_id(self, job_id):
329
  if job_id not in jobs:
330
- return None, "❌ Job ID not found"
331
  job = jobs[job_id]
332
  if job.get("status") != "completed":
333
- return None, f"⏳ Job is {job.get('status')} – not ready yet"
334
  if not job.get("output_file") or not os.path.exists(job.get("output_file")):
335
- return None, "❌ Output file missing"
336
- return job["output_file"], f"✅ Download ready: {os.path.basename(job['output_file'])}"
 
 
 
337
 
338
 
339
  # ========== Gradio Interface ==========
@@ -343,7 +332,6 @@ def create_interface():
343
  with gr.Blocks(title="Video Fingerprint Evader") as demo:
344
  gr.Markdown("""
345
  # 🚀 Video Fingerprint Evader – Live Logs + Background Processing
346
- **Live Logs में ETA, Speed, FPS और Progress की पूरी जानकारी देखें।**
347
  """)
348
 
349
  job_id_state = gr.State("")
@@ -358,8 +346,13 @@ def create_interface():
358
  )
359
  process_btn = gr.Button("🔥 Process in Background", variant="primary")
360
  job_status = gr.Textbox(label="📊 Job Status", lines=3, interactive=False)
361
- download_btn = gr.Button("📥 Download Completed Video", variant="secondary")
362
- download_output = gr.File(label="📥 Download", visible=False)
 
 
 
 
 
363
 
364
  with gr.Column(scale=2):
365
  log_display = gr.Textbox(
@@ -387,7 +380,8 @@ def create_interface():
387
  gr.Markdown("### 📥 Download by Job ID")
388
  download_job_id = gr.Textbox(label="Enter Job ID", placeholder="e.g., 5b7c3970")
389
  download_by_id_btn = gr.Button("📥 Download Video", variant="primary")
390
- download_by_id_output = gr.File(label="Download", visible=False)
 
391
  download_by_id_status = gr.Textbox(label="Status", lines=2, interactive=False)
392
 
393
  # ===== Processing Functions =====
@@ -406,13 +400,26 @@ def create_interface():
406
  progress = jobs.get(job_id, {}).get("progress", 0)
407
  return logs, f"Status: {status} | Progress: {progress}%"
408
 
409
- def download_completed(job_id):
410
  if not job_id or job_id not in jobs:
411
- return None
412
- job = jobs.get(job_id)
413
- if job and job.get("status") == "completed" and job.get("output_file"):
414
- return job["output_file"]
415
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
416
 
417
  def refresh_history():
418
  job_list = evader.get_all_jobs()
@@ -437,12 +444,6 @@ def create_interface():
437
  ])
438
  return gr.update(value=rows, visible=True)
439
 
440
- def download_by_job_id(job_id):
441
- if not job_id:
442
- return None, "❌ Please enter a Job ID"
443
- file_path, status = evader.download_job_by_id(job_id)
444
- return file_path, status
445
-
446
  # ===== Event Handlers =====
447
 
448
  process_btn.click(
@@ -462,9 +463,9 @@ def create_interface():
462
  )
463
 
464
  download_btn.click(
465
- download_completed,
466
  inputs=[job_id_state],
467
- outputs=[download_output]
468
  )
469
 
470
  history_refresh_btn.click(
@@ -474,12 +475,12 @@ def create_interface():
474
  )
475
 
476
  download_by_id_btn.click(
477
- download_by_job_id,
478
  inputs=[download_job_id],
479
- outputs=[download_by_id_output, download_by_id_status]
480
  )
481
 
482
- # ===== Auto-refresh using gr.Timer =====
483
  timer = gr.Timer(value=5, active=False)
484
 
485
  def toggle_timer(job_id):
 
14
  from queue import Queue
15
 
16
  # ========== Global Job Storage ==========
17
+ jobs = {}
18
 
19
  class UltimateVideoEvader:
20
  def __init__(self):
 
56
 
57
  def build_brutal_command(self, input_file, output_file):
58
  cmd = [self.ffmpeg_path, "-i", input_file]
 
59
  cmd.extend(["-map_metadata", "-1"])
60
 
61
  scale = self._random_float(0.6, 1.4)
 
117
 
118
  codec = random.choice(["libx264", "libx265", "libvpx-vp9"])
119
  cmd.extend(["-c:v", codec])
 
120
  preset = random.choice(["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow"])
121
  cmd.extend(["-preset", preset])
 
122
  crf = random.randint(18, 28)
123
  cmd.extend(["-crf", str(crf)])
 
124
  audio_codec = random.choice(["aac", "libmp3lame"])
125
  cmd.extend(["-c:a", audio_codec, "-b:a", "128k"])
 
126
  container = random.choice(["mp4", "mkv", "mov"])
127
  base = os.path.splitext(output_file)[0]
128
  output_file = f"{base}.{container}"
 
129
  cmd.extend(["-y", output_file])
130
  return cmd, output_file
131
 
 
171
  speed_pattern = re.compile(r'speed=\s*([\d.]+)x')
172
  fps_pattern = re.compile(r'fps=\s*([\d.]+)')
173
  time_pattern = re.compile(r'time=(\d{2}):(\d{2}):(\d{2})\.(\d{2})')
 
174
 
175
  start_time = time.time()
176
  last_log_time = 0
 
179
  line = process.stderr.readline()
180
  if not line:
181
  break
 
182
  line = line.strip()
183
 
184
  if 'frame=' in line or 'time=' in line:
 
 
 
 
185
  time_match = time_pattern.search(line)
186
  if time_match:
187
  h, m, s, cs = time_match.groups()
 
189
 
190
  speed_match = speed_pattern.search(line)
191
  speed_val = speed_match.group(1) if speed_match else "?"
 
192
  fps_match = fps_pattern.search(line)
193
  fps_val = fps_match.group(1) if fps_match else "?"
194
 
195
  if duration > 0 and time_match and speed_match:
 
196
  if float(speed_val) > 0:
197
  eta = (duration - current_time) / float(speed_val)
198
  eta_min = int(eta // 60)
 
311
  job_list.sort(key=lambda x: x["timestamp"], reverse=True)
312
  return job_list
313
 
314
+ def get_download_link(self, job_id):
315
  if job_id not in jobs:
316
+ return None, "❌ Job not found"
317
  job = jobs[job_id]
318
  if job.get("status") != "completed":
319
+ return None, f"⏳ Job is {job.get('status')}"
320
  if not job.get("output_file") or not os.path.exists(job.get("output_file")):
321
+ return None, "❌ File missing"
322
+ file_path = job["output_file"]
323
+ file_name = os.path.basename(file_path)
324
+ # Return file and HTML link
325
+ return file_path, f"✅ Ready: {file_name}"
326
 
327
 
328
  # ========== Gradio Interface ==========
 
332
  with gr.Blocks(title="Video Fingerprint Evader") as demo:
333
  gr.Markdown("""
334
  # 🚀 Video Fingerprint Evader – Live Logs + Background Processing
 
335
  """)
336
 
337
  job_id_state = gr.State("")
 
346
  )
347
  process_btn = gr.Button("🔥 Process in Background", variant="primary")
348
  job_status = gr.Textbox(label="📊 Job Status", lines=3, interactive=False)
349
+
350
+ gr.Markdown("---")
351
+ gr.Markdown("### 📥 Download Current Job")
352
+ download_btn = gr.Button("📥 Download Video", variant="secondary")
353
+ download_file = gr.File(label="📥 Download", visible=False)
354
+ download_link_html = gr.HTML(label="", visible=False)
355
+ download_status = gr.Textbox(label="Status", lines=2, interactive=False)
356
 
357
  with gr.Column(scale=2):
358
  log_display = gr.Textbox(
 
380
  gr.Markdown("### 📥 Download by Job ID")
381
  download_job_id = gr.Textbox(label="Enter Job ID", placeholder="e.g., 5b7c3970")
382
  download_by_id_btn = gr.Button("📥 Download Video", variant="primary")
383
+ download_by_id_file = gr.File(label="Download", visible=False)
384
+ download_by_id_link = gr.HTML(label="", visible=False)
385
  download_by_id_status = gr.Textbox(label="Status", lines=2, interactive=False)
386
 
387
  # ===== Processing Functions =====
 
400
  progress = jobs.get(job_id, {}).get("progress", 0)
401
  return logs, f"Status: {status} | Progress: {progress}%"
402
 
403
+ def download_current(job_id):
404
  if not job_id or job_id not in jobs:
405
+ return None, "", False, "❌ No job"
406
+ file_path, status = evader.get_download_link(job_id)
407
+ if file_path and os.path.exists(file_path):
408
+ file_name = os.path.basename(file_path)
409
+ # Create HTML download link
410
+ html_link = f'<a href="/file={file_path}" download="{file_name}" target="_blank">📥 Click here to download: {file_name}</a>'
411
+ return file_path, html_link, True, status
412
+ return None, "", False, status
413
+
414
+ def download_by_id(job_id):
415
+ if not job_id:
416
+ return None, "", False, "❌ Please enter Job ID"
417
+ file_path, status = evader.get_download_link(job_id)
418
+ if file_path and os.path.exists(file_path):
419
+ file_name = os.path.basename(file_path)
420
+ html_link = f'<a href="/file={file_path}" download="{file_name}" target="_blank">📥 Click here to download: {file_name}</a>'
421
+ return file_path, html_link, True, status
422
+ return None, "", False, status
423
 
424
  def refresh_history():
425
  job_list = evader.get_all_jobs()
 
444
  ])
445
  return gr.update(value=rows, visible=True)
446
 
 
 
 
 
 
 
447
  # ===== Event Handlers =====
448
 
449
  process_btn.click(
 
463
  )
464
 
465
  download_btn.click(
466
+ download_current,
467
  inputs=[job_id_state],
468
+ outputs=[download_file, download_link_html, download_file, download_status]
469
  )
470
 
471
  history_refresh_btn.click(
 
475
  )
476
 
477
  download_by_id_btn.click(
478
+ download_by_id,
479
  inputs=[download_job_id],
480
+ outputs=[download_by_id_file, download_by_id_link, download_by_id_file, download_by_id_status]
481
  )
482
 
483
+ # ===== Auto-refresh =====
484
  timer = gr.Timer(value=5, active=False)
485
 
486
  def toggle_timer(job_id):