openfree commited on
Commit
85604c8
ยท
verified ยท
1 Parent(s): 03709da

Update app-backup.py

Browse files
Files changed (1) hide show
  1. app-backup.py +97 -56
app-backup.py CHANGED
@@ -722,7 +722,7 @@ def process_video_bg(vid, bg_type="์ƒ‰์ƒ", bg_image=None, bg_video=None, color=
722
  yield None, None, f"๋น„๋””์˜ค ์ฒ˜๋ฆฌ ์˜ค๋ฅ˜: {e}. ๊ฒฝ๊ณผ ์‹œ๊ฐ„: {elapsed_time:.2f}์ดˆ"
723
 
724
  @spaces.GPU(duration=180)
725
- def merge_videos_with_audio(video_files, audio_file, audio_volume, output_fps):
726
  """์—ฌ๋Ÿฌ ๋น„๋””์˜ค๋ฅผ ๋ณ‘ํ•ฉํ•˜๊ณ  ์˜ค๋””์˜ค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜"""
727
  if not video_files:
728
  return None, "๋น„๋””์˜ค ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”."
@@ -773,20 +773,15 @@ def merge_videos_with_audio(video_files, audio_file, audio_volume, output_fps):
773
  logging.warning(f"๋น„๋””์˜ค ํฌ๊ธฐ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค ํฌ๊ธฐ({target_width}x{target_height})๋กœ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.")
774
 
775
  # ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฅธ ๋น„๋””์˜ค๋“ค์„ ์กฐ์ •
776
-
777
  adjusted_clips = []
778
  for clip, size in zip(video_clips, clip_sizes):
779
  if size != (target_width, target_height):
780
- # resize ํ•จ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด ์‚ฌ์šฉ, ์—†์œผ๋ฉด ๋Œ€์ฒด ๋ฐฉ๋ฒ• ์‚ฌ์šฉ
781
  if resize is not None:
782
  adjusted_clip = resize(clip, newsize=(target_width, target_height))
783
  else:
784
- # resize๊ฐ€ ์—†์„ ๋•Œ ๋Œ€์ฒด ๋ฐฉ๋ฒ•
785
- # clip.resize() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ์‹œ๋„
786
  if hasattr(clip, 'resize'):
787
  adjusted_clip = clip.resize((target_width, target_height))
788
  else:
789
- # ์ตœํ›„์˜ ์ˆ˜๋‹จ: ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
790
  adjusted_clip = clip
791
  logging.warning(f"Cannot resize video. Using original size.")
792
  adjusted_clips.append(adjusted_clip)
@@ -813,19 +808,17 @@ def merge_videos_with_audio(video_files, audio_file, audio_volume, output_fps):
813
  if isinstance(audio_file, str):
814
  audio_path = audio_file
815
  else:
816
- # gr.Audio์—์„œ ๋ฐ˜ํ™˜๋œ ํŠœํ”Œ์ธ ๊ฒฝ์šฐ
817
  audio_path = audio_file
818
 
819
  logging.info(f"Processing audio from: {audio_path}")
 
820
 
821
  # ์˜ค๋””์˜ค ๋กœ๋“œ
822
  if audio_path.endswith(('.mp4', '.avi', '.mov', '.mkv')):
823
- # ๋น„๋””์˜ค ํŒŒ์ผ์—์„œ ์˜ค๋””์˜ค ์ถ”์ถœ
824
  temp_video = VideoFileClip(audio_path)
825
  audio_clip = temp_video.audio
826
  temp_video.close()
827
  else:
828
- # ์˜ค๋””์˜ค ํŒŒ์ผ ์ง์ ‘ ๋กœ๋“œ
829
  audio_clip = AudioFileClip(audio_path)
830
 
831
  if audio_clip is None:
@@ -840,31 +833,39 @@ def merge_videos_with_audio(video_files, audio_file, audio_volume, output_fps):
840
  audio_duration = audio_clip.duration
841
 
842
  if audio_duration > video_duration:
843
- # ์˜ค๋””์˜ค๊ฐ€ ๋” ๊ธธ๋ฉด ์ž˜๋ผ๋ƒ„
844
  audio_clip = audio_clip.subclip(0, video_duration)
845
  elif audio_duration < video_duration:
846
- # ์˜ค๋””์˜ค๊ฐ€ ๋” ์งง์œผ๋ฉด ๋ฐ˜๋ณต
847
  loops_needed = int(video_duration / audio_duration) + 1
848
  audio_clips_list = [audio_clip] * loops_needed
849
  looped_audio = concatenate_audioclips(audio_clips_list)
850
  audio_clip = looped_audio.subclip(0, video_duration)
851
 
852
- # ๊ธฐ์กด ์˜ค๋””์˜ค ์ œ๊ฑฐํ•˜๊ณ  ์ƒˆ ์˜ค๋””์˜ค๋กœ ๊ต์ฒด
853
- # (๊ธฐ์กด ์˜ค๋””์˜ค์™€ ํ•ฉ์„ฑํ•˜๋ ค๋ฉด ์•„๋ž˜ ์ฃผ์„ ํ•ด์ œ)
854
- final_video = final_video.set_audio(audio_clip)
855
-
856
- # ๊ธฐ์กด ์˜ค๋””์˜ค์™€ ์ƒˆ ์˜ค๋””์˜ค ํ•ฉ์„ฑ์„ ์›ํ•˜๋Š” ๊ฒฝ์šฐ:
857
- # if final_video.audio:
858
- # final_audio = CompositeAudioClip([final_video.audio, audio_clip])
859
- # final_video = final_video.set_audio(final_audio)
860
- # else:
861
- # final_video = final_video.set_audio(audio_clip)
 
 
 
 
 
 
 
 
 
 
 
862
 
863
- logging.info("Audio successfully added to video")
864
 
865
  except Exception as e:
866
  logging.error(f"์˜ค๋””์˜ค ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
867
- # ์˜ค๋””์˜ค ์ฒ˜๋ฆฌ ์‹คํŒจํ•ด๋„ ๋น„๋””์˜ค๋Š” ๊ณ„์† ์ฒ˜๋ฆฌ
868
  status = f"์˜ค๋””์˜ค ์ฒ˜๋ฆฌ ์‹คํŒจ: {str(e)}, ๋น„๋””์˜ค๋งŒ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค."
869
 
870
  status = "๋น„๋””์˜ค ์ €์žฅ ์ค‘..."
@@ -879,8 +880,8 @@ def merge_videos_with_audio(video_files, audio_file, audio_volume, output_fps):
879
  fps=output_fps,
880
  codec="libx264",
881
  audio_codec="aac",
882
- preset="medium", # ํ’ˆ์งˆ ์„ค์ •
883
- bitrate="5000k", # ๋น„ํŠธ๋ ˆ์ดํŠธ ์„ค์ •์œผ๋กœ ํ’ˆ์งˆ ์œ ์ง€
884
  audio_bitrate="192k"
885
  )
886
 
@@ -895,7 +896,15 @@ def merge_videos_with_audio(video_files, audio_file, audio_volume, output_fps):
895
  audio_clip.close()
896
  final_video.close()
897
 
898
- return temp_filepath, f"โœ… ์„ฑ๊ณต์ ์œผ๋กœ {len(video_paths)}๊ฐœ์˜ ๋น„๋””์˜ค๋ฅผ ๋ณ‘ํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค! (ํฌ๊ธฐ: {target_width}x{target_height})"
 
 
 
 
 
 
 
 
899
 
900
  except Exception as e:
901
  logging.error(f"Video merge error: {str(e)}")
@@ -1126,7 +1135,8 @@ with demo:
1126
  interactive=False
1127
  )
