deepuurf commited on
Commit
8fcbdfa
·
verified ·
1 Parent(s): 4c92c82

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -148
app.py CHANGED
@@ -1,169 +1,134 @@
1
- # app_cpu.py – Wasteland Forge MK-IV (CPU Edition)
2
- import gradio as gr
3
- import torch
4
- import cv2
5
- import numpy as np
6
- import librosa
7
- import soundfile as sf
8
- import subprocess
9
  import os
10
- import random
11
- import shutil
12
- import time
13
- from PIL import Image
14
- from diffusers import StableDiffusionImg2ImgPipeline, DDIMScheduler
15
- import warnings
16
- warnings.filterwarnings('ignore')
17
-
18
- # ---------- CPU कॉन्फ़िग ----------
19
- DEVICE = "cpu"
20
- DTYPE = torch.float32 # CPU पर FP16 समर्थन नहीं
21
- MODEL_ID = "segmind/tiny-sd" # हल्का मॉडल (~500MB) – CPU के लिए बेस्ट
22
- OUTPUT_DIR = "/tmp/forge_output"
23
- os.makedirs(OUTPUT_DIR, exist_ok=True)
24
-
25
- print("[Cipher] CPU इंजन लोड हो रहा (कृपया धैर्य रखें)...")
26
- pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
27
- MODEL_ID,
28
- torch_dtype=DTYPE,
29
- safety_checker=None,
30
- requires_safety_checker=False
31
- )
32
- pipe = pipe.to(DEVICE)
33
- pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
34
- pipe.enable_attention_slicing() # मेमोरी बचत
35
- print("[Cipher] CPU इंजन तैयार।")
36
-
37
- def safe_remove(path):
38
- if os.path.exists(path):
39
- os.remove(path)
40
-
41
- # ---------- CPU-अनुकूलित डिफ्यूज़र (256x256, 4 स्टेप्स) ----------
42
- def diffuse_frame_cpu(frame_np, strength=0.75, seed=None):
43
- if seed is not None:
44
- torch.manual_seed(seed)
45
- # 256x256 – VAE को कम काम
46
- pil_img = Image.fromarray(cv2.cvtColor(frame_np, cv2.COLOR_BGR2RGB)).resize((256, 256))
47
- prompt = "post-apocalyptic wasteland, gritty texture, harsh lighting, detailed"
48
- with torch.no_grad():
49
- out = pipe(
50
- prompt=prompt,
51
- negative_prompt="smooth, cartoon, bright, clean, blurry",
52
- image=pil_img,
53
- strength=strength,
54
- guidance_scale=4.0, # कम = तेज़
55
- num_inference_steps=4, # 4 स्टेप – गुणवत्ता कम, लेकिन स्पीड अच्छी
56
- ).images[0]
57
- out_np = np.array(out.resize((frame_np.shape[1], frame_np.shape[0])))
58
- return cv2.cvtColor(out_np, cv2.COLOR_RGB2BGR)
59
 
60
- # ---------- ऑडियो (soundfile) ----------
61
- def destroy_audio(input_wav, output_wav):
62
- y, sr = librosa.load(input_wav, sr=None)
63
- stretch = 1.0 + random.uniform(-0.005, 0.005)
64
- y = librosa.effects.time_stretch(y, rate=stretch)
65
- y = librosa.effects.pitch_shift(y, sr=sr, n_steps=random.uniform(-0.7, 0.7))
66
- block = 2048
67
- for i in range(0, len(y)-block, block):
68
- if random.random() > 0.6:
69
- y[i:i+block] = -y[i:i+block]
70
- t = np.arange(len(y)) / sr
71
- sweep = 0.005 * np.sin(2 * np.pi * (20 + 50 * t / len(y)) * t)
72
- noise = np.random.normal(0, 0.01 * np.std(y), len(y))
73
- y = y + sweep + noise
74
- y = y / np.max(np.abs(y)) * 0.95
75
- sf.write(output_wav, y.astype(np.float32), sr)
76
 
