aliceblue11 commited on
Commit
34524fb
·
verified ·
1 Parent(s): c0e15e4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -100
app.py CHANGED
@@ -1,122 +1,130 @@
1
  import gradio as gr
2
  import moviepy.editor as mp
 
3
  import os
4
- from PIL import Image
5
-
6
- def process_video(video_file, start_time, end_time, resolution, fps, playback_speed, loop_count):
7
- # 로그 출력: 파일 업로드 확인
8
- print("파일 업로드 완료:", video_file.name)
9
-
10
- # 동영상 불러오기
11
- video = mp.VideoFileClip(video_file.name)
12
- duration = video.duration
13
- print("동영상 길이:", duration)
14
-
15
- # 시작/끝 시간 처리
16
- start_time = float(start_time) if start_time else 0
17
- end_time = float(end_time) if end_time else duration
18
- print(f"시작 시간: {start_time}, 끝 시간: {end_time}")
19
-
20
- # 영상 클립 추출
21
- trimmed_clip = video.subclip(start_time, end_time)
22
-
23
- # 해상도 조정
24
- if resolution != "원본":
25
- width, height = [int(i) for i in resolution.split("x")]
26
- trimmed_clip = trimmed_clip.resize(height=height)
27
- print("해상도 조정:", resolution)
28
- else:
29
- print("해상도 유지: 원본")
30
-
31
- # 프레임 속도 조정
32
- trimmed_clip = trimmed_clip.set_fps(fps)
33
- print("프레임 속도 조정:", fps)
34
-
35
- # 재생 속도 조정
36
- trimmed_clip = trimmed_clip.fx(mp.vfx.speedx, playback_speed)
37
- print("재생 속도 조정:", playback_speed)
38
-
39
- # GIF 반복 횟수
40
- loop_count = "infinite" if loop_count == 0 else loop_count
41
- print("GIF 반복 횟수 설정:", loop_count)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
  # 썸네일 생성
44
- start_thumb = trimmed_clip.get_frame(0)
45
- end_thumb = trimmed_clip.get_frame(end_time - start_time)
46
- start_thumbnail = Image.fromarray(start_thumb)
47
- end_thumbnail = Image.fromarray(end_thumb)
48
-
49
- # GIF 저장
50
- gif_path = "output.gif"
51
- trimmed_clip.write_gif(gif_path, loop=loop_count)
52
- print("GIF 생성 완료:", gif_path)
53
-
54
- return start_thumbnail, end_thumbnail, gif_path
55
 
 
 
56
 
57
- def preview_gif(gif_path):
58
- return gif_path
59
-
60
-
61
- # Gradio 인터페이스 구성
62
- with gr.Blocks() as app:
63
- gr.Markdown("## 동영상을 GIF로 변환하는 툴")
64
-
65
- # 동영상 업로드
66
- video_input = gr.Video(label="동영상 업로드")
67
 
68
- # 동영상 재생 및 정보 출력
69
- video_output = gr.Video(label="��로드된 동영상 미리보기")
70
- video_info = gr.Label(label="동영상 정보")
71
 
72
- # 입력창: 시작 시간, 끝 시간
73
- start_time = gr.Textbox(label="시작 시간 (초 단위)", placeholder="예: 5.0")
74
- end_time = gr.Textbox(label="끝 시간 (초 단위)", placeholder="예: 10.0")
75
 
76
- # 썸네일 출력
77
- start_thumbnail_output = gr.Image(label="시작 지점 썸네일")
78
- end_thumbnail_output = gr.Image(label="끝 지점 썸네일")
79
 
80
- # 해상도 조절 슬라이더
81
- resolution_slider = gr.Dropdown(
82
- choices=["원본", "1920x1080", "1280x720", "640x480"],
83
- value="원본",
84
- label="해상도 선택"
85
- )
86
 
87
- # 프레임 속도 조절 슬라이더
88
- fps_slider = gr.Slider(1, 60, step=1, value=30, label="프레임 속도 (기본 30fps)")
 
89
 
90
- # 재생 속도 조절 슬라이더
91
- playback_speed_slider = gr.Slider(0.1, 4.0, step=0.1, value=1.0, label="재생 속도 (기본 1배속)")
 
92
 
93
- # GIF 반복 횟수 조절 슬라이더
94
- loop_count_slider = gr.Slider(0, 10, step=1, value=0, label="GIF 반복 횟수 (0은 무한 반복)")
 
95
 
96
- # GIF 생성 버튼
97
  generate_button = gr.Button("GIF 생성")
 
 
 
 
98
 
99
- # GIF 미리보기 및 다운로드 출력
100
- gif_preview_output = gr.Image(label="GIF 미리보기")
101
- gif_download_output = gr.File(label="GIF 다운로드")
 
 
102
 
103
- # 동영상 처리 함수 연결
104
- video_input.change(
105
- lambda video_file: (video_file, {"동영상 길이(초)": mp.VideoFileClip(video_file.name).duration}),
106
- inputs=[video_input],
107
- outputs=[video_output, video_info]
108
- )
109
 
110
  generate_button.click(
111
- process_video,
112
- inputs=[
113
- video_input, start_time, end_time, resolution_slider,
114
- fps_slider, playback_speed_slider, loop_count_slider
115
- ],
116
- outputs=[start_thumbnail_output, end_thumbnail_output, gif_download_output]
117
  )
118
 
119
- gif_preview_output.change(preview_gif, inputs=[gif_download_output], outputs=[gif_preview_output])
120
-
121
- # 앱 실행
122
- app.launch()
 
1
  import gradio as gr
2
  import moviepy.editor as mp
3
+ import imageio
4
  import os