1128
 
1129
- # ๋„ค ๋ฒˆ์งธ ํƒญ: ๋น„๋””์˜ค ํŽธ์ง‘
 
1130
  with gr.Tab("๋น„๋””์˜ค ํŽธ์ง‘", elem_classes="tabitem"):
1131
  with gr.Row(equal_height=True):
1132
  # ์ž…๋ ฅ ์ปฌ๋Ÿผ
@@ -1134,57 +1144,78 @@ with demo:
1134
  with gr.Group(elem_classes="panel-box"):
1135
  gr.Markdown("### ๐ŸŽฅ ๋น„๋””์˜ค ์—…๋กœ๋“œ (์ตœ๋Œ€ 10๊ฐœ)")
1136
  gr.Markdown("**ํŒŒ์ผ๋ช…์ด ์ž‘์„์ˆ˜๋ก ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค** (์˜ˆ: 1.mp4, 2.mp4, 3.mp4)")
1137
-
1138
  video_files = gr.File(
1139
  label="๋น„๋””์˜ค ํŒŒ์ผ๋“ค",
1140
  file_count="multiple",
1141
  file_types=["video"],
1142
  type="filepath"
1143
  )
1144
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1145
  with gr.Group(elem_classes="panel-box"):
1146
  gr.Markdown("### ๐ŸŽต ์˜ค๋””์˜ค ์„ค์ • (์„ ํƒ)")
