sh4lu-z commited on
Commit
bccc38b
·
verified ·
1 Parent(s): b121970

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -56
app.py CHANGED
@@ -2,11 +2,15 @@ from flask import Flask, request, send_file, jsonify
2
  import os
3
  import subprocess
4
  import uuid
 
 
 
5
 
6
  app = Flask(__name__)
7
  UPLOAD_FOLDER = "uploads"
8
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
9
 
 
10
  def get_video_duration(input_path):
11
  try:
12
  result = subprocess.run(
@@ -15,20 +19,17 @@ def get_video_duration(input_path):
15
  )
16
  return float(result.stdout)
17
  except:
18
- return 10.0
19
 
20
- def convert_video(input_path, output_path, conf):
21
- # conf කියන්නේ අපි යවන settings object එක
22
  duration = conf['t']
23
  fps = conf['fps']
24
  quality = conf['q']
25
- scale_size = conf['s'] # අලුත් Feature එක: Size එක වෙනස් කරන්න පුළුවන් (512, 400, 320)
26
-
27
- # 🎨 PREMIUM BLUR FILTER Logic
28
- # 1. වීඩියෝ එක මැදට ගන්නවා (Scale කරලා).
29
- # 2. වටේට ඒ වීඩියෝ එකම ලොකු කරලා Blur කරලා දානවා.
30
- # 3. අන්තිමට මුළු ස්ටිකර් එකම අපි තීරණය කරන Size එකට (scale_size) හදනවා.
31
 
 
 
32
  filter_complex = (
33
  f"split[bg][fg];"
34
  f"[bg]scale={scale_size}:{scale_size}:force_original_aspect_ratio=increase,crop={scale_size}:{scale_size},boxblur=20:10[bg_blurred];"
@@ -37,19 +38,18 @@ def convert_video(input_path, output_path, conf):
37
  )
38
 
39
  command = [
40
- "ffmpeg", "-y", "-i", input_path,
 
 
41
  "-vf", f"{filter_complex},fps={fps}",
42
  "-vcodec", "libwebp",
43
  "-lossless", "0",
44
-
45
- # 🔥 ULTRA COMPRESSION (16GB RAM POWER)
46
- "-compression_level", "6", # මේක දැම්මම හොඳටම Compress වෙනවා quality යන්නේ නැතුව. (CPU heavy)
47
  "-preset", "default",
48
-
49
  "-q:v", str(quality),
50
  "-loop", "0",
51
  "-an",
52
- "-t", str(duration),
53
  output_path
54
  ]
55
 
@@ -62,10 +62,13 @@ def convert_video(input_path, output_path, conf):
62
 
63
  @app.route("/")
64
  def home():
65
- return "🔥 High-End Sticker Engine (Pro Logic) is Running!"
66
 
 
 
 
67
  @app.route("/sticker", methods=["POST"])
68
- def make_sticker():
69
  if 'file' not in request.files:
70
  return jsonify({"error": "No file uploaded"}), 400
71
 
@@ -82,64 +85,108 @@ def make_sticker():
82
 
83
  if is_animated:
84
  original_duration = get_video_duration(input_path)
85
-
86
- # අපි උපරිම තත්පර 10 කට ට්‍රයි කරමු මුලින්.
87
  target_duration = min(original_duration, 10.0)
88
 
89
- # =========================================================
90
- # 🧠 PRO-APP LOGIC (Priority List)
91
- # =========================================================
92
- # ඇත්ත ඇප් වල වගේ පියවරෙන් පියවර ට්‍රයි කරනවා.
93
-
94
  attempts = [
95
- # 1. BEST QUALITY (512px, High Quality, Max Duration)
96
- {"s": 512, "q": 60, "fps": 15, "t": target_duration},
97
-
98
- # 2. SMART RESIZE (512px -> 384px) - මේක තමයි රහස.
99
- # 384px කියන්නේ ෆෝන් එකට හොඳටම ඇති. හැබැයි සයිස් එක 40% කින් අඩුවෙනවා.
100
- {"s": 384, "q": 50, "fps": 15, "t": target_duration},
101
-
102
- # 3. IF STILL BIG -> Reduce FPS & Duration slightly
103
- {"s": 384, "q": 40, "fps": 12, "t": min(target_duration, 7.0)},
104
-
105
- # 4. EMERGENCY MODE (Phone එකේ Data ඉතුරු කරන mode එක වගේ)
106
- # 320px වලට බස්සනවා.
107
- {"s": 320, "q": 35, "fps": 10, "t": min(target_duration, 5.0)}
108
  ]
109
 
110
  for i, conf in enumerate(attempts):
111
- print(f"🔄 Attempt {i+1}: Size={conf['s']}px, Q={conf['q']}, Time={conf['t']}s")
112
-
113
- if convert_video(input_path, output_path, conf):
114
  size = os.path.getsize(output_path)