77
- # ---------- मुख्य फोर्ज ----------
78
- def forge_video(file_obj, strength_slider, progress=gr.Progress()):
79
- if file_obj is None:
80
- return None, "❌ कोई फ़ाइल नहीं"
81
- input_path = file_obj.name
82
- start_total = time.time()
83
- base = os.path.splitext(os.path.basename(input_path))[0]
84
- out_video = os.path.join(OUTPUT_DIR, f"{base}_FORGED_CPU.mp4")
85
 
86
- progress(0, desc="फ़्रेम निकाल रहा हूँ...")
87
- os.makedirs("/tmp/frames_in", exist_ok=True)
88
- os.makedirs("/tmp/frames_out", exist_ok=True)
89
- subprocess.run(
90
- f"ffmpeg -i {input_path} -qscale:v 2 /tmp/frames_in/frame_%05d.jpg -y",
91
- shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
92
- )
93
 
94
- frames = sorted(os.listdir("/tmp/frames_in"))
95
- total = len(frames)
96
- progress(0.05, desc=f"कुल {total} फ़्रेम, CPU प्रोसेसिंग (धीमी) शुरू...")
97
 
98
- for idx, fname in enumerate(frames):
99
- img = cv2.imread(f"/tmp/frames_in/{fname}")
100
- if img is None:
101
- continue
102
- dyn_strength = strength_slider + random.uniform(-0.07, 0.07)
103
- dyn_strength = max(0.55, min(0.90, dyn_strength))
104
- seed = 2147 + idx * 17 + random.randint(0, 200)
105
- out_img = diffuse_frame_cpu(img, strength=dyn_strength, seed=seed)
106
- cv2.imwrite(f"/tmp/frames_out/{fname}", out_img)
107
-
108
- if idx % 5 == 0 or idx == total-1:
109
- pct = 5 + 90 * ((idx+1)/total)
110
- progress(pct/100, desc=f"{pct:.1f}% प्रगति (CPU)")
111
- elapsed = time.time() - start_total
112
- eta = (elapsed / (idx+1)) * (total - idx - 1) if idx > 0 else 0
113
- print(f"⚡ {pct:.1f}% | {idx+1}/{total} | शेष: {eta/60:.1f}मि (CPU)")
114
 
115
- progress(0.95, desc="ऑडियो + मर्ज...")
116
- subprocess.run(
117
- f"ffmpeg -i {input_path} -q:a 0 -map a /tmp/audio_orig.wav -y",
118
- shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
119
- )
120
- destroy_audio("/tmp/audio_orig.wav", "/tmp/audio_destroyed.wav")
 
 
 
 
 
 
 
 
121
 
122
- subprocess.run(
123
- f"ffmpeg -framerate 30 -i /tmp/frames_out/frame_%05d.jpg -c:v libx264 -crf 19 -preset veryfast -g 79 -bf 3 -timebase 1/48000 -vsync vfr /tmp/temp_vid.mp4 -y",
124
- shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
125
- )
126
- subprocess.run(
127
- f"ffmpeg -i /tmp/temp_vid.mp4 -i /tmp/audio_destroyed.wav -filter_complex '[1:a]adelay=150|150[a]' -map 0:v -map '[a]' -c:v copy -c:a aac -b:a 96k -shortest {out_video} -y",
128
- shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
129
- )
130
 
131
- with open(out_video, 'ab') as f:
132
- f.write(os.urandom(random.randint(100, 500)))
 
 
 
 
 
 
 
 
 
 
133
 
134
- shutil.rmtree("/tmp/frames_in", ignore_errors=True)
135
- shutil.rmtree("/tmp/frames_out", ignore_errors=True)
136
- safe_remove("/tmp/temp_vid.mp4")
137
- safe_remove("/tmp/audio_orig.wav")
138
- safe_remove("/tmp/audio_destroyed.wav")
 
 
139
 