1147
- gr.Markdown("**์ฃผ์˜**: ์—…๋กœ๋“œํ•œ ์˜ค๋””์˜ค๊ฐ€ ๋น„๋””์˜ค์˜ ๊ธฐ์กด ์˜ค๋””์˜ค๋ฅผ ์™„์ „ํžˆ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.")
1148
-
 
 
 
 
 
 
 
1149
  audio_file = gr.Audio(
1150
  label="์˜ค๋””์˜ค ํŒŒ์ผ (MP3, WAV, M4A ๋“ฑ)",
1151
  type="filepath",
1152
  sources=["upload"]
1153
  )
1154
-
1155
  audio_volume = gr.Slider(
1156
  minimum=0,
1157
  maximum=200,
1158
  value=100,
1159
  step=1,
1160
- label="์˜ค๋””์˜ค ๋ณผ๋ฅจ (%)",
1161
  info="100% = ์›๋ณธ ๋ณผ๋ฅจ"
1162
  )
1163
-
1164
- gr.Markdown("""
1165
- **์˜ค๋””์˜ค ์˜ต์…˜**:
1166
- - ์˜ค๋””์˜ค๊ฐ€ ๋น„๋””์˜ค๋ณด๋‹ค ์งง์œผ๋ฉด ์ž๋™์œผ๋กœ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค
1167
- - ์˜ค๋””์˜ค๊ฐ€ ๋น„๋””์˜ค๋ณด๋‹ค ๊ธธ๋ฉด ๋น„๋””์˜ค ๊ธธ์ด์— ๋งž์ถฐ ์ž˜๋ฆฝ๋‹ˆ๋‹ค
1168
- """)
1169
-
1170
- with gr.Group(elem_classes="panel-box"):
1171
- gr.Markdown("### โš™๏ธ ํŽธ์ง‘ ์„ค์ •")
1172
-
1173
- output_fps = gr.Slider(
1174
  minimum=0,
1175
- maximum=60,
1176
- value=0,
1177
  step=1,
1178
- label="์ถœ๋ ฅ FPS (0 = ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค์˜ FPS ์‚ฌ์šฉ)"
 
 
1179
  )
1180
-
1181
  gr.Markdown("""
1182
- **ํฌ๊ธฐ ์ฒ˜๋ฆฌ**:
1183
- - ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค์˜ ํฌ๊ธฐ๊ฐ€ ๊ธฐ์ค€์ด ๋ฉ๋‹ˆ๋‹ค
1184
- - ๋‹ค๋ฅธ ํฌ๊ธฐ์˜ ๋น„๋””์˜ค๋Š” ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค ํฌ๊ธฐ๋กœ ์กฐ์ •๋ฉ๋‹ˆ๋‹ค
1185
- - ์ตœ์ƒ์˜ ๊ฒฐ๊ณผ๋ฅผ ์œ„ํ•ด ๊ฐ™์€ ํฌ๊ธฐ์˜ ๋น„๋””์˜ค๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”
 
1186
  """)
