Spaces:
tester343
/
Configuration error

tester343 commited on
Commit
91c74fc
Β·
verified Β·
1 Parent(s): a280bc6

Update app_enhanced.py

Browse files
Files changed (1) hide show
  1. app_enhanced.py +34 -31
app_enhanced.py CHANGED
@@ -15,15 +15,21 @@ import torch
15
  from flask import Flask, jsonify, request, send_from_directory, send_file
16
 
17
  # ======================================================
18
- # πŸš€ CUDA CONFIGURATION
19
  # ======================================================
20
- def check_cuda():
21
- """Checks for CUDA availability without ZeroGPU decorators"""
22
  if torch.cuda.is_available():
23
- print(f"βœ… CUDA Engine Active: {torch.cuda.get_device_name(0)}")
 
 
 
 
 
 
24
  return True
25
  else:
26
- print("⚠️ CUDA Not Detected. Running on CPU (Expect slower generation)")
27
  return False
28
 
29
  # ======================================================
@@ -60,8 +66,9 @@ app = Flask(__name__)
60
  BASE_USER_DIR = "userdata"
61
  SAVED_COMICS_DIR = "saved_comics"
62
 
63
- os.makedirs(BASE_USER_DIR, exist_ok=True)
64
- os.makedirs(SAVED_COMICS_DIR, exist_ok=True)
 
65
 
66
  def generate_save_code(length=8):
67
  chars = string.ascii_uppercase + string.digits
@@ -71,16 +78,13 @@ def generate_save_code(length=8):
71
  return code
72
 
73
  # ======================================================
74
- # 🧠 CORE PROCESSING FUNCTIONS (Standard CUDA)
75
- # ======================================================
76
- # Removed @spaces.GPU decorators. These functions now run
77
- # directly in the thread/process invoking them.
78
  # ======================================================
79
 
80
  def generate_comic_core(video_path, user_dir, frames_dir, metadata_path, target_pages):
81
- print(f"πŸš€ Processing Task Started: {video_path} | Pages: {target_pages}")
82
 
83
- # Import backend logic here to ensure they load into the correct context
84
  from backend.keyframes.keyframes import black_bar_crop
85
  from backend.simple_color_enhancer import SimpleColorEnhancer
86
  from backend.quality_color_enhancer import QualityColorEnhancer
