openfree commited on
Commit
e9a7e97
Β·
verified Β·
1 Parent(s): 9c99701

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -26
app.py CHANGED
@@ -4,6 +4,9 @@ import numpy as np
4
  import os
5
  import zipfile
6
  from PIL import Image
 
 
 
7
 
8
  def get_video_duration(video_path):
9
  cap = cv2.VideoCapture(video_path)
@@ -13,7 +16,7 @@ def get_video_duration(video_path):
13
  cap.release()
14
  return duration
15
 
16
- def extract_frames(video_path, output_dir, start_time, end_time):
17
  cap = cv2.VideoCapture(video_path)
18
  fps = cap.get(cv2.CAP_PROP_FPS)
19
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
@@ -24,41 +27,46 @@ def extract_frames(video_path, output_dir, start_time, end_time):
24
  frames = []
25
  cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
26
 
27
- for i in range(start_frame, min(end_frame, total_frames)):
 
 
 
28
  ret, frame = cap.read()
29
  if not ret:
30
  break
31
  frames.append(frame)
 
 
32
 
33
  cap.release()
34
  return frames
35
 
36
- def create_grid(frames, grid_size=(10, 9)):
37
  rows, cols = grid_size
 
 
 
38
  frame_height, frame_width = frames[0].shape[:2]
39
  grid = np.zeros((frame_height * rows, frame_width * cols, 3), dtype=np.uint8)
40
 
41
  for i, frame in enumerate(frames):
42
- if i >= rows * cols:
43
- break
44
  row = i // cols
45
  col = i % cols
46
  grid[row*frame_height:(row+1)*frame_height, col*frame_width:(col+1)*frame_width] = frame
47
 
48
  return grid
49
 
50
- def save_frames(frames, output_dir):
51
  os.makedirs(output_dir, exist_ok=True)
52
- for i, frame in enumerate(frames):
53
  cv2.imwrite(os.path.join(output_dir, f"frame_{i:04d}.jpg"), frame)
54
 
55
- def create_zip(output_dir):
56
  zip_path = os.path.join(output_dir, "frames.zip")
57
  with zipfile.ZipFile(zip_path, 'w') as zipf:
58
- for root, _, files in os.walk(output_dir):
59
- for file in files:
60
- if file.endswith('.jpg'):
61
- zipf.write(os.path.join(root, file), file)
62
  return zip_path
63
 
64
  def update_slider(video):
@@ -67,9 +75,7 @@ def update_slider(video):
67
  duration = get_video_duration(video.name)
68
  return gr.Slider(minimum=0, maximum=duration, value=0, step=0.1, label="CUT μ‹œμž‘ μ‹œκ°„ (초)"), gr.Slider(minimum=0, maximum=duration, value=duration, step=0.1, label="CUT μ’…λ£Œ μ‹œκ°„ (초)")
69
 
70
-
71
-
72
- def process_video(video, start_time, end_time):
73
  if video is None:
74
  return None, None, "λΉ„λ””μ˜€ νŒŒμΌμ„ μ—…λ‘œλ“œν•΄μ£Όμ„Έμš”."
75
 
@@ -78,16 +84,20 @@ def process_video(video, start_time, end_time):
78
  if file_size > 2 * 1024 * 1024 * 1024: # 2GB in bytes
79
  return None, None, "파일 크기가 2GBλ₯Ό μ΄ˆκ³Όν•©λ‹ˆλ‹€. 더 μž‘μ€ νŒŒμΌμ„ μ—…λ‘œλ“œν•΄μ£Όμ„Έμš”."
80
 
81
- output_dir = "output_frames"
82
- frames = extract_frames(video.name, output_dir, start_time, end_time)
83
- if not frames:
84
- return None, None, "ν”„λ ˆμž„ μΆ”μΆœμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€. λΉ„λ””μ˜€ νŒŒμΌμ„ ν™•μΈν•΄μ£Όμ„Έμš”."
85
-
86
- save_frames(frames, output_dir)
87
- grid = create_grid(frames)
88
- zip_path = create_zip(output_dir)
 
 
 
 
89
 