1187
-
1188
  merge_videos_btn = gr.Button("๐ŸŽฌ ๋น„๋””์˜ค ๋ณ‘ํ•ฉ", variant="primary", elem_id="merge-btn")
1189
 
1190
  # ์ถœ๋ ฅ ์ปฌ๋Ÿผ
@@ -1362,12 +1393,22 @@ with demo:
1362
  )
1363
 
1364
  # ์ด๋ฒคํŠธ ์—ฐ๊ฒฐ - ๋„ค ๋ฒˆ์งธ ํƒญ (๋น„๋””์˜ค ํŽธ์ง‘)
 
 
 
 
 
 
 
 
 
 
 
1365
  merge_videos_btn.click(
1366
  merge_videos_with_audio,
1367
- inputs=[video_files, audio_file, audio_volume, output_fps],
1368
  outputs=[merged_video, merge_status]
1369
- )
1370
-
1371
  # ์ด๋ฒคํŠธ ์—ฐ๊ฒฐ - ๋‹ค์„ฏ ๋ฒˆ์งธ ํƒญ (๋น„๋””์˜ค ๋ฐฐ๊ฒฝ์ œ๊ฑฐ/ํ•ฉ์„ฑ)
1372
  def update_bg_visibility(bg_type):
1373
  if bg_type == "์ƒ‰์ƒ":
 
722
  yield None, None, f"๋น„๋””์˜ค ์ฒ˜๋ฆฌ ์˜ค๋ฅ˜: {e}. ๊ฒฝ๊ณผ ์‹œ๊ฐ„: {elapsed_time:.2f}์ดˆ"
723
 
724
  @spaces.GPU(duration=180)
725
+ def merge_videos_with_audio(video_files, audio_file, audio_mode, audio_volume, original_audio_volume, output_fps):
726
  """์—ฌ๋Ÿฌ ๋น„๋””์˜ค๋ฅผ ๋ณ‘ํ•ฉํ•˜๊ณ  ์˜ค๋””์˜ค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜"""
727
  if not video_files:
728
  return None, "๋น„๋””์˜ค ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”."
 
773
  logging.warning(f"๋น„๋””์˜ค ํฌ๊ธฐ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค ํฌ๊ธฐ({target_width}x{target_height})๋กœ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.")
774
 
775
  # ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฅธ ๋น„๋””์˜ค๋“ค์„ ์กฐ์ •
 
776
  adjusted_clips = []
777
  for clip, size in zip(video_clips, clip_sizes):
778
  if size != (target_width, target_height):
 
779
  if resize is not None:
780
  adjusted_clip = resize(clip, newsize=(target_width, target_height))
781
  else:
 
 
782
  if hasattr(clip, 'resize'):
783
  adjusted_clip = clip.resize((target_width, target_height))
784
  else:
 
785
  adjusted_clip = clip
786
  logging.warning(f"Cannot resize video. Using original size.")
787
  adjusted_clips.append(adjusted_clip)
 
808
  if isinstance(audio_file, str):
809
  audio_path = audio_file
810
  else:
 
811
  audio_path = audio_file
812
 
813
  logging.info(f"Processing audio from: {audio_path}")
814
+ logging.info(f"Audio mode: {audio_mode}")
815
 
816
  # ์˜ค๋””์˜ค ๋กœ๋“œ
817
  if audio_path.endswith(('.mp4', '.avi', '.mov', '.mkv')):
 
818
  temp_video = VideoFileClip(audio_path)
819
  audio_clip = temp_video.audio
820
  temp_video.close()
821
  else:
 
822
  audio_clip = AudioFileClip(audio_path)
823
 
824
  if audio_clip is None:
 
833
  audio_duration = audio_clip.duration
834
 