140
- total_time = (time.time() - start_total) / 60
141
- progress(1, desc="✅ पूर्ण!")
142
- return out_video, f"✅ CPU पर {total_time:.1f} मिनट में फोर्ज पूर्ण। यह अभी भी ~90% तक YouTube को धोखा दे सकता है।"
 
 
 
 
 
 
 
 
 
 
143
 
144
- # ---------- Gradio UI ----------
145
- with gr.Blocks(title="☢️ वेस्टलैंड फोर्ज – CPU संस्करण") as demo:
 
146
  gr.Markdown("""
147
- ## ☢️ वेस्टलैंड फोर्ज MK-IV (CPU अनुकूलित)
148
- **यह उपकरण CPU पर भी चलता है हल्के मॉडल और कम स्टेप्स के साथ।**
149
- ⚡ **गति:** 1 मिनट के वीडियो में ~30-40 मिनट (CPU पर)।
150
- ⚠️ 100% नहीं, लेकिन 90% तक प्रभावी।
151
  """)
152
 
153
  with gr.Row():
154
  with gr.Column(scale=1):
155
- file_input = gr.File(label="📁 वीडियो अपलोड करें", file_types=[".mp4", ".avi", ".mov", ".mkv"])
156
- strength = gr.Slider(0.55, 0.90, value=0.78, step=0.01, label="🎛️ तीव्रता")
157
- submit_btn = gr.Button("🚀 फोर्ज करो", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  with gr.Column(scale=1):
159
- output_file = gr.File(label="⬇️ फोर्ज्ड वीडियो")
160
- status = gr.Textbox(label="📊 स्थिति", lines=3)
161
 
162
- submit_btn.click(
163
- fn=forge_video,
164
- inputs=[file_input, strength],
165
- outputs=[output_file, status]
 
166
  )
 
 
 
 
 
167
 
168
- if __name__ == "__main__":
169
- demo.launch(share=False) # Hugging Face पर share=False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+ import gradio as gr
3
+ from pathlib import Path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ # ─── SETUP ───
6
+ DOWNLOAD_DIR = Path("/content/downloads")
7
+ DOWNLOAD_DIR.mkdir(exist_ok=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ # ─── DOWNLOADER ENGINE ───
10
+ def download_video(url, quality, audio_only, platform):
11
+ if not url.strip():
12
+ return None, "❌ URL daalo!"
 
 
 
 
13
 
14
+ import yt_dlp
 
 
 
 
 
 
15
 
16
+ output_template = str(DOWNLOAD_DIR / '%(title)s.%(ext)s')
 
 
17
 
18
+ opts = {
19
+ 'outtmpl': output_template,
20
+ 'quiet': True,
21
+ 'no_warnings': True,
22
+ }
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ if audio_only:
25
+ opts['format'] = 'bestaudio/best'
26
+ opts['postprocessors'] = [{
27
+ 'key': 'FFmpegExtractAudio',
28
+ 'preferredcodec': 'mp3',
29
+ 'preferredquality': '320',
30
+ }]
31
+ elif quality == "Best":
32
+ opts['format'] = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best'
33
+ elif quality == "Worst":
34
+ opts['format'] = 'worst'
35
+ else:
36
+ h = quality.replace('p', '')
37
+ opts['format'] = f'bestvideo[height<={h}][ext=mp4]+bestaudio[ext=m4a]/best[height<={h}]'
38
 
39
+ if platform in ["Instagram", "TikTok", "Facebook"]:
40
+ opts['cookiesfrombrowser'] = 'chrome'
 
 
 
 
 
 
41
 
42
+ try:
43
+ with yt_dlp.YoutubeDL(opts) as ydl:
44
+ info = ydl.extract_info(url, download=True)
45
+ filename = ydl.prepare_filename(info)
46
+
47
+ if audio_only:
48
+ filename = filename.replace('.webm', '.mp3').replace('.m4a', '.mp3')
49
+
50
+ fpath = Path(filename)
51
+ size_mb = fpath.stat().st_size / 1024 / 1024 if fpath.exists() else 0
52
+
53
+ return str(filename), f"✅ Done!\nTitle: {info.get('title', 'Unknown')}\nSize: {size_mb:.1f} MB\nBy: {info.get('uploader', 'Unknown')}"
54
 
55
+ except Exception as e:
56
+ return None, f"❌ Error: {str(e)[:200]}"
57
+
58
+
59
+ def get_video_info(url):
60
+ if not url.strip():
61
+ return "❌ URL daalo!"
62
 
63
+ import yt_dlp
64
+ try:
65
+ with yt_dlp.YoutubeDL({'quiet': True}) as ydl:
66
+ info = ydl.extract_info(url, download=False)
67
+ return f"""
68
+ 🎬 **{info.get('title', 'Unknown')}**
69
+ 👤 Uploader: {info.get('uploader', 'Unknown')}
70
+ ⏱️ Duration: {info.get('duration', 0)//60}m {info.get('duration', 0)%60}s
71
+ 👁️ Views: {info.get('view_count', 0):,}
72
+ 📺 Platform: {info.get('extractor', 'Unknown')}
73
+ """
74
+ except Exception as e:
75
+ return f"❌ Error: {str(e)[:200]}"
76
 
77
+
78
+ # ─── GRADIO UI ───
79
+ with gr.Blocks(title="☢️ Nuclear Downloader") as app:
80
  gr.Markdown("""
81
+ # ☢️ Nuclear Video Downloader
82
+ ### YouTube | Instagram | TikTok | Facebook | Twitter | Reddit | +1000 sites
 
 
83
  """)
84
 
85
  with gr.Row():
86
  with gr.Column(scale=1):
87
+ url_input = gr.Textbox(
88
+ label="🔗 Video URL",
89
+ placeholder="https://...",
90
+ lines=2
91
+ )
92
+ platform = gr.Dropdown(
93
+ label="📱 Platform",
94
+ choices=["Auto-Detect", "YouTube", "Instagram", "TikTok", "Facebook", "Twitter/X", "Reddit", "Vimeo"],
95
+ value="Auto-Detect"
96
+ )
97
+ quality = gr.Dropdown(
98
+ label="🎞️ Quality",
99
+ choices=["Best", "1080p", "720p", "480p", "360p", "Worst"],
100
+ value="Best"
101
+ )
102
+ audio_only = gr.Checkbox(label="🎵 Audio Only (MP3)", value=False)
103
+
104
+ with gr.Row():
105
+ info_btn = gr.Button("ℹ️ Get Info", variant="secondary")
106
+ download_btn = gr.Button("⬇️ Download", variant="primary")
107
+
108
  with gr.Column(scale=1):
109
+ output_file = gr.File(label="📥 Downloaded File")
110
+ status_text = gr.Textbox(label="📋 Status", lines=6, interactive=False)
111
 
112
+ info_btn.click(fn=get_video_info, inputs=url_input, outputs=status_text)
113
+ download_btn.click(
114
+ fn=download_video,
115
+ inputs=[url_input, quality, audio_only, platform],
116
+ outputs=[output_file, status_text]
117
  )
118
+
119
+ gr.Markdown("""
120
+ ---
121
+ ⚠️ **Note:** Link active jab tak Colab runtime chalega.
122
+ """)
123
 
124
+ # ─── LAUNCH WITH PUBLIC SHARE ───
125
+ print("🚀 Creating public link...")
126
+ print("⏳ Thoda wait karo...")
127
+
128
+ app.launch(
129
+ server_name="0.0.0.0",
130
+ server_port=7860,
131
+ share=True, # ← THIS = Automatic public link
132
+ quiet=True,
133
+ show_error=True
134
+ )