90
- return Image.fromarray(cv2.cvtColor(grid, cv2.COLOR_BGR2RGB)), zip_path, "ν”„λ ˆμž„ μΆ”μΆœμ΄ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€."
91
  except Exception as e:
92
  return None, None, f"였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€: {str(e)}"
93
 
@@ -121,7 +131,7 @@ document.addEventListener('DOMContentLoaded', () => {
121
  with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, js=js) as iface:
122
  gr.Markdown("# λΉ„λ””μ˜€ to 이미지(ν”„λ ˆμž„)")
123
  gr.Markdown("μ›ν•˜λŠ” κ΅¬κ°„μ˜ ν”„λ ˆμž„μ„ μΆ”μΆœν•˜μ—¬ κ·Έλ¦¬λ“œλ‘œ ν‘œμ‹œν•˜κ³ , κ°œλ³„ 이미지λ₯Ό ZIP 파일둜 λ‹€μš΄λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.")
124
- gr.Markdown("μ΅œλŒ€ 2GB 크기의 λΉ„λ””μ˜€ νŒŒμΌμ„ μ—…λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.")
125
 
126
  with gr.Row():
127
  video_input = gr.Video(label="Upload and Play Video")
@@ -146,4 +156,4 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, js=js) as iface:
146
  process_button.click(process_video, inputs=[video_input, start_slider, end_slider], outputs=[image_output, file_output, message_output])
147
 
148
  if __name__ == "__main__":
149
- iface.launch(share=True) # server_timeout λ§€κ°œλ³€μˆ˜ 제거
 
4
  import os
5
  import zipfile
6
  from PIL import Image
7
+ import tempfile
8
+ import shutil
9
+ from tqdm import tqdm
10
 
11
  def get_video_duration(video_path):
12
  cap = cv2.VideoCapture(video_path)
 
16
  cap.release()
17
  return duration
18
 
19
+ def extract_frames(video_path, output_dir, start_time, end_time, max_frames=10000, progress=gr.Progress()):
20
  cap = cv2.VideoCapture(video_path)
21
  fps = cap.get(cv2.CAP_PROP_FPS)
22
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
 
27
  frames = []
28
  cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
29
 