5
+ import logging
6
+
7
+ # 로그 설정
8
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
9
+
10
+ def get_video_info(video_path):
11
+ try:
12
+ clip = mp.VideoFileClip(video_path)
13
+ duration = clip.duration
14
+ logging.info(f"동영상 재생 시간: {duration}초")
15
+ return duration
16
+ except Exception as e:
17
+ logging.error(f"동영상 정보 추출 실패: {e}")
18
+ return None
19
+
20
+ def generate_thumbnails(video_path, start_time, end_time):
21
+ try:
22
+ clip = mp.VideoFileClip(video_path)
23
+ start_frame = clip.get_frame(start_time)
24
+ end_frame = clip.get_frame(end_time)
25
+ start_thumb_path = "start_thumbnail.png"
26
+ end_thumb_path = "end_thumbnail.png"
27
+ imageio.imwrite(start_thumb_path, start_frame)
28
+ imageio.imwrite(end_thumb_path, end_frame)
29
+ logging.info("썸네일 생성 성공")
30
+ return start_thumb_path, end_thumb_path
31
+ except Exception as e:
32
+ logging.error(f"썸네일 생성 실패: {e}")
33
+ return None, None
34
+
35
+ def create_gif(video_path, start_time, end_time, resolution, fps, speed, repeat):
36
+ try:
37
+ clip = mp.VideoFileClip(video_path).subclip(start_time, end_time)
38
+ # 해상도 조절
39
+ if resolution != 100:
40
+ new_width = int(clip.w * resolution / 100)
41
+ new_height = int(clip.h * resolution / 100)
42
+ clip = clip.resize(newsize=(new_width, new_height))
43
+ logging.info(f"해상도 조절: {new_width}x{new_height}")
44
+ # 프레임 속도 조절
45
+ clip = clip.set_fps(fps)
46
+ logging.info(f"프레임 속도 조절: {fps}fps")
47
+ # 재생 속도 조절
48
+ clip = clip.fx(mp.vfx.speedx, speed)
49
+ logging.info(f"재생 속도 조절: {speed}배속")
50
+ # GIF 반복 설정
51
+ if repeat == -1:
52
+ loop = 0 # 무한 반복
53
+ else:
54
+ loop = repeat
55
+ gif_path = "output.gif"
56
+ clip.write_gif(gif_path, loop=loop)
57
+ logging.info("GIF 생성 성공")
58
+ return gif_path
59
+ except Exception as e:
60
+ logging.error(f"GIF 생성 실패: {e}")
61
+ return None
62
+
63
+ def process_video(video, start_time, end_time, resolution, fps, speed, repeat):
64
+ if video is None:
65
+ logging.warning("업로드된 동영상이 없습니다.")
66
+ return None, None
67
+
68
+ video_path = video.name
69
+ logging.info(f"동영상 업로드: {video_path}")
70
+
71
+ # 동영상 정보 추출
72
+ duration = get_video_info(video_path)
73
 
74
  # 썸네일 생성
75
+ start_thumb, end_thumb = generate_thumbnails(video_path, start_time, end_time)
 
 
 
 
 
 
 
 
 
 
76
 
77
+ # GIF 생성
78
+ gif_path = create_gif(video_path, start_time, end_time, resolution, fps, speed, repeat)
79
 
80
+ if gif_path:
81
+ return gif_path, gif_path
82
+ else:
83
+ return None, None
 
 
 
 
 
 
84
 
85
+ with gr.Blocks() as demo:
86
+ gr.Markdown("# 동영상을 GIF로 변환하기")
 
87
 
88
+ with gr.Row():
89
+ video_input = gr.Video(label="동영상 업로드")
 
90
 
91
+ with gr.Row():
92
+ video_info = gr.Textbox(label="동영상 재생 시간 (초)", interactive=False)
 
93
 
94
+ with gr.Row():
95
+ start_time = gr.Number(label="시작 시간 (초)", value=0)
96
+ end_time = gr.Number(label=" 시간 (초)", value=5)
 
 
 
97
 
98
+ with gr.Row():
99
+ start_thumbnail = gr.Image(label="시작 부분 썸네일")
100
+ end_thumbnail = gr.Image(label="끝 부분 썸네일")
101
 
102
+ with gr.Row():
103
+ resolution = gr.Slider(label="해상도 조절 (%)", minimum=10, maximum=200, step=10, value=100)
104
+ fps = gr.Slider(label="프레임 속도 조절", minimum=1, maximum=60, step=1, value=24)
105
 
106
+ with gr.Row():
107
+ speed = gr.Slider(label="재생 속도 조절", minimum=0.5, maximum=3.0, step=0.1, value=1.0)
108
+ repeat = gr.Slider(label="GIF 반복 횟수", minimum=-1, maximum=10, step=1, value=-1)
109
 
 
110
  generate_button = gr.Button("GIF 생성")
111
+
112
+ with gr.Row():
113
+ gif_preview = gr.Image(label="GIF 미리보기")
114
+ gif_download = gr.File(label="GIF 다운로드")
115
 
116
+ def update_video_info(video):
117
+ if video is None:
118
+ return ""
119
+ duration = get_video_info(video.name)
120
+ return f"{duration:.2f} 초" if duration else "정보 불러오기 실패"
121
 
122
+ video_input.change(fn=update_video_info, inputs=video_input, outputs=video_info)
 
 
 
 
 
123
 
124
  generate_button.click(
125
+ fn=process_video,
126
+ inputs=[video_input, start_time, end_time, resolution, fps, speed, repeat],
127
+ outputs=[gif_preview, gif_download]
 
 
 
128
  )
129
 
130
+ demo.launch()