835
  if audio_duration > video_duration:
 
836
  audio_clip = audio_clip.subclip(0, video_duration)
837
  elif audio_duration < video_duration:
 
838
  loops_needed = int(video_duration / audio_duration) + 1
839
  audio_clips_list = [audio_clip] * loops_needed
840
  looped_audio = concatenate_audioclips(audio_clips_list)
841
  audio_clip = looped_audio.subclip(0, video_duration)
842
 
843
+ # ์˜ค๋””์˜ค ๋ชจ๋“œ์— ๋”ฐ๋ฅธ ์ฒ˜๋ฆฌ
844
+ if audio_mode == "๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง":
845
+ # ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง ๋ชจ๋“œ: ๊ธฐ์กด ์˜ค๋””์˜ค์™€ ํ•ฉ์„ฑ
846
+ if final_video.audio:
847
+ # ์›๋ณธ ์˜ค๋””์˜ค ๋ณผ๋ฅจ ์กฐ์ ˆ
848
+ original_audio = final_video.audio
849
+ if original_audio_volume != 100:
850
+ original_audio = original_audio.volumex(original_audio_volume / 100)
851
+
852
+ # ๋‘ ์˜ค๋””์˜ค ํ•ฉ์„ฑ
853
+ final_audio = CompositeAudioClip([original_audio, audio_clip])
854
+ final_video = final_video.set_audio(final_audio)
855
+ logging.info("Background music mode: Mixed original and new audio")
856
+ else:
857
+ # ์›๋ณธ ์˜ค๋””์˜ค๊ฐ€ ์—†์œผ๋ฉด ๊ทธ๋ƒฅ ์ถ”๊ฐ€
858
+ final_video = final_video.set_audio(audio_clip)
859
+ logging.info("No original audio found, adding new audio only")
860
+ else:
861
+ # ๋Œ€์ฒด ๋ชจ๋“œ: ๊ธฐ์กด ์˜ค๋””์˜ค๋ฅผ ์™„์ „ํžˆ ๊ต์ฒด
862
+ final_video = final_video.set_audio(audio_clip)
863
+ logging.info("Replace mode: Replaced original audio")
864
 
865
+ logging.info("Audio successfully processed")
866
 
867
  except Exception as e:
868
  logging.error(f"์˜ค๋””์˜ค ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
 
869
  status = f"์˜ค๋””์˜ค ์ฒ˜๋ฆฌ ์‹คํŒจ: {str(e)}, ๋น„๋””์˜ค๋งŒ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค."
870
 
871
  status = "๋น„๋””์˜ค ์ €์žฅ ์ค‘..."
 
880
  fps=output_fps,
881
  codec="libx264",
882
  audio_codec="aac",
883
+ preset="medium",
884
+ bitrate="5000k",
885
  audio_bitrate="192k"
886
  )
887
 
 
896
  audio_clip.close()
897
  final_video.close()
898
 
899
+ # ์ƒํƒœ ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ
900
+ if audio_file and audio_mode == "๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง":
901
+ mode_msg = "๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง ์ถ”๊ฐ€๋จ"
902
+ elif audio_file:
903
+ mode_msg = "์˜ค๋””์˜ค ๋Œ€์ฒด๋จ"
904
+ else:
905
+ mode_msg = "์˜ค๋””์˜ค ์—†์Œ"
906
+
907
+ return temp_filepath, f"โœ… ์„ฑ๊ณต์ ์œผ๋กœ {len(video_paths)}๊ฐœ์˜ ๋น„๋””์˜ค๋ฅผ ๋ณ‘ํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค! (ํฌ๊ธฐ: {target_width}x{target_height}, {mode_msg})"
908
 
909
  except Exception as e:
910
  logging.error(f"Video merge error: {str(e)}")
 
1135
  interactive=False
1136
  )
1137
 