30
+ frame_interval = max(1, (end_frame - start_frame) // max_frames)
31
+
32
+ for i in progress.tqdm(range(start_frame, min(end_frame, total_frames), frame_interval), desc="ν”„λ ˆμž„ μΆ”μΆœ 쀑"):
33
+ cap.set(cv2.CAP_PROP_POS_FRAMES, i)
34
  ret, frame = cap.read()
35
  if not ret:
36
  break
37
  frames.append(frame)
38
+ if len(frames) >= max_frames:
39
+ break
40
 
41
  cap.release()
42
  return frames
43
 
44
+ def create_grid(frames, grid_size=(10, 10)):
45
  rows, cols = grid_size
46
+ n_frames = len(frames)
47
+ frames = frames[:rows*cols] # Limit to grid size
48
+
49
  frame_height, frame_width = frames[0].shape[:2]
50
  grid = np.zeros((frame_height * rows, frame_width * cols, 3), dtype=np.uint8)
51
 
52
  for i, frame in enumerate(frames):
 
 
53
  row = i // cols
54
  col = i % cols
55
  grid[row*frame_height:(row+1)*frame_height, col*frame_width:(col+1)*frame_width] = frame
56
 
57
  return grid
58
 
59
+ def save_frames(frames, output_dir, progress=gr.Progress()):
60
  os.makedirs(output_dir, exist_ok=True)
61
+ for i, frame in progress.tqdm(enumerate(frames), desc="ν”„λ ˆμž„ μ €μž₯ 쀑", total=len(frames)):
62
  cv2.imwrite(os.path.join(output_dir, f"frame_{i:04d}.jpg"), frame)
63
 
64
+ def create_zip(output_dir, progress=gr.Progress()):
65
  zip_path = os.path.join(output_dir, "frames.zip")
66
  with zipfile.ZipFile(zip_path, 'w') as zipf:
67
+ files = [f for f in os.listdir(output_dir) if f.endswith('.jpg')]
68
+ for file in progress.tqdm(files, desc="ZIP 파일 생성 쀑"):
69
+ zipf.write(os.path.join(output_dir, file), file)
 
70
  return zip_path
71
 
72
  def update_slider(video):
 
75
  duration = get_video_duration(video.name)
76
  return gr.Slider(minimum=0, maximum=duration, value=0, step=0.1, label="CUT μ‹œμž‘ μ‹œκ°„ (초)"), gr.Slider(minimum=0, maximum=duration, value=duration, step=0.1, label="CUT μ’…λ£Œ μ‹œκ°„ (초)")
77
 
78
+ def process_video(video, start_time, end_time, progress=gr.Progress()):
 
 
79
  if video is None:
80
  return None, None, "λΉ„λ””μ˜€ νŒŒμΌμ„ μ—…λ‘œλ“œν•΄μ£Όμ„Έμš”."
81
 
 
84
  if file_size > 2 * 1024 * 1024 * 1024: # 2GB in bytes
85
  return None, None, "파일 크기가 2GBλ₯Ό μ΄ˆκ³Όν•©λ‹ˆλ‹€. 더 μž‘μ€ νŒŒμΌμ„ μ—…λ‘œλ“œν•΄μ£Όμ„Έμš”."
86
 
87
+ with tempfile.TemporaryDirectory() as temp_dir:
88
+ frames = extract_frames(video.name, temp_dir, start_time, end_time, max_frames=10000, progress=progress)
89
+ if not frames:
90
+ return None, None, "ν”„λ ˆμž„ μΆ”μΆœμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€. λΉ„λ””μ˜€ νŒŒμΌμ„ ν™•μΈν•΄μ£Όμ„Έμš”."
91
+
92
+ save_frames(frames, temp_dir, progress=progress)
93
+ grid = create_grid(frames)
94
+ zip_path = create_zip(temp_dir, progress=progress)
95
+
96
+ # κ²°κ³Ό νŒŒμΌμ„ μž„μ‹œ 디렉토리 λ°–μœΌλ‘œ 볡사
97
+ final_zip_path = "frames.zip"
98
+ shutil.copy(zip_path, final_zip_path)
99
 
100
+ return Image.fromarray(cv2.cvtColor(grid, cv2.COLOR_BGR2RGB)), final_zip_path, f"ν”„λ ˆμž„ μΆ”μΆœμ΄ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. 총 {len(frames)}개의 ν”„λ ˆμž„μ΄ μΆ”μΆœλ˜μ—ˆμŠ΅λ‹ˆλ‹€."
101
  except Exception as e:
102
  return None, None, f"였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€: {str(e)}"
103
 
 
131
  with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, js=js) as iface:
132
  gr.Markdown("# λΉ„λ””μ˜€ to 이미지(ν”„λ ˆμž„)")
133
  gr.Markdown("μ›ν•˜λŠ” κ΅¬κ°„μ˜ ν”„λ ˆμž„μ„ μΆ”μΆœν•˜μ—¬ κ·Έλ¦¬λ“œλ‘œ ν‘œμ‹œν•˜κ³ , κ°œλ³„ 이미지λ₯Ό ZIP 파일둜 λ‹€μš΄λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.")
134
+ gr.Markdown("μ΅œλŒ€ 2GB 크기의 λΉ„λ””μ˜€ νŒŒμΌμ„ μ—…λ‘œλ“œν•  수 있으며, μ΅œλŒ€ 10000개의 ν”„λ ˆμž„μ„ μΆ”μΆœν•©λ‹ˆλ‹€.")
135
 
136
  with gr.Row():
137
  video_input = gr.Video(label="Upload and Play Video")
 
156
  process_button.click(process_video, inputs=[video_input, start_slider, end_slider], outputs=[image_output, file_output, message_output])
157
 
158
  if __name__ == "__main__":
159
+ iface.launch(share=True)