@@ -99,18 +103,17 @@ def generate_comic_core(video_path, user_dir, frames_dir, metadata_path, target_
99
  # 2. Subtitles Generation
100
  user_srt = os.path.join(user_dir, 'subs.srt')
101
  try:
 
102
  get_real_subtitles(video_path)
103
  if os.path.exists('test1.srt'):
104
  shutil.move('test1.srt', user_srt)
105
  except Exception as e:
106
- print(f"Subtitle error (using placeholder): {e}")
107
  with open(user_srt, 'w') as f: f.write("1\n00:00:01,000 --> 00:00:04,000\n...\n")
108
 
109
  with open(user_srt, 'r', encoding='utf-8') as f:
110
- try:
111
- all_subs = list(srt.parse(f.read()))
112
- except:
113
- all_subs = []
114
 
115
  # 3. Smart Keyframe Selection
116
  valid_subs = [s for s in all_subs if s.content.strip()]
@@ -152,11 +155,11 @@ def generate_comic_core(video_path, user_dir, frames_dir, metadata_path, target_
152
 
153
  with open(metadata_path, 'w') as f: json.dump(frame_metadata, f, indent=2)
154
 
155
- # 5. Image Enhancement
156
  try: black_bar_crop()
157
  except: pass
158
 
159
- # Initialize enhancers (they usually load models to CUDA if available)
160
  se = SimpleColorEnhancer()
161
  qe = QualityColorEnhancer()
162
 
@@ -167,7 +170,7 @@ def generate_comic_core(video_path, user_dir, frames_dir, metadata_path, target_
167
  try: qe.enhance_single(p, p)
168
  except: pass
169
 
170
- # 6. Bubble Placement
171
  bubbles_list = []
172
  for f in frame_files_ordered:
173
  p = os.path.join(frames_dir, f)
@@ -280,8 +283,8 @@ class EnhancedComicGenerator:
280
 
281
  def run(self, target_pages):
282
  try:
283
- self.write_status("Waiting for GPU/Processor...", 5)
284
- # Directly call the core function (standard CUDA)
285
  data = generate_comic_core(self.video_path, self.user_dir, self.frames_dir, self.metadata_path, int(target_pages))
286
  with open(os.path.join(self.output_dir, 'pages.json'), 'w') as f:
287
  json.dump(data, f, indent=2)
@@ -303,7 +306,7 @@ INDEX_HTML = '''
303
  <head>
304
  <meta charset="UTF-8">
305
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
306
- <title>🎬 Enhanced Comic Generator</title>
307
  <script src="https://cdnjs.cloudflare.com/ajax/libs/html-to-image/1.11.11/html-to-image.min.js"></script>
308
  <link href="https://fonts.googleapis.com/css2?family=Bangers&family=Comic+Neue:wght@700&family=Gloria+Hallelujah&family=Lato&display=swap" rel="stylesheet">
309
  <style>
@@ -446,7 +449,7 @@ INDEX_HTML = '''
446
  <body>
447
  <div id="upload-container">
448
  <div class="upload-box">
449
- <h1>🎬 Enhanced Comic Generator</h1>
450
  <input type="file" id="file-upload" class="file-input" onchange="document.getElementById('fn').innerText=this.files[0].name">
451
  <label for="file-upload" class="file-label">πŸ“ Choose Video File</label>
452
  <span id="fn" style="margin-bottom:10px; display:block; color:#666;">No file selected</span>
@@ -455,7 +458,7 @@ INDEX_HTML = '''
455
  <input type="number" id="page-count" value="4" min="1" max="15" placeholder="e.g. 4">
456
  <small style="color:#666; font-size:11px; display:block; margin-top:5px;">System calculates ~4 panels per page.</small>
457
  </div>
458
- <button class="submit-btn" onclick="upload()">πŸš€ Generate Comic</button>
459
  <button id="restore-draft-btn" class="restore-btn" style="display:none; margin-top:15px;" onclick="restoreDraft()">πŸ“‚ Restore Unsaved Draft</button>
460
  <div class="load-section">
461
  <h3>πŸ“₯ Load Saved Comic</h3>
@@ -466,7 +469,7 @@ INDEX_HTML = '''
466
  </div>
467
  <div class="loading-view" id="loading-view" style="display:none; margin-top:20px;">
468
  <div class="loader" style="margin:0 auto;"></div>
469
- <p id="status-text" style="margin-top:10px;">Starting...</p>
470
  </div>
471
  </div>
472
  </div>
@@ -903,7 +906,7 @@ def upload():
903
  f.save(gen.video_path)
904
  gen.write_status("Starting...", 5)
905
 
906
- # Run in thread - Standard processing
907
  threading.Thread(target=gen.run, args=(target_pages,)).start()
908
  return jsonify({'success': True, 'message': 'Generation started.'})
909
 
@@ -929,7 +932,7 @@ def regen():
929
  sid = request.args.get('sid')
930
  d = request.get_json()
931
  gen = EnhancedComicGenerator(sid)
932
- # Direct function call
933
  return jsonify(regen_frame_core(gen.video_path, gen.frames_dir, gen.metadata_path, d['filename'], d['direction']))
934
 
935
  @app.route('/goto_timestamp', methods=['POST'])
@@ -937,7 +940,7 @@ def go_time():
937
  sid = request.args.get('sid')
938
  d = request.get_json()
939
  gen = EnhancedComicGenerator(sid)
940
- # Direct function call
941
  return jsonify(get_frame_at_ts_core(gen.video_path, gen.frames_dir, gen.metadata_path, d['filename'], float(d['timestamp'])))
942
 
943
  @app.route('/replace_panel', methods=['POST'])
@@ -1004,5 +1007,5 @@ def load_comic(code):
1004
  return jsonify({'success': False, 'message': str(e)})
1005
 
1006
  if __name__ == '__main__':
1007
- check_cuda()
1008
  app.run(host='0.0.0.0', port=7860)
 
15
  from flask import Flask, jsonify, request, send_from_directory, send_file
16
 
17
  # ======================================================
18
+ # πŸš€ H100 / CUDA CONFIGURATION
19
  # ======================================================
20
+ def initialize_h100():
21
+ """Checks and initializes the H100 GPU environment"""
22
  if torch.cuda.is_available():
23
+ gpu_name = torch.cuda.get_device_name(0)
24
+ vram = torch.cuda.get_device_properties(0).total_memory / 1e9
25
+ print(f"\n{'='*40}")
26
+ print(f"βœ… H100 DETECTED: {gpu_name}")
27
+ print(f"πŸš€ VRAM AVAILABLE: {vram:.2f} GB")
28
+ print(f"βœ… CUDA Version: {torch.version.cuda}")
29
+ print(f"{'='*40}\n")
30
  return True
31
  else:
32
+ print("\n⚠️ WARNING: CUDA NOT DETECTED. Running on CPU (H100 not active?)\n")
33
  return False
34
 
35
  # ======================================================
 
66
  BASE_USER_DIR = "userdata"
67
  SAVED_COMICS_DIR = "saved_comics"
68
 
69
+ # Ensure write permissions for Docker environment
70
+ os.makedirs(BASE_USER_DIR, mode=0o777, exist_ok=True)
71
+ os.makedirs(SAVED_COMICS_DIR, mode=0o777, exist_ok=True)
72
 
73
  def generate_save_code(length=8):
74
  chars = string.ascii_uppercase + string.digits
 
78
  return code
79
 
80
  # ======================================================
81
+ # 🧠 CORE LOGIC (Native CUDA)
 
 
 
82
  # ======================================================
83
 
84
  def generate_comic_core(video_path, user_dir, frames_dir, metadata_path, target_pages):
85
+ print(f"πŸš€ Processing Started on H100: {video_path}")
86
 
87
+ # Imports inside function to ensure they use the initialized CUDA context
88
  from backend.keyframes.keyframes import black_bar_crop
89
  from backend.simple_color_enhancer import SimpleColorEnhancer
90
  from backend.quality_color_enhancer import QualityColorEnhancer
 
103
  # 2. Subtitles Generation
104
  user_srt = os.path.join(user_dir, 'subs.srt')
105
  try:
106
+ # This will use the GPU for Whisper/ASR if implemented in backend
107
  get_real_subtitles(video_path)
108
  if os.path.exists('test1.srt'):
109
  shutil.move('test1.srt', user_srt)
110
  except Exception as e:
111
+ print(f"Subtitle generation skipped/failed: {e}")
112
  with open(user_srt, 'w') as f: f.write("1\n00:00:01,000 --> 00:00:04,000\n...\n")
113
 
114
  with open(user_srt, 'r', encoding='utf-8') as f:
115
+ try: all_subs = list(srt.parse(f.read()))
116
+ except: all_subs = []
 
 
117
 
118
  # 3. Smart Keyframe Selection
119
  valid_subs = [s for s in all_subs if s.content.strip()]
 
155
 
156
  with open(metadata_path, 'w') as f: json.dump(frame_metadata, f, indent=2)
157
 
158
+ # 5. Image Enhancement (GPU Accelerated)
159
  try: black_bar_crop()
160
  except: pass
161
 
162
+ # Initialize enhancers - these should load to GPU automatically if backend supports it
163
  se = SimpleColorEnhancer()
164
  qe = QualityColorEnhancer()
165
 
 
170
  try: qe.enhance_single(p, p)
171
  except: pass
172
 
173
+ # 6. Bubble Placement (Uses Face Detection on GPU)
174
  bubbles_list = []
175
  for f in frame_files_ordered:
176
  p = os.path.join(frames_dir, f)
 
283
 
284
  def run(self, target_pages):
285
  try:
286
+ self.write_status("Waiting for H100...", 5)
287
+ # Direct call to core function (no decorator)
288
  data = generate_comic_core(self.video_path, self.user_dir, self.frames_dir, self.metadata_path, int(target_pages))
289
  with open(os.path.join(self.output_dir, 'pages.json'), 'w') as f:
290
  json.dump(data, f, indent=2)
 
306
  <head>
307
  <meta charset="UTF-8">
308
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
309
+ <title>🎬 H100 Comic Studio</title>
310
  <script src="https://cdnjs.cloudflare.com/ajax/libs/html-to-image/1.11.11/html-to-image.min.js"></script>
311
  <link href="https://fonts.googleapis.com/css2?family=Bangers&family=Comic+Neue:wght@700&family=Gloria+Hallelujah&family=Lato&display=swap" rel="stylesheet">
312
  <style>
 
449
  <body>
450
  <div id="upload-container">
451
  <div class="upload-box">
452
+ <h1>🎬 H100 Comic Studio</h1>
453
  <input type="file" id="file-upload" class="file-input" onchange="document.getElementById('fn').innerText=this.files[0].name">
454
  <label for="file-upload" class="file-label">πŸ“ Choose Video File</label>
455
  <span id="fn" style="margin-bottom:10px; display:block; color:#666;">No file selected</span>
 
458
  <input type="number" id="page-count" value="4" min="1" max="15" placeholder="e.g. 4">
459
  <small style="color:#666; font-size:11px; display:block; margin-top:5px;">System calculates ~4 panels per page.</small>
460
  </div>
461
+ <button class="submit-btn" onclick="upload()">πŸš€ Generate Comic (H100 Speed)</button>
462
  <button id="restore-draft-btn" class="restore-btn" style="display:none; margin-top:15px;" onclick="restoreDraft()">πŸ“‚ Restore Unsaved Draft</button>
463
  <div class="load-section">
464
  <h3>πŸ“₯ Load Saved Comic</h3>
 
469
  </div>
470
  <div class="loading-view" id="loading-view" style="display:none; margin-top:20px;">
471
  <div class="loader" style="margin:0 auto;"></div>
472
+ <p id="status-text" style="margin-top:10px;">Firing up the H100...</p>
473
  </div>
474
  </div>
475
  </div>
 
906
  f.save(gen.video_path)
907
  gen.write_status("Starting...", 5)
908
 
909
+ # Run in thread - Standard H100 processing
910
  threading.Thread(target=gen.run, args=(target_pages,)).start()
911
  return jsonify({'success': True, 'message': 'Generation started.'})
912
 
 
932
  sid = request.args.get('sid')
933
  d = request.get_json()
934
  gen = EnhancedComicGenerator(sid)
935
+ # Direct function call - H100
936
  return jsonify(regen_frame_core(gen.video_path, gen.frames_dir, gen.metadata_path, d['filename'], d['direction']))
937
 
938
  @app.route('/goto_timestamp', methods=['POST'])
 
940
  sid = request.args.get('sid')
941
  d = request.get_json()
942
  gen = EnhancedComicGenerator(sid)
943
+ # Direct function call - H100
944
  return jsonify(get_frame_at_ts_core(gen.video_path, gen.frames_dir, gen.metadata_path, d['filename'], float(d['timestamp'])))
945
 
946
  @app.route('/replace_panel', methods=['POST'])
 
1007
  return jsonify({'success': False, 'message': str(e)})
1008
 
1009
  if __name__ == '__main__':
1010
+ initialize_h100()
1011
  app.run(host='0.0.0.0', port=7860)