1138
+
1139
+ # ๋„ค ๋ฒˆ์งธ ํƒญ: ๋น„๋””์˜ค ํŽธ์ง‘ ๋ถ€๋ถ„์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •
1140
  with gr.Tab("๋น„๋””์˜ค ํŽธ์ง‘", elem_classes="tabitem"):
1141
  with gr.Row(equal_height=True):
1142
  # ์ž…๋ ฅ ์ปฌ๋Ÿผ
 
1144
  with gr.Group(elem_classes="panel-box"):
1145
  gr.Markdown("### ๐ŸŽฅ ๋น„๋””์˜ค ์—…๋กœ๋“œ (์ตœ๋Œ€ 10๊ฐœ)")
1146
  gr.Markdown("**ํŒŒ์ผ๋ช…์ด ์ž‘์„์ˆ˜๋ก ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค** (์˜ˆ: 1.mp4, 2.mp4, 3.mp4)")
1147
+
1148
  video_files = gr.File(
1149
  label="๋น„๋””์˜ค ํŒŒ์ผ๋“ค",
1150
  file_count="multiple",
1151
  file_types=["video"],
1152
  type="filepath"
1153
  )
1154
+
1155
+ with gr.Group(elem_classes="panel-box"):
1156
+ gr.Markdown("### โš™๏ธ ํŽธ์ง‘ ์„ค์ •")
1157
+
1158
+ output_fps = gr.Slider(
1159
+ minimum=0,
1160
+ maximum=60,
1161
+ value=0,
1162
+ step=1,
1163
+ label="์ถœ๋ ฅ FPS (0 = ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค์˜ FPS ์‚ฌ์šฉ)"
1164
+ )
1165
+
1166
+ gr.Markdown("""
1167
+ **ํฌ๊ธฐ ์ฒ˜๋ฆฌ**:
1168
+ - ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค์˜ ํฌ๊ธฐ๊ฐ€ ๊ธฐ์ค€์ด ๋ฉ๋‹ˆ๋‹ค
1169
+ - ๋‹ค๋ฅธ ํฌ๊ธฐ์˜ ๋น„๋””์˜ค๋Š” ์ฒซ ๋ฒˆ์งธ ๋น„๋””์˜ค ํฌ๊ธฐ๋กœ ์กฐ์ •๋ฉ๋‹ˆ๋‹ค
1170
+ - ์ตœ์ƒ์˜ ๊ฒฐ๊ณผ๋ฅผ ์œ„ํ•ด ๊ฐ™์€ ํฌ๊ธฐ์˜ ๋น„๋””์˜ค๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”
1171
+ """)
1172
+
1173
+
1174
  with gr.Group(elem_classes="panel-box"):
1175
  gr.Markdown("### ๐ŸŽต ์˜ค๋””์˜ค ์„ค์ • (์„ ํƒ)")
1176
+
1177
+ # ์˜ค๋””์˜ค ๋ชจ๋“œ ์„ ํƒ ์ถ”๊ฐ€
1178
+ audio_mode = gr.Radio(
1179
+ ["๋Œ€์ฒด", "๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง"],
1180
+ label="์˜ค๋””์˜ค ๋ชจ๋“œ",
1181
+ value="๋Œ€์ฒด",
1182
+ info="๋Œ€์ฒด: ๊ธฐ์กด ์˜ค๋””์˜ค๋ฅผ ์™„์ „ํžˆ ๊ต์ฒด | ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง: ๊ธฐ์กด ์˜ค๋””์˜ค์™€ ํ•จ๊ป˜ ์žฌ์ƒ"
1183
+ )
1184
+
1185
  audio_file = gr.Audio(
1186
  label="์˜ค๋””์˜ค ํŒŒ์ผ (MP3, WAV, M4A ๋“ฑ)",
1187
  type="filepath",
1188
  sources=["upload"]
1189
  )
1190
+
1191
  audio_volume = gr.Slider(
1192
  minimum=0,
1193
  maximum=200,
1194
  value=100,
1195
  step=1,
1196
+ label="์ถ”๊ฐ€ ์˜ค๋””์˜ค ๋ณผ๋ฅจ (%)",
1197
  info="100% = ์›๋ณธ ๋ณผ๋ฅจ"
1198
  )