115
- print(f"📦 Result Size: {size/1024:.2f} KB")
116
-
117
- # 900KB Safe Limit (WhatsApp limit is 1MB strictly)
118
- if size < 980000:
119
  success = True
120
- break # Success!
121
- else:
122
- print("⚠️ Too big! Trying next optimization method...")
123
-
124
  else:
125
- # Static Images (High Quality)
126
- cmd = ["ffmpeg", "-y", "-i", input_path,
127
- "-vf", "scale='if(gt(iw,ih),512,-1)':'if(gt(iw,ih),-1,512)',scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000",
128
- "-vcodec", "libwebp", "-lossless", "0", "-q:v", "85", output_path]
129
  try:
130
  subprocess.run(cmd, check=True)
131
  success = True
132
  except:
133
  success = False
134
 
135
- # Cleanup
136
- if os.path.exists(input_path):
137
- os.remove(input_path)
138
 
139
  if success and os.path.exists(output_path):
140
  return send_file(output_path, mimetype='image/webp')
141
  else:
142
- return jsonify({"error": "Failed to create sticker within 1MB limit"}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
  if __name__ == "__main__":
145
  app.run(host="0.0.0.0", port=7860)
 
2
  import os
3
  import subprocess
4
  import uuid
5
+ import shutil
6
+ import zipfile
7
+ import math
8
 
9
  app = Flask(__name__)
10
  UPLOAD_FOLDER = "uploads"
11
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
12
 
13
+ # වීඩියෝ එකේ කාලය (Duration) ගන්න ෆන්ෂන් එක
14
  def get_video_duration(input_path):
15
  try:
16
  result = subprocess.run(
 
19
  )
20
  return float(result.stdout)
21
  except:
22
+ return 0.0
23
 
24
+ # 🎨 UNIVERSAL CONVERTER ENGINE (මේක තමයි හැම වැඩේම කරන්නේ)
25
+ def convert_segment(input_path, output_path, conf, start_time=0):
26
  duration = conf['t']
27
  fps = conf['fps']
28
  quality = conf['q']
29
+ scale_size = conf['s']
 
 
 
 
 
30
 
31
+ # 🌟 Blur Filter Logic (Smart Resize එක්ක)
32
+ # 512px, 384px, 320px ඕන එකකට හරියන්න මේක හැදෙනවා
33
  filter_complex = (
34
  f"split[bg][fg];"
35
  f"[bg]scale={scale_size}:{scale_size}:force_original_aspect_ratio=increase,crop={scale_size}:{scale_size},boxblur=20:10[bg_blurred];"
 
38
  )
39
 
40
  command = [
41
+ "ffmpeg", "-y",
42
+ "-ss", str(start_time), # පටන් ගන්න තැන (Pack එකට ඕන වෙනවා)
43
+ "-i", input_path,
44
  "-vf", f"{filter_complex},fps={fps}",
45
  "-vcodec", "libwebp",
46
  "-lossless", "0",
47
+ "-compression_level", "6", # Ultra Compression
 
 
48
  "-preset", "default",
 
49
  "-q:v", str(quality),
50
  "-loop", "0",
51
  "-an",
52
+ "-t", str(duration), # කොච්චර වෙලා කපනවද
53
  output_path
54
  ]
55
 
 
62
 
63
  @app.route("/")
64
  def home():
65
+ return "🔥 Cipher_MD Smart Engine (Guaranteed < 1MB) Running!"
66
 
67
+ # ================================================================
68
+ # 1. SINGLE STICKER ROUTE (SMART LOOP ENABLED ✅)
69
+ # ================================================================
70
  @app.route("/sticker", methods=["POST"])
71
+ def make_single_sticker():
72
  if 'file' not in request.files:
73
  return jsonify({"error": "No file uploaded"}), 400
74
 
 
85
 
86
  if is_animated:
87
  original_duration = get_video_duration(input_path)
 
 
88
  target_duration = min(original_duration, 10.0)
89
 
90
+ # 🧠 SMART LOOP (Priority List)
91
+ # එකින් එක ට්‍රයි කරලා 1MB ට අඩු එකක් හම්බෙනකම් දුවනවා
 
 
 
92
  attempts = [
93
+ {"s": 512, "q": 50, "fps": 15, "t": target_duration}, # Attempt 1
94
+ {"s": 384, "q": 45, "fps": 12, "t": target_duration}, # Attempt 2 (Resize)
95
+ {"s": 320, "q": 40, "fps": 12, "t": min(target_duration, 7.0)}, # Attempt 3 (Time Cut)
96
+ {"s": 256, "q": 30, "fps": 10, "t": min(target_duration, 5.0)} # Emergency (Low Quality)
 
 
 
 
 
 
 
 
 
97
  ]
98
 
99
  for i, conf in enumerate(attempts):
100
+ print(f"🔄 Single Attempt {i+1}: Size={conf['s']}px...")
101
+ if convert_segment(input_path, output_path, conf, start_time=0):
 
102
  size = os.path.getsize(output_path)
103
+ print(f"📦 Size: {size/1024:.2f} KB")
104
+
105
+ if size < 980000: # 980KB Safe Limit
 
106
  success = True
107
+ break
 
 
 
108
  else:
109
+ # Static Image Logic
110
+ cmd = ["ffmpeg", "-y", "-i", input_path, "-vf", "scale='if(gt(iw,ih),512,-1)':'if(gt(iw,ih),-1,512)',scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000", "-vcodec", "libwebp", "-lossless", "0", "-q:v", "80", output_path]
 
 
111
  try:
112
  subprocess.run(cmd, check=True)
113
  success = True
114
  except:
115
  success = False
116
 
117
+ if os.path.exists(input_path): os.remove(input_path)
 
 
118
 
119
  if success and os.path.exists(output_path):
120
  return send_file(output_path, mimetype='image/webp')
121
  else:
122
+ return jsonify({"error": "Failed to generate valid sticker"}), 500
123
+
124
+ # ================================================================
125
+ # 2. HEAVY PACK ROUTE (SMART LOOP FOR EVERY SEGMENT ✅)
126
+ # ================================================================
127
+ @app.route("/pack", methods=["POST"])
128
+ def make_pack():
129
+ if 'file' not in request.files:
130
+ return jsonify({"error": "No file uploaded"}), 400
131
+
132
+ file = request.files['file']
133
+ request_id = str(uuid.uuid4())
134
+
135
+ pack_folder = os.path.join(UPLOAD_FOLDER, request_id)
136
+ os.makedirs(pack_folder, exist_ok=True)
137
+
138
+ input_path = os.path.join(pack_folder, "video.mp4")
139
+ file.save(input_path)
140
+
141
+ duration = get_video_duration(input_path)
142
+ if duration > 130:
143
+ shutil.rmtree(pack_folder)
144
+ return jsonify({"error": "Video too long (Max 2 mins)"}), 400
145
+
146
+ sticker_files = []
147
+ num_segments = math.ceil(duration / 10)
148
+
149
+ # 🔄 හැම කෑල්ලක්ම Loop එකක් ඇතුලේ Process කරනවා
150
+ for i in range(num_segments):
151
+ start_time = i * 10
152
+ output_name = f"{i+1}.webp"
153
+ output_full_path = os.path.join(pack_folder, output_name)
154
+
155
+ segment_duration = min(10, duration - start_time)
156
+ if segment_duration < 1: continue
157
+
158
+ # 🧠 PACK SMART LOOP (මේක තමයි කලින් මිස් වුනේ!)
159
+ # හැම Sticker කෑල්ලක්ම 1MB ට අඩු වෙනකම් Resize කරනවා
160
+ attempts = [
161
+ {"s": 512, "q": 50, "fps": 15, "t": segment_duration},
162
+ {"s": 384, "q": 45, "fps": 12, "t": segment_duration},
163
+ {"s": 320, "q": 40, "fps": 10, "t": segment_duration},
164
+ {"s": 256, "q": 30, "fps": 10, "t": segment_duration}
165
+ ]
166
+
167
+ converted = False
168
+ for conf in attempts:
169
+ print(f"📦 Pack Segment {i+1}: Trying Size={conf['s']}...")
170
+ if convert_segment(input_path, output_full_path, conf, start_time=start_time):
171
+ if os.path.getsize(output_full_path) < 980000:
172
+ sticker_files.append(output_full_path)
173
+ converted = True
174
+ break # හරි ගියොත් ඊළඟ කෑල්ලට යනවා
175
+
176
+ # කොහොමවත් බැරි වුනොත් අන්තිම Output එක හරි ගන්නවා (Fail නොවෙන්න)
177
+ if not converted and os.path.exists(output_full_path):
178
+ sticker_files.append(output_full_path)
179
+
180
+ # ZIP File එක හදනවා
181
+ zip_path = os.path.join(UPLOAD_FOLDER, f"{request_id}.zip")
182
+ with zipfile.ZipFile(zip_path, 'w') as zipf:
183
+ for sticker in sticker_files:
184
+ zipf.write(sticker, arcname=os.path.basename(sticker))
185
+
186
+ # Cleanup
187
+ shutil.rmtree(pack_folder)
188
+
189
+ return send_file(zip_path, mimetype='application/zip', as_attachment=True, download_name=f"{request_id}.zip")
190
 
191
  if __name__ == "__main__":
192
  app.run(host="0.0.0.0", port=7860)