1199
+
1200
+ # ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ชจ๋“œ์ผ ๋•Œ๋งŒ ๋ณด์ด๋Š” ์›๋ณธ ์˜ค๋””์˜ค ๋ณผ๋ฅจ ์กฐ์ ˆ
1201
+ original_audio_volume = gr.Slider(
 
 
 
 
 
 
 
 
1202
  minimum=0,
1203
+ maximum=200,
1204
+ value=100,
1205
  step=1,
1206
+ label="์›๋ณธ ์˜ค๋””์˜ค ๋ณผ๋ฅจ (%)",
1207
+ info="๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง ๋ชจ๋“œ์—์„œ ์›๋ณธ ๋น„๋””์˜ค ์˜ค๋””์˜ค์˜ ๋ณผ๋ฅจ",
1208
+ visible=False
1209
  )
1210
+
1211
  gr.Markdown("""
1212
+ **์˜ค๋””์˜ค ์˜ต์…˜**:
1213
+ - **๋Œ€์ฒด ๋ชจ๋“œ**: ์—…๋กœ๋“œํ•œ ์˜ค๋””์˜ค๊ฐ€ ๋น„๋””์˜ค์˜ ๊ธฐ์กด ์˜ค๋””์˜ค๋ฅผ ์™„์ „ํžˆ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค
1214
+ - **๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง ๋ชจ๋“œ**: ์—…๋กœ๋“œํ•œ ์˜ค๋””์˜ค๊ฐ€ ๊ธฐ์กด ์˜ค๋””์˜ค์™€ ํ•จ๊ป˜ ์žฌ์ƒ๋ฉ๋‹ˆ๋‹ค
1215
+ - ์˜ค๋””์˜ค๊ฐ€ ๋น„๋””์˜ค๋ณด๋‹ค ์งง์œผ๋ฉด ์ž๋™์œผ๋กœ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค
1216
+ - ์˜ค๋””์˜ค๊ฐ€ ๋น„๋””์˜ค๋ณด๋‹ค ๊ธธ๋ฉด ๋น„๋””์˜ค ๊ธธ์ด์— ๋งž์ถฐ ์ž˜๋ฆฝ๋‹ˆ๋‹ค
1217
  """)
1218
+
1219
  merge_videos_btn = gr.Button("๐ŸŽฌ ๋น„๋””์˜ค ๋ณ‘ํ•ฉ", variant="primary", elem_id="merge-btn")
1220
 
1221
  # ์ถœ๋ ฅ ์ปฌ๋Ÿผ
 
1393
  )
1394
 
1395
  # ์ด๋ฒคํŠธ ์—ฐ๊ฒฐ - ๋„ค ๋ฒˆ์งธ ํƒญ (๋น„๋””์˜ค ํŽธ์ง‘)
1396
+
1397
+ def toggle_original_volume(mode):
1398
+ return gr.update(visible=(mode == "๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฎค์ง"))
1399
+
1400
+ audio_mode.change(
1401
+ toggle_original_volume,
1402
+ inputs=[audio_mode],
1403
+ outputs=[original_audio_volume]
1404
+ )
1405
+
1406
+
1407
  merge_videos_btn.click(
1408
  merge_videos_with_audio,
1409
+ inputs=[video_files, audio_file, audio_mode, audio_volume, original_audio_volume, output_fps],
1410
  outputs=[merged_video, merge_status]
1411
+ )
 
1412
  # ์ด๋ฒคํŠธ ์—ฐ๊ฒฐ - ๋‹ค์„ฏ ๋ฒˆ์งธ ํƒญ (๋น„๋””์˜ค ๋ฐฐ๊ฒฝ์ œ๊ฑฐ/ํ•ฉ์„ฑ)
1413
  def update_bg_visibility(bg_type):
1414
  if bg_type == "์ƒ‰์ƒ":