openfree commited on
Commit
5beda4f
Β·
verified Β·
1 Parent(s): 9bc725d

Update app-backup1.py

Browse files
Files changed (1) hide show
  1. app-backup1.py +567 -483
app-backup1.py CHANGED
@@ -22,7 +22,7 @@ import os
22
  import gc
23
  from openai import OpenAI
24
  import re
25
-
26
  # Load system prompts
27
  system_prompt_t2v = """당신은 λΉ„λ””μ˜€ 생성을 μœ„ν•œ ν”„λ‘¬ν”„νŠΈ μ „λ¬Έκ°€μž…λ‹ˆλ‹€.
28
  주어진 ν”„λ‘¬ν”„νŠΈλ₯Ό λ‹€μŒ ꡬ쑰에 맞게 κ°œμ„ ν•΄μ£Όμ„Έμš”:
@@ -239,14 +239,7 @@ pipeline = XoraVideoPipeline(
239
  vae=vae,
240
  ).to(device)
241
 
242
- # State λ³€μˆ˜λ“€μ˜ μ΄ˆκΈ°ν™” μˆ˜μ •
243
- txt2vid_current_height = gr.State(value=320)
244
- txt2vid_current_width = gr.State(value=512)
245
- txt2vid_current_num_frames = gr.State(value=257)
246
 
247
- img2vid_current_height = gr.State(value=320)
248
- img2vid_current_width = gr.State(value=512)
249
- img2vid_current_num_frames = gr.State(value=257)
250
 
251
  # Preset options for resolution and frame configuration
252
  # Convert frames to seconds assuming 25 FPS
@@ -279,27 +272,29 @@ preset_options = [
279
  ]
280
 
281
  def preset_changed(preset):
282
- selected = next(item for item in preset_options if item["label"] == preset)
 
 
283
  return [
284
- selected["height"],
285
- selected["width"],
286
- selected["num_frames"],
287
  gr.update(visible=False),
288
  gr.update(visible=False),
289
  gr.update(visible=False),
290
- ]
291
-
292
  def generate_video_from_text(
293
- prompt="",
294
- enhance_prompt_toggle=False,
295
- negative_prompt="low quality, worst quality, deformed, distorted, warped, motion smear, motion artifacts, fused fingers, incorrect anatomy, strange hands, unattractive",
296
- frame_rate=25,
297
- seed=171198,
298
- num_inference_steps=41,
299
- guidance_scale=4,
300
- height=320,
301
- width=512,
302
- num_frames=257,
303
  progress=gr.Progress(),
304
  ):
305
  if len(prompt.strip()) < 50:
@@ -308,10 +303,23 @@ def generate_video_from_text(
308
  duration=5,
309
  )
310
 
 
 
 
 
311
  # Translate Korean prompts to English
312
  prompt = translate_korean_prompt(prompt)
313
  negative_prompt = translate_korean_prompt(negative_prompt)
314
 
 
 
 
 
 
 
 
 
 
315
  sample = {
316
  "prompt": prompt,
317
  "prompt_attention_mask": None,
@@ -354,7 +362,6 @@ def generate_video_from_text(
354
  gc.collect()
355
 
356
  output_path = tempfile.mktemp(suffix=".mp4")
357
- print(images.shape)
358
  video_np = images.squeeze(0).permute(1, 2, 3, 0).cpu().float().numpy()
359
  video_np = (video_np * 255).astype(np.uint8)
360
  height, width = video_np.shape[1:3]
@@ -371,21 +378,20 @@ def generate_video_from_text(
371
 
372
  def generate_video_from_image(
373
  image_path,
374
- prompt="",
375
- enhance_prompt_toggle=False,
376
- negative_prompt="low quality, worst quality, deformed, distorted, warped, motion smear, motion artifacts, fused fingers, incorrect anatomy, strange hands, unattractive",
377
- frame_rate=25,
378
- seed=171198,
379
- num_inference_steps=41,
380
- guidance_scale=4,
381
- height=320,
382
- width=512,
383
- num_frames=257,
384
  progress=gr.Progress(),
385
  ):
386
- print("Height: ", height)
387
- print("Width: ", width)
388
- print("Num Frames: ", num_frames)
389
 
390
  if len(prompt.strip()) < 50:
391
  raise gr.Error(
@@ -393,13 +399,24 @@ def generate_video_from_image(
393
  duration=5,
394
  )
395
 
396
- if not image_path:
397
- raise gr.Error("μž…λ ₯ 이미지λ₯Ό μ œκ³΅ν•΄μ£Όμ„Έμš”.", duration=5)
 
398
 
399
  # Translate Korean prompts to English
400
  prompt = translate_korean_prompt(prompt)
401
  negative_prompt = translate_korean_prompt(negative_prompt)
402
 
 
 
 
 
 
 
 
 
 
 
403
  media_items = (
404
  load_image_to_tensor_with_resize(image_path, height, width).to(device).detach()
405
  )
@@ -447,6 +464,7 @@ def generate_video_from_image(
447
  for frame in video_np[..., ::-1]:
448
  out.write(frame)
449
  out.release()
 
450
  except Exception as e:
451
  raise gr.Error(
452
  f"λΉ„λ””μ˜€ 생성 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”. 였λ₯˜: {e}",
@@ -456,6 +474,12 @@ def generate_video_from_image(
456
  finally:
457
  torch.cuda.empty_cache()
458
  gc.collect()
 
 
 
 
 
 
459
 
460
  return output_path
461
 
@@ -551,99 +575,95 @@ system_prompt_scenario = """당신은 μ˜μƒ μŠ€ν¬λ¦½νŠΈμ— λ§žλŠ” λ°°κ²½ 영
551
 
552
 
553
  def analyze_scenario(scenario):
554
- """μ‹œλ‚˜λ¦¬μ˜€λ₯Ό λΆ„μ„ν•˜μ—¬ λ°°κ²½ μ˜μƒμš© ν”„λ‘¬ν”„νŠΈ 생성"""
555
- messages = [
556
- {"role": "system", "content": system_prompt_scenario},
557
- {"role": "user", "content": f"""
558
- λ‹€μŒ 슀크립트의 λΆ„μœ„κΈ°μ™€ 감성을 ν‘œν˜„ν•  수 μžˆλŠ” λ°°κ²½ μ˜μƒ ν”„λ‘¬ν”„νŠΈλ₯Ό μƒμ„±ν•΄μ£Όμ„Έμš”:
559
-
560
- 주어진 슀크립트의 λΆ„μœ„κΈ°μ™€ λ§₯락을 μ‹œκ°μ  배경으둜 ν‘œν˜„ν•˜λ˜, λ‹€μŒ 원칙을 λ°˜λ“œμ‹œ μ€€μˆ˜ν•˜μ„Έμš”:
561
-
562
- 1. μ œν’ˆμ΄λ‚˜ μ„œλΉ„μŠ€λ₯Ό μ§μ ‘μ μœΌλ‘œ λ¬˜μ‚¬ν•˜μ§€ 말 것
563
- 2. 슀크립트의 감성과 ν†€μ•€λ§€λ„ˆλ₯Ό ν‘œν˜„ν•˜λŠ” λ°°κ²½ μ˜μƒμ— 집쀑할 것
564
- 3. 5개 μ„Ήμ…˜μ΄ ν•˜λ‚˜μ˜ μ΄μ•ΌκΈ°μ²˜λŸΌ μžμ—°μŠ€λŸ½κ²Œ μ—°κ²°λ˜λ„λ‘ ν•  것
565
- 4. 좔상적이고 μ€μœ μ μΈ μ‹œκ° ν‘œν˜„μ„ ν™œμš©ν•  것
566
-
567
- 각 μ„Ήμ…˜λ³„ ν”„λ‘¬ν”„νŠΈ μž‘μ„± κ°€μ΄λ“œ:
568
- 1. λ°°κ²½ 및 ν•„μš”μ„±: 주제의 μ „λ°˜μ μΈ λΆ„μœ„κΈ°λ₯Ό ν‘œν˜„ν•˜λŠ” λ°°κ²½ 씬
569
- 2. ν₯λ―Έ 유발: κΈ΄μž₯κ°μ΄λ‚˜ κ°ˆλ“±μ„ μ•”μ‹œν•˜λŠ” λΆ„μœ„κΈ° μžˆλŠ” λ°°κ²½
570
- 3. ν•΄κ²°μ±… μ œμ‹œ: 희망적이고 밝은 ν†€μ˜ λ°°κ²½ μ „ν™˜
571
- 4. λ³Έλ‘ : μ•ˆμ •κ° 있고 신뒰도λ₯Ό λ†’μ΄λŠ” λ°°κ²½
572
- 5. κ²°λ‘ : μž„νŒ©νŠΈ μžˆλŠ” 마무리λ₯Ό μœ„ν•œ 역동적인 λ°°κ²½
573
-
574
- λͺ¨λ“  μ„Ήμ…˜μ΄ μΌκ΄€λœ μŠ€νƒ€μΌκ³Ό 톀을 μœ μ§€ν•˜λ©΄μ„œλ„ μžμ—°μŠ€λŸ½κ²Œ 이어지도둝 κ΅¬μ„±ν•˜μ„Έμš”.
575
-
576
- 각 μ„Ήμ…˜μ˜ ν”„λ‘¬ν”„νŠΈ μž‘μ„±μ‹œ λ°˜λ“œμ‹œ λ‹€μŒ ꡬ쑰에 맞게 κ°œμ„ ν•΄μ£Όμ„Έμš”:
577
- 1. μ£Όμš” λ™μž‘μ„ λͺ…ν™•ν•œ ν•œ λ¬Έμž₯으둜 μ‹œμž‘
578
- 2. ꡬ체적인 λ™μž‘κ³Ό 제슀처λ₯Ό μ‹œκ°„ μˆœμ„œλŒ€λ‘œ μ„€λͺ…
579
- 3. 캐릭터/객체의 μ™Έλͺ¨λ₯Ό μƒμ„Ένžˆ λ¬˜μ‚¬
580
- 4. λ°°κ²½κ³Ό ν™˜κ²½ μ„ΈλΆ€ 사항을 ꡬ체적으둜 포함
581
- 5. 카메라 각도와 μ›€μ§μž„μ„ λͺ…μ‹œ
582
- 6. μ‘°λͺ…κ³Ό 색상을 μžμ„Ένžˆ μ„€λͺ…
583
- 7. λ³€ν™”λ‚˜ κ°‘μž‘μŠ€λŸ¬μš΄ 사건을 μžμ—°μŠ€λŸ½κ²Œ 포함
584
- λͺ¨λ“  μ„€λͺ…은 ν•˜λ‚˜μ˜ μžμ—°μŠ€λŸ¬μš΄ λ¬Έλ‹¨μœΌλ‘œ μž‘μ„±ν•˜κ³ ,
585
- 촬영 감독이 촬영 λͺ©λ‘μ„ μ„€λͺ…ν•˜λŠ” κ²ƒμ²˜λŸΌ ꡬ체적이고 μ‹œκ°μ μœΌλ‘œ μž‘μ„±ν•˜μ„Έμš”.
586
- 200단어λ₯Ό λ„˜μ§€ μ•Šλ„λ‘ ν•˜λ˜, μ΅œλŒ€ν•œ μƒμ„Έν•˜κ²Œ μž‘μ„±ν•˜μ„Έμš”.
587
 
 
588
  {scenario}
589
 
590
- 각 μ„Ήμ…˜λ³„λ‘œ 직접적인 μ œν’ˆ λ¬˜μ‚¬λŠ” ν”Όν•˜κ³ , 슀크립트의 감성을 ν‘œν˜„ν•˜λŠ” λ°°κ²½ μ˜μƒμ— μ§‘μ€‘ν•΄μ£Όμ„Έμš”."""},
591
- ]
592
-
593
-
594
- response = client.chat.completions.create(
595
- model="gpt-4-1106-preview",
596
- messages=messages,
597
- max_tokens=2000,
598
- )
599
- content = response.choices[0].message.content.strip()
600
-
601
- # μ„Ήμ…˜λ³„λ‘œ 뢄리
602
- sections = []
603
- current_section = ""
604
- for line in content.split('\n'):
605
- if line.strip().startswith(('1.', '2.', '3.', '4.', '5.')):
606
- if current_section:
607
- sections.append(current_section.strip())
608
- current_section = line
609
- else:
610
- current_section += "\n" + line
611
-
612
- if current_section:
613
- sections.append(current_section.strip())
614
 
615
- # λΆ€μ‘±ν•œ μ„Ήμ…˜ μ±„μš°κΈ°
616
- while len(sections) < 5:
617
- sections.append("μΆ”κ°€ μ„Ήμ…˜μ΄ ν•„μš”ν•©λ‹ˆλ‹€.")
618
 
619
- return sections[:5]
 
 
 
620
 
621
  except Exception as e:
622
  print(f"Error during scenario analysis: {e}")
623
  return ["Error occurred during analysis"] * 5
624
 
625
  def generate_section_video(prompt, preset, section_number=1, base_seed=171198, progress=gr.Progress()):
626
- """각 μ„Ήμ…˜μ˜ λΉ„λ””μ˜€ 생성 - μ—λŸ¬ 처리 μΆ”κ°€"""
627
  try:
628
  if not prompt or len(prompt.strip()) < 50:
629
  raise gr.Error("ν”„λ‘¬ν”„νŠΈλŠ” μ΅œμ†Œ 50자 이상이어야 ν•©λ‹ˆλ‹€.")
630
 
631
- selected = next(item for item in preset_options if item["label"] == preset)
 
 
 
 
 
 
632
  section_seed = base_seed + section_number
633
 
634
  return generate_video_from_text(
635
  prompt=prompt,
 
 
 
 
 
 
636
  height=selected["height"],
637
  width=selected["width"],
638
  num_frames=selected["num_frames"],
639
- seed=section_seed,
640
  progress=progress
641
  )
642
  except Exception as e:
643
  print(f"Error in section {section_number}: {e}")
644
  raise gr.Error(f"μ„Ήμ…˜ {section_number} 생성 쀑 였λ₯˜: {str(e)}")
 
 
 
645
 
646
- # κ°œλ³„ μ„Ήμ…˜ ν”„λ‘¬ν”„νŠΈ 생성 ν•¨μˆ˜ μΆ”κ°€
647
  def generate_single_section_prompt(scenario, section_number):
648
  """κ°œλ³„ μ„Ήμ…˜μ— λŒ€ν•œ ν”„λ‘¬ν”„νŠΈ 생성"""
649
  section_descriptions = {
@@ -658,23 +678,35 @@ def generate_single_section_prompt(scenario, section_number):
658
  {"role": "system", "content": system_prompt_scenario},
659
  {"role": "user", "content": f"""
660
  λ‹€μŒ 슀크립트의 {section_number}번째 μ„Ήμ…˜({section_descriptions[section_number]})에 λŒ€ν•œ
661
- λ°°κ²½ μ˜μƒ ν”„λ‘¬ν”„νŠΈλ§Œμ„ μƒμ„±ν•΄μ£Όμ„Έμš”:
662
 
 
663
  {scenario}
664
 
665
- 직접적인 μ œν’ˆ λ¬˜μ‚¬λŠ” ν”Όν•˜κ³ , 슀크립트의 μ£Όμ œμ™€ 감성을 ν‘œν˜„ν•˜λŠ” 핡심 ν‚€μ›Œλ“œλ₯Ό λ°˜μ˜ν•œ λ°°κ²½ μ˜μƒμ— μ§‘μ€‘ν•΄μ£Όμ„Έμš”."""}
 
 
 
 
 
 
 
 
 
666
  ]
667
 
668
  try:
669
  response = client.chat.completions.create(
670
  model="gpt-4-1106-preview",
671
  messages=messages,
672
- max_tokens=500,
 
673
  )
674
- return response.choices[0].message.content.strip()
 
675
  except Exception as e:
676
- print(f"Error during prompt generation: {e}")
677
- return "Error occurred during prompt generation"
678
 
679
 
680
  # λΉ„λ””μ˜€ κ²°ν•© ν•¨μˆ˜ μΆ”κ°€
@@ -716,11 +748,23 @@ def merge_section_videos(section1, section2, section3, section4, section5):
716
  videos = []
717
 
718
  # 각 μ„Ήμ…˜ λΉ„λ””μ˜€ 확인 및 처리
719
- for i, video in enumerate([section1, section2, section3, section4, section5], 1):
720
- if video and os.path.exists(video):
721
- videos.append(video)
 
 
 
 
 
 
 
 
 
 
 
 
722
  else:
723
- raise gr.Error(f"μ„Ήμ…˜ {i}의 μ˜μƒμ΄ μ—†κ±°λ‚˜ μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.")
724
 
725
  if not videos:
726
  raise gr.Error("κ²°ν•©ν•  μ˜μƒμ΄ μ—†μŠ΅λ‹ˆλ‹€.")
@@ -746,388 +790,428 @@ def merge_section_videos(section1, section2, section3, section4, section5):
746
  ret, frame = cap.read()
747
  if not ret:
748
  break
749
- # ν•„μš”ν•œ 경우 ν”„λ ˆμž„ 크기 μ‘°μ •
750
  if frame.shape[:2] != (height, width):
751
  frame = cv2.resize(frame, (width, height))
752
  out.write(frame)
753
  cap.release()
754
 
755
  out.release()
 
756
  return output_path
757
 
758
  except Exception as e:
759
  raise gr.Error(f"λΉ„λ””μ˜€ κ²°ν•© 쀑 였λ₯˜ λ°œμƒ: {e}")
760
 
761
-
762
- # Gradio Interface Definition
763
- with gr.Blocks(theme=gr.themes.Soft()) as iface:
764
- with gr.Tabs():
765
- # Text to Video Tab
766
- with gr.TabItem("ν…μŠ€νŠΈλ‘œ λΉ„λ””μ˜€ λ§Œλ“€κΈ°"):
767
- with gr.Row():
768
- with gr.Column():
769
- txt2vid_prompt = gr.Textbox(
770
- label="Step 1: ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
771
- placeholder="μƒμ„±ν•˜κ³  싢은 λΉ„λ””μ˜€λ₯Ό μ„€λͺ…ν•˜μ„Έμš” (μ΅œμ†Œ 50자)...",
772
- value="κ·€μ—¬μš΄ 고양이",
773
- lines=5,
774
- )
775
- txt2vid_enhance_toggle = Toggle(
776
- label="ν”„λ‘¬ν”„νŠΈ κ°œμ„ ",
777
- value=False,
778
- interactive=True,
779
- )
780
-
781
- txt2vid_negative_prompt = gr.Textbox(
782
- label="Step 2: λ„€κ±°ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
783
- placeholder="λΉ„λ””μ˜€μ—μ„œ μ›ν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό μ„€λͺ…ν•˜μ„Έμš”...",
784
- value="low quality, worst quality, deformed, distorted, warped, motion smear, motion artifacts, fused fingers, incorrect anatomy, strange hands, unattractive",
785
- lines=2,
786
- visible=False
787
- )
788
-
789
- txt2vid_preset = gr.Dropdown(
790
- choices=[p["label"] for p in preset_options],
791
- value="[16:9] 512x320, 10.3초",
792
- label="Step 2: 해상도 프리셋 선택",
793
- )
794
-
795
- txt2vid_frame_rate = gr.Slider(
796
- label="Step 3: ν”„λ ˆμž„ 레이트",
797
- minimum=21,
798
- maximum=30,
799
- step=1,
800
- value=25,
801
- visible=False
802
- )
803
-
804
- txt2vid_advanced = create_advanced_options()
805
- txt2vid_generate = gr.Button(
806
- "Step 3: λΉ„λ””μ˜€ 생성",
807
- variant="primary",
808
- size="lg",
809
- )
810
-
811
- with gr.Column():
812
- txt2vid_output = gr.Video(label="μƒμ„±λœ λΉ„λ””μ˜€")
813
-
814
- # Image to Video Tab
815
- with gr.TabItem("μ΄λ―Έμ§€λ‘œ λΉ„λ””μ˜€ λ§Œλ“€κΈ°"):
816
- with gr.Row():
817
- with gr.Column():
818
- img2vid_image = gr.Image(
819
- type="filepath",
820
- label="Step 1: μž…λ ₯ 이미지 μ—…λ‘œλ“œ",
821
- elem_id="image_upload",
822
- )
823
- img2vid_prompt = gr.Textbox(
824
- label="Step 2: ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
825
- placeholder="이미지λ₯Ό μ–΄λ–»κ²Œ μ• λ‹ˆλ©”μ΄μ…˜ν™”ν• μ§€ μ„€λͺ…ν•˜μ„Έμš” (μ΅œμ†Œ 50자)...",
826
- value="κ·€μ—¬μš΄ 고양이",
827
- lines=5,
828
- )
829
- img2vid_enhance_toggle = Toggle(
830
- label="ν”„λ‘¬ν”„νŠΈ 증강",
831
- value=False,
832
- interactive=True,
833
- )
834
- img2vid_negative_prompt = gr.Textbox(
835
- label="Step 3: λ„€κ±°ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
836
- placeholder="λΉ„λ””μ˜€μ—μ„œ μ›ν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό μ„€λͺ…ν•˜μ„Έμš”...",
837
- value="low quality, worst quality, deformed, distorted, warped, motion smear, motion artifacts, fused fingers, incorrect anatomy, strange hands, unattractive",
838
- lines=2,
839
- visible=False
840
- )
841
-
842
- img2vid_preset = gr.Dropdown(
843
- choices=[p["label"] for p in preset_options],
844
- value="[16:9] 512x320, 10.3초",
845
- label="Step 3: 해상도 프리셋 선택",
846
- )
847
-
848
- img2vid_frame_rate = gr.Slider(
849
- label="Step 4: ν”„λ ˆμž„ 레이트",
850
- minimum=21,
851
- maximum=30,
852
- step=1,
853
- value=25,
854
- visible=False
855
- )
856
-
857
- img2vid_advanced = create_advanced_options()
858
- img2vid_generate = gr.Button(
859
- "Step 4: λΉ„λ””μ˜€ 생성",
860
- variant="primary",
861
- size="lg",
862
- )
863
-
864
- with gr.Column():
865
- img2vid_output = gr.Video(label="μƒμ„±λœ λΉ„λ””μ˜€")
866
-
867
-
868
- # Scenario to Video Tab (Modified)
869
- with gr.TabItem("μ‹œλ‚˜λ¦¬μ˜€λ‘œ λΉ„λ””μ˜€ λ§Œλ“€κΈ°(숏폼)"):
870
- with gr.Row():
871
- with gr.Column(scale=1):
872
- scenario_input = gr.Textbox(
873
- label="μ˜μƒ 슀크립트 μž…λ ₯",
874
- placeholder="전체 μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μž…λ ₯ν•˜μ„Έμš”...",
875
- lines=10
876
- )
877
- scenario_preset = gr.Dropdown(
878
- choices=[p["label"] for p in preset_options],
879
- value="[16:9] 512x320, 10.3초",
880
- label="ν™”λ©΄ 크기 선택"
881
- )
882
- analyze_btn = gr.Button("μ‹œλ‚˜λ¦¬μ˜€ 뢄석 및 ν”„λ‘¬ν”„νŠΈ 생성", variant="primary")
883
-
884
- with gr.Column(scale=2):
885
- with gr.Row():
886
- # μ„Ήμ…˜ 1
887
- with gr.Column():
888
- section1_prompt = gr.Textbox(
889
- label="1. λ°°κ²½ 및 ν•„μš”μ„±",
890
- lines=4
891
- )
892
- with gr.Row():
893
- section1_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
894
- section1_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
895
- section1_video = gr.Video(label="μ„Ήμ…˜ 1 μ˜μƒ")
896
-
897
- # μ„Ήμ…˜ 2
898
- with gr.Column():
899
- section2_prompt = gr.Textbox(
900
- label="2. ν₯λ―Έ 유발",
901
- lines=4
902
- )
903
- with gr.Row():
904
- section2_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
905
- section2_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
906
- section2_video = gr.Video(label="μ„Ήμ…˜ 2 μ˜μƒ")
907
-
908
- with gr.Row():
909
- # μ„Ήμ…˜ 3
910
- with gr.Column():
911
- section3_prompt = gr.Textbox(
912
- label="3. ν•΄κ²°μ±… μ œμ‹œ",
913
- lines=4
914
- )
915
- with gr.Row():
916
- section3_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
917
- section3_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
918
- section3_video = gr.Video(label="μ„Ήμ…˜ 3 μ˜μƒ")
919
-
920
- # μ„Ήμ…˜ 4
921
- with gr.Column():
922
- section4_prompt = gr.Textbox(
923
- label="4. λ³Έλ‘ ",
924
- lines=4
925
- )
926
- with gr.Row():
927
- section4_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
928
- section4_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
929
- section4_video = gr.Video(label="μ„Ήμ…˜ 4 μ˜μƒ")
930
-
931
- with gr.Row():
932
- # μ„Ήμ…˜ 5
933
- with gr.Column():
934
- section5_prompt = gr.Textbox(
935
- label="5. κ²°λ‘  및 κ°•μ‘°",
936
- lines=4
937
- )
938
- with gr.Row():
939
- section5_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
940
- section5_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
941
- section5_video = gr.Video(label="μ„Ήμ…˜ 5 μ˜μƒ")
942
-
943
-
944
-
945
- # 톡합 μ˜μƒ μ„Ήμ…˜ μΆ”κ°€
946
- with gr.Row():
947
- with gr.Column(scale=1):
948
- # 기쑴의 scenario_inputκ³Ό analyze_btn μœ μ§€
949
- merge_videos_btn = gr.Button("톡합 μ˜μƒ 생성", variant="primary", size="lg")
950
 
951
- with gr.Column(scale=2):
952
- # 기쑴의 μ„Ήμ…˜ 1-5 μœ μ§€
953
-
954
- # 톡합 μ˜μƒ 좜λ ₯ μ„Ήμ…˜ μΆ”κ°€
955
- with gr.Row():
956
- merged_video_output = gr.Video(label="톡합 μ˜μƒ")
957
-
958
-
959
-
960
-
961
- # Event handlers
962
- txt2vid_preset.change(
963
- fn=preset_changed,
964
- inputs=[txt2vid_preset],
965
- outputs=[
966
- txt2vid_current_height,
967
- txt2vid_current_width,
968
- txt2vid_current_num_frames,
969
- *txt2vid_advanced[3:]
970
- ]
971
- )
972
-
973
- txt2vid_enhance_toggle.change(
974
- fn=update_prompt_t2v,
975
- inputs=[txt2vid_prompt, txt2vid_enhance_toggle],
976
- outputs=txt2vid_prompt
977
- )
978
-
979
- txt2vid_generate.click(
980
- fn=generate_video_from_text,
981
- inputs=[
982
- txt2vid_prompt,
983
- txt2vid_enhance_toggle,
984
- txt2vid_negative_prompt,
985
- txt2vid_frame_rate,
986
- *txt2vid_advanced[:3],
987
- txt2vid_current_height,
988
- txt2vid_current_width,
989
- txt2vid_current_num_frames,
990
- ],
991
- outputs=txt2vid_output,
992
- concurrency_limit=1,
993
- concurrency_id="generate_video",
994
- queue=True,
995
- )
996
-
997
- img2vid_preset.change(
998
- fn=preset_changed,
999
- inputs=[img2vid_preset],
1000
- outputs=[
1001
- img2vid_current_height,
1002
- img2vid_current_width,
1003
- img2vid_current_num_frames,
1004
- *img2vid_advanced[3:]
1005
- ]
1006
- )
1007
-
1008
- img2vid_enhance_toggle.change(
1009
- fn=update_prompt_i2v,
1010
- inputs=[img2vid_prompt, img2vid_enhance_toggle],
1011
- outputs=img2vid_prompt
1012
- )
1013
-
1014
- img2vid_generate.click(
1015
- fn=generate_video_from_image,
1016
- inputs=[
1017
- img2vid_image,
1018
- img2vid_prompt,
1019
- img2vid_enhance_toggle,
1020
- img2vid_negative_prompt,
1021
- img2vid_frame_rate,
1022
- *img2vid_advanced[:3],
1023
- img2vid_current_height,
1024
- img2vid_current_width,
1025
- img2vid_current_num_frames,
1026
- ],
1027
- outputs=img2vid_output,
1028
- concurrency_limit=1,
1029
- concurrency_id="generate_video",
1030
- queue=True,
1031
- )
1032
-
1033
- # Scenario tab event handlers
1034
- analyze_btn.click(
1035
- fn=analyze_scenario,
1036
- inputs=[scenario_input],
1037
- outputs=[
1038
- section1_prompt, section2_prompt, section3_prompt,
1039
- section4_prompt, section5_prompt
1040
- ]
1041
- )
1042
-
1043
-
1044
- # 각 μ„Ήμ…˜μ˜ ν”„λ‘¬ν”„νŠΈ μž¬μƒμ„± 이벀트 ν•Έλ“€λŸ¬ μΆ”κ°€
1045
- section1_regenerate.click(
1046
- fn=lambda x: generate_single_section_prompt(x, 1),
1047
- inputs=[scenario_input],
1048
- outputs=section1_prompt
1049
- )
1050
-
1051
- section2_regenerate.click(
1052
- fn=lambda x: generate_single_section_prompt(x, 2),
1053
- inputs=[scenario_input],
1054
- outputs=section2_prompt
1055
- )
1056
-
1057
- section3_regenerate.click(
1058
- fn=lambda x: generate_single_section_prompt(x, 3),
1059
- inputs=[scenario_input],
1060
- outputs=section3_prompt
1061
- )
1062
-
1063
- section4_regenerate.click(
1064
- fn=lambda x: generate_single_section_prompt(x, 4),
1065
- inputs=[scenario_input],
1066
- outputs=section4_prompt
1067
- )
1068
 
1069
- section5_regenerate.click(
1070
- fn=lambda x: generate_single_section_prompt(x, 5),
1071
- inputs=[scenario_input],
1072
- outputs=section5_prompt
1073
- )
1074
-
1075
-
1076
- # μ„Ήμ…˜ 생성 이벀트 ν•Έλ“€λŸ¬
1077
- section1_generate.click(
1078
- fn=generate_section_video,
1079
- inputs=[section1_prompt, scenario_preset],
1080
- outputs=section1_video,
1081
- api_name=f"generate_section1"
1082
- )
1083
-
1084
- section2_generate.click(
1085
- fn=lambda p, pr: generate_section_video(p, pr, 2),
1086
- inputs=[section2_prompt, scenario_preset],
1087
- outputs=section2_video,
1088
- api_name=f"generate_section2"
1089
- )
1090
-
1091
- section3_generate.click(
1092
- fn=lambda p, pr: generate_section_video(p, pr, 3),
1093
- inputs=[section3_prompt, scenario_preset],
1094
- outputs=section3_video,
1095
- api_name=f"generate_section3"
1096
- )
1097
-
1098
- section4_generate.click(
1099
- fn=lambda p, pr: generate_section_video(p, pr, 4),
1100
- inputs=[section4_prompt, scenario_preset],
1101
- outputs=section4_video,
1102
- api_name=f"generate_section4"
1103
- )
1104
-
1105
- section5_generate.click(
1106
- fn=lambda p, pr: generate_section_video(p, pr, 5),
1107
- inputs=[section5_prompt, scenario_preset],
1108
- outputs=section5_video,
1109
- api_name=f"generate_section5"
1110
- )
1111
-
1112
-
1113
-
1114
 
1115
 
1116
- # 이벀트 ν•Έλ“€λŸ¬ μΆ”κ°€
1117
- merge_videos_btn.click(
1118
- fn=merge_section_videos,
1119
- inputs=[
1120
- section1_video,
1121
- section2_video,
1122
- section3_video,
1123
- section4_video,
1124
- section5_video
1125
- ],
1126
- outputs=merged_video_output
1127
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1128
 
1129
-
1130
  if __name__ == "__main__":
1131
- iface.queue(max_size=64, default_concurrency_limit=1, api_open=False).launch(
1132
- share=True, show_api=False
1133
- )
 
 
22
  import gc
23
  from openai import OpenAI
24
  import re
25
+ import time
26
  # Load system prompts
27
  system_prompt_t2v = """당신은 λΉ„λ””μ˜€ 생성을 μœ„ν•œ ν”„λ‘¬ν”„νŠΈ μ „λ¬Έκ°€μž…λ‹ˆλ‹€.
28
  주어진 ν”„λ‘¬ν”„νŠΈλ₯Ό λ‹€μŒ ꡬ쑰에 맞게 κ°œμ„ ν•΄μ£Όμ„Έμš”:
 
239
  vae=vae,
240
  ).to(device)
241
 
 
 
 
 
242
 
 
 
 
243
 
244
  # Preset options for resolution and frame configuration
245
  # Convert frames to seconds assuming 25 FPS
 
272
  ]
273
 
274
  def preset_changed(preset):
275
+ selected = next((item for item in preset_options if item["label"] == preset), None)
276
+ if selected is None:
277
+ raise gr.Error("Invalid preset selected")
278
  return [
279
+ gr.State(value=selected["height"]),
280
+ gr.State(value=selected["width"]),
281
+ gr.State(value=selected["num_frames"]),
282
  gr.update(visible=False),
283
  gr.update(visible=False),
284
  gr.update(visible=False),
285
+ ]
286
+
287
  def generate_video_from_text(
288
+ prompt,
289
+ enhance_prompt_toggle,
290
+ negative_prompt,
291
+ frame_rate,
292
+ seed,
293
+ num_inference_steps,
294
+ guidance_scale,
295
+ height,
296
+ width,
297
+ num_frames,
298
  progress=gr.Progress(),
299
  ):
300
  if len(prompt.strip()) < 50:
 
303
  duration=5,
304
  )
305
 
306
+ # ν”„λ‘¬ν”„νŠΈ κ°œμ„ μ΄ ν™œμ„±ν™”λœ 경우
307
+ if enhance_prompt_toggle:
308
+ prompt = enhance_prompt(prompt, "t2v")
309
+
310
  # Translate Korean prompts to English
311
  prompt = translate_korean_prompt(prompt)
312
  negative_prompt = translate_korean_prompt(negative_prompt)
313
 
314
+ # κΈ°λ³Έκ°’ μ„€μ •
315
+ height = height or 320
316
+ width = width or 512
317
+ num_frames = num_frames or 257
318
+ frame_rate = frame_rate or 25
319
+ seed = seed or 171198
320
+ num_inference_steps = num_inference_steps or 41
321
+ guidance_scale = guidance_scale or 4.0
322
+
323
  sample = {
324
  "prompt": prompt,
325
  "prompt_attention_mask": None,
 
362
  gc.collect()
363
 
364
  output_path = tempfile.mktemp(suffix=".mp4")
 
365
  video_np = images.squeeze(0).permute(1, 2, 3, 0).cpu().float().numpy()
366
  video_np = (video_np * 255).astype(np.uint8)
367
  height, width = video_np.shape[1:3]
 
378
 
379
  def generate_video_from_image(
380
  image_path,
381
+ prompt,
382
+ enhance_prompt_toggle,
383
+ negative_prompt,
384
+ frame_rate,
385
+ seed,
386
+ num_inference_steps,
387
+ guidance_scale,
388
+ height,
389
+ width,
390
+ num_frames,
391
  progress=gr.Progress(),
392
  ):
393
+ if not image_path:
394
+ raise gr.Error("μž…λ ₯ 이미지λ₯Ό μ œκ³΅ν•΄μ£Όμ„Έμš”.", duration=5)
 
395
 
396
  if len(prompt.strip()) < 50:
397
  raise gr.Error(
 
399
  duration=5,
400
  )
401
 
402
+ # ν”„λ‘¬ν”„νŠΈ κ°œμ„ μ΄ ν™œμ„±ν™”λœ 경우
403
+ if enhance_prompt_toggle:
404
+ prompt = enhance_prompt(prompt, "i2v")
405
 
406
  # Translate Korean prompts to English
407
  prompt = translate_korean_prompt(prompt)
408
  negative_prompt = translate_korean_prompt(negative_prompt)
409
 
410
+ # κΈ°λ³Έκ°’ μ„€μ •
411
+ height = height or 320
412
+ width = width or 512
413
+ num_frames = num_frames or 257
414
+ frame_rate = frame_rate or 25
415
+ seed = seed or 171198
416
+ num_inference_steps = num_inference_steps or 41
417
+ guidance_scale = guidance_scale or 4.0
418
+
419
+ # 이미지 λ‘œλ“œ 및 μ „μ²˜λ¦¬
420
  media_items = (
421
  load_image_to_tensor_with_resize(image_path, height, width).to(device).detach()
422
  )
 
464
  for frame in video_np[..., ::-1]:
465
  out.write(frame)
466
  out.release()
467
+
468
  except Exception as e:
469
  raise gr.Error(
470
  f"λΉ„λ””μ˜€ 생성 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”. 였λ₯˜: {e}",
 
474
  finally:
475
  torch.cuda.empty_cache()
476
  gc.collect()
477
+ if 'images' in locals():
478
+ del images
479
+ if 'video_np' in locals():
480
+ del video_np
481
+ if 'media_items' in locals():
482
+ del media_items
483
 
484
  return output_path
485
 
 
575
 
576
 
577
  def analyze_scenario(scenario):
578
+ """μ‹œλ‚˜λ¦¬μ˜€λ₯Ό λΆ„μ„ν•˜μ—¬ 각 μ„Ήμ…˜λ³„ λ°°κ²½ μ˜μƒμš© ν”„λ‘¬ν”„νŠΈ 생성"""
579
+ try:
580
+ # 각 μ„Ήμ…˜λ³„ ν”„λ‘¬ν”„νŠΈ 생성을 μœ„ν•œ λ©”μ‹œμ§€ ꡬ성
581
+ section_prompts = []
582
+
583
+ for section_num in range(1, 6):
584
+ section_descriptions = {
585
+ 1: "λ°°κ²½ 및 ν•„μš”μ„±: 주제의 μ „λ°˜μ μΈ λΆ„μœ„κΈ°λ₯Ό ν‘œν˜„ν•˜λŠ” λ°°κ²½ 씬",
586
+ 2: "ν₯λ―Έ 유발: κΈ΄μž₯κ°μ΄λ‚˜ κ°ˆλ“±μ„ μ•”μ‹œν•˜λŠ” λΆ„μœ„κΈ° μžˆλŠ” λ°°κ²½",
587
+ 3: "ν•΄κ²°μ±… μ œμ‹œ: 희망적이고 밝은 ν†€μ˜ λ°°κ²½ μ „ν™˜",
588
+ 4: "λ³Έλ‘ : μ•ˆμ •κ° 있고 신뒰도λ₯Ό λ†’μ΄λŠ” λ°°κ²½",
589
+ 5: "κ²°λ‘ : μž„νŒ©νŠΈ μžˆλŠ” 마무리λ₯Ό μœ„ν•œ 역동적인 λ°°κ²½"
590
+ }
591
+
592
+ messages = [
593
+ {"role": "system", "content": system_prompt_scenario},
594
+ {"role": "user", "content": f"""
595
+ λ‹€μŒ 슀크립트의 {section_num}번째 μ„Ήμ…˜({section_descriptions[section_num]})에 λŒ€ν•œ
596
+ λ°°κ²½ μ˜μƒ ν”„λ‘¬ν”„νŠΈλ₯Ό μƒμ„±ν•΄μ£Όμ„Έμš”.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
597
 
598
+ 슀크립트:
599
  {scenario}
600
 
601
+ μ£Όμ˜μ‚¬ν•­:
602
+ 1. ν•΄λ‹Ή μ„Ήμ…˜μ˜ νŠΉμ„±({section_descriptions[section_num]})에 λ§žλŠ” λΆ„μœ„κΈ°μ™€ 톀을 λ°˜μ˜ν•˜μ„Έμš”.
603
+ 2. 직접적인 μ œν’ˆ/μ„œλΉ„μŠ€ λ¬˜μ‚¬λŠ” ν”Όν•˜κ³ , 감성적이고 μ€μœ μ μΈ λ°°κ²½ μ˜μƒμ— μ§‘μ€‘ν•˜μ„Έμš”.
604
+ 3. λ‹€μŒ ꡬ쑰λ₯Ό λ°˜λ“œμ‹œ ν¬ν•¨ν•˜μ„Έμš”:
605
+ - μ£Όμš” λ™μž‘μ„ λͺ…ν™•ν•œ ν•œ λ¬Έμž₯으둜 μ‹œμž‘
606
+ - ꡬ체적인 λ™μž‘κ³Ό ���슀처λ₯Ό μ‹œκ°„ μˆœμ„œλŒ€λ‘œ μ„€λͺ…
607
+ - λ°°κ²½κ³Ό ν™˜κ²½ μ„ΈλΆ€ 사항을 ꡬ체적으둜 포함
608
+ - 카메라 각도와 μ›€μ§μž„μ„ λͺ…μ‹œ
609
+ - μ‘°λͺ…κ³Ό 색상을 μžμ„Ένžˆ μ„€λͺ…
610
+ - λ³€ν™”λ‚˜ κ°‘μž‘μŠ€λŸ¬μš΄ 사건을 μžμ—°μŠ€λŸ½κ²Œ 포함"""}
611
+ ]
612
+
613
+ response = client.chat.completions.create(
614
+ model="gpt-4-1106-preview",
615
+ messages=messages,
616
+ max_tokens=1000,
617
+ temperature=0.7
618
+ )
 
 
 
 
 
 
619
 
620
+ section_prompt = response.choices[0].message.content.strip()
621
+ section_prompts.append(f"{section_num}. {section_prompt}")
 
622
 
623
+ # API μš”μ²­ 사이에 짧은 λ”œλ ˆμ΄ μΆ”κ°€
624
+ time.sleep(1)
625
+
626
+ return section_prompts
627
 
628
  except Exception as e:
629
  print(f"Error during scenario analysis: {e}")
630
  return ["Error occurred during analysis"] * 5
631
 
632
  def generate_section_video(prompt, preset, section_number=1, base_seed=171198, progress=gr.Progress()):
633
+ """각 μ„Ήμ…˜μ˜ λΉ„λ””μ˜€ 생성"""
634
  try:
635
  if not prompt or len(prompt.strip()) < 50:
636
  raise gr.Error("ν”„λ‘¬ν”„νŠΈλŠ” μ΅œμ†Œ 50자 이상이어야 ν•©λ‹ˆλ‹€.")
637
 
638
+ if not preset:
639
+ raise gr.Error("해상도 프리셋을 μ„ νƒν•΄μ£Όμ„Έμš”.")
640
+
641
+ selected = next((item for item in preset_options if item["label"] == preset), None)
642
+ if not selected:
643
+ raise gr.Error("μ˜¬λ°”λ₯΄μ§€ μ•Šμ€ ν”„λ¦¬μ…‹μž…λ‹ˆλ‹€.")
644
+
645
  section_seed = base_seed + section_number
646
 
647
  return generate_video_from_text(
648
  prompt=prompt,
649
+ enhance_prompt_toggle=False, # μ„Ήμ…˜ μƒμ„±μ‹œλŠ” ν”„λ‘¬ν”„νŠΈ 증강 λΉ„ν™œμ„±ν™”
650
+ negative_prompt="low quality, worst quality, deformed, distorted, warped",
651
+ frame_rate=25,
652
+ seed=section_seed,
653
+ num_inference_steps=41,
654
+ guidance_scale=4.0,
655
  height=selected["height"],
656
  width=selected["width"],
657
  num_frames=selected["num_frames"],
 
658
  progress=progress
659
  )
660
  except Exception as e:
661
  print(f"Error in section {section_number}: {e}")
662
  raise gr.Error(f"μ„Ήμ…˜ {section_number} 생성 쀑 였λ₯˜: {str(e)}")
663
+ finally:
664
+ torch.cuda.empty_cache()
665
+ gc.collect()
666
 
 
667
  def generate_single_section_prompt(scenario, section_number):
668
  """κ°œλ³„ μ„Ήμ…˜μ— λŒ€ν•œ ν”„λ‘¬ν”„νŠΈ 생성"""
669
  section_descriptions = {
 
678
  {"role": "system", "content": system_prompt_scenario},
679
  {"role": "user", "content": f"""
680
  λ‹€μŒ 슀크립트의 {section_number}번째 μ„Ήμ…˜({section_descriptions[section_number]})에 λŒ€ν•œ
681
+ λ°°κ²½ μ˜μƒ ν”„λ‘¬ν”„νŠΈλ₯Ό μƒμ„±ν•΄μ£Όμ„Έμš”.
682
 
683
+ 슀크립트:
684
  {scenario}
685
 
686
+ μ£Όμ˜μ‚¬ν•­:
687
+ 1. ν•΄λ‹Ή μ„Ήμ…˜μ˜ νŠΉμ„±({section_descriptions[section_number]})에 λ§žλŠ” λΆ„μœ„κΈ°μ™€ 톀을 λ°˜μ˜ν•˜μ„Έμš”.
688
+ 2. 직접적인 μ œν’ˆ/μ„œλΉ„μŠ€ λ¬˜μ‚¬λŠ” ν”Όν•˜κ³ , 감성적이고 μ€μœ μ μΈ λ°°κ²½ μ˜μƒμ— μ§‘μ€‘ν•˜μ„Έμš”.
689
+ 3. λ‹€μŒ ꡬ쑰λ₯Ό λ°˜λ“œμ‹œ ν¬ν•¨ν•˜μ„Έμš”:
690
+ - μ£Όμš” λ™μž‘μ„ λͺ…ν™•ν•œ ν•œ λ¬Έμž₯으둜 μ‹œμž‘
691
+ - ꡬ체적인 λ™μž‘κ³Ό 제슀처λ₯Ό μ‹œκ°„ μˆœμ„œλŒ€λ‘œ μ„€λͺ…
692
+ - λ°°κ²½κ³Ό ν™˜κ²½ μ„ΈλΆ€ 사항을 ꡬ체적으둜 포함
693
+ - 카메라 각도와 μ›€μ§μž„μ„ λͺ…μ‹œ
694
+ - μ‘°λͺ…κ³Ό 색상을 μžμ„Ένžˆ μ„€λͺ…
695
+ - λ³€ν™”λ‚˜ κ°‘μž‘μŠ€λŸ¬μš΄ 사건을 μžμ—°μŠ€λŸ½κ²Œ 포함"""}
696
  ]
697
 
698
  try:
699
  response = client.chat.completions.create(
700
  model="gpt-4-1106-preview",
701
  messages=messages,
702
+ max_tokens=1000, # 토큰 수 증가
703
+ temperature=0.7
704
  )
705
+ generated_prompt = response.choices[0].message.content.strip()
706
+ return f"{section_number}. {generated_prompt}"
707
  except Exception as e:
708
+ print(f"Error during prompt generation for section {section_number}: {e}")
709
+ return f"Error occurred during prompt generation for section {section_number}"
710
 
711
 
712
  # λΉ„λ””μ˜€ κ²°ν•© ν•¨μˆ˜ μΆ”κ°€
 
748
  videos = []
749
 
750
  # 각 μ„Ήμ…˜ λΉ„λ””μ˜€ 확인 및 처리
751
+ for i, video_path in enumerate([section1, section2, section3, section4, section5], 1):
752
+ if video_path:
753
+ if os.path.exists(video_path):
754
+ try:
755
+ # λΉ„λ””μ˜€ 파일 검증
756
+ cap = cv2.VideoCapture(video_path)
757
+ if cap.isOpened():
758
+ videos.append(video_path)
759
+ cap.release()
760
+ else:
761
+ raise gr.Error(f"μ„Ήμ…˜ {i}의 μ˜μƒ 파일이 μ†μƒλ˜μ—ˆκ±°λ‚˜ 읽을 수 μ—†μŠ΅λ‹ˆλ‹€.")
762
+ except Exception as e:
763
+ raise gr.Error(f"μ„Ήμ…˜ {i} μ˜μƒ 처리 쀑 였λ₯˜: {str(e)}")
764
+ else:
765
+ raise gr.Error(f"μ„Ήμ…˜ {i}의 μ˜μƒ νŒŒμΌμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.")
766
  else:
767
+ raise gr.Error(f"μ„Ήμ…˜ {i}의 μ˜μƒμ΄ μ—†μŠ΅λ‹ˆλ‹€.")
768
 
769
  if not videos:
770
  raise gr.Error("κ²°ν•©ν•  μ˜μƒμ΄ μ—†μŠ΅λ‹ˆλ‹€.")
 
790
  ret, frame = cap.read()
791
  if not ret:
792
  break
793
+ # ν”„λ ˆμž„ 크기가 λ‹€λ₯Έ 경우 λ¦¬μ‚¬μ΄μ¦ˆ
794
  if frame.shape[:2] != (height, width):
795
  frame = cv2.resize(frame, (width, height))
796
  out.write(frame)
797
  cap.release()
798
 
799
  out.release()
800
+ print(f"Successfully merged {len(videos)} videos")
801
  return output_path
802
 
803
  except Exception as e:
804
  raise gr.Error(f"λΉ„λ””μ˜€ κ²°ν•© 쀑 였λ₯˜ λ°œμƒ: {e}")
805
 
806
+ def generate_script(topic):
807
+ """μ£Όμ œμ— λ§žλŠ” 슀크립트 생성"""
808
+ if not topic:
809
+ return "주제λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
810
 
811
+ messages = [
812
+ {"role": "system", "content": """당신은 μ˜μƒ 슀크립트 μž‘μ„± μ „λ¬Έκ°€μž…λ‹ˆλ‹€.
813
+ 주어진 주제둜 λ‹€μŒ ꡬ쑰에 λ§žλŠ” 5개 μ„Ήμ…˜μ˜ 슀크립트λ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”:
814
+
815
+ 1. λ°°κ²½ 및 ν•„μš”μ„±: 주제 μ†Œκ°œμ™€ μ‹œμ²­μžμ˜ ν₯λ―Έ 유발
816
+ 2. ν₯λ―Έ 유발: ꡬ체적인 λ‚΄μš© μ „κ°œμ™€ ν˜ΈκΈ°μ‹¬ 자극
817
+ 3. ν•΄κ²°μ±… μ œμ‹œ: 핡심 λ‚΄μš©κ³Ό ν•΄κ²°λ°©μ•ˆ μ œμ‹œ
818
+ 4. λ³Έλ‘ : μƒμ„Έν•œ μ„€λͺ…κ³Ό μž₯점 뢀각
819
+ 5. κ²°λ‘ : 핡심 λ©”μ‹œμ§€ 강쑰와 행동 μœ λ„
820
+
821
+ 각 μ„Ήμ…˜μ€ μžμ—°μŠ€λŸ½κ²Œ μ—°κ²°λ˜μ–΄μ•Ό ν•˜λ©°,
822
+ μ „μ²΄μ μœΌλ‘œ μΌκ΄€λœ 톀과 λΆ„μœ„κΈ°λ₯Ό μœ μ§€ν•˜λ©΄μ„œλ„
823
+ μ‹œμ²­μžμ˜ 관심을 λκΉŒμ§€ μœ μ§€ν•  수 μžˆλ„λ‘ μž‘μ„±ν•΄μ£Όμ„Έμš”."""},
824
+ {"role": "user", "content": f"λ‹€μŒ 주제둜 μ˜μƒ 슀크립트λ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”: {topic}"}
825
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
826
 
827
+ try:
828
+ response = client.chat.completions.create(
829
+ model="gpt-4-1106-preview",
830
+ messages=messages,
831
+ max_tokens=2000,
832
+ temperature=0.7
833
+ )
834
+ return response.choices[0].message.content.strip()
835
+ except Exception as e:
836
+ print(f"Error during script generation: {e}")
837
+ return "슀크립트 생성 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
838
 
839
 
840
+ def cleanup():
841
+ """λ©”λͺ¨λ¦¬ 정리 ν•¨μˆ˜"""
842
+ torch.cuda.empty_cache()
843
+ gc.collect()
844
+
845
+ with gr.Blocks(theme="Yntec/HaleyCH_Theme_Orange") as iface:
846
+ # State λ³€μˆ˜λ“€μ˜ μ΄ˆκΈ°ν™”
847
+ txt2vid_current_height = gr.State(value=320)
848
+ txt2vid_current_width = gr.State(value=512)
849
+ txt2vid_current_num_frames = gr.State(value=257)
850
+
851
+ img2vid_current_height = gr.State(value=320)
852
+ img2vid_current_width = gr.State(value=512)
853
+ img2vid_current_num_frames = gr.State(value=257)
854
+
855
+ with gr.Tabs():
856
+ # Text to Video Tab
857
+ with gr.TabItem("ν…μŠ€νŠΈλ‘œ λΉ„λ””μ˜€ λ§Œλ“€κΈ°"):
858
+ with gr.Row():
859
+ with gr.Column():
860
+ txt2vid_prompt = gr.Textbox(
861
+ label="Step 1: ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
862
+ placeholder="μƒμ„±ν•˜κ³  싢은 λΉ„λ””μ˜€λ₯Ό μ„€λͺ…ν•˜μ„Έμš” (μ΅œμ†Œ 50자)...",
863
+ value="κ·€μ—¬μš΄ 고양이",
864
+ lines=5,
865
+ )
866
+ txt2vid_enhance_toggle = Toggle(
867
+ label="ν”„λ‘¬ν”„νŠΈ 증강",
868
+ value=False,
869
+ interactive=True,
870
+ )
871
+ txt2vid_negative_prompt = gr.Textbox(
872
+ label="Step 2: λ„€κ±°ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
873
+ placeholder="λΉ„λ””μ˜€μ—μ„œ μ›ν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό μ„€λͺ…ν•˜μ„Έμš”...",
874
+ value="low quality, worst quality, deformed, distorted, warped, motion smear, motion artifacts, fused fingers, incorrect anatomy, strange hands, unattractive",
875
+ lines=2,
876
+ visible=False
877
+ )
878
+ txt2vid_preset = gr.Dropdown(
879
+ choices=[p["label"] for p in preset_options],
880
+ value="[16:9] 512x320, 10.3초",
881
+ label="Step 2: 해상도 프리셋 선택",
882
+ )
883
+ txt2vid_frame_rate = gr.Slider(
884
+ label="Step 3: ν”„λ ˆμž„ 레이트",
885
+ minimum=21,
886
+ maximum=30,
887
+ step=1,
888
+ value=25,
889
+ visible=False
890
+ )
891
+ txt2vid_advanced = create_advanced_options()
892
+ txt2vid_generate = gr.Button(
893
+ "Step 3: λΉ„λ””μ˜€ 생성",
894
+ variant="primary",
895
+ size="lg",
896
+ )
897
+ with gr.Column():
898
+ txt2vid_output = gr.Video(label="μƒμ„±λœ λΉ„λ””μ˜€")
899
+
900
+
901
+ # Image to Video Tab
902
+ with gr.TabItem("μ΄λ―Έμ§€λ‘œ λΉ„λ””μ˜€ λ§Œλ“€κΈ°"):
903
+ with gr.Row():
904
+ with gr.Column():
905
+ img2vid_image = gr.Image(
906
+ type="filepath",
907
+ label="Step 1: μž…λ ₯ 이미지 μ—…λ‘œλ“œ",
908
+ elem_id="image_upload",
909
+ )
910
+ img2vid_prompt = gr.Textbox(
911
+ label="Step 2: ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
912
+ placeholder="이미지λ₯Ό μ–΄λ–»κ²Œ μ• λ‹ˆλ©”μ΄μ…˜ν™”ν• μ§€ μ„€λͺ…ν•˜μ„Έμš” (μ΅œμ†Œ 50자)...",
913
+ value="κ·€μ—¬μš΄ 고양이",
914
+ lines=5,
915
+ )
916
+ img2vid_enhance_toggle = Toggle(
917
+ label="ν”„λ‘¬ν”„νŠΈ 증강",
918
+ value=False,
919
+ interactive=True,
920
+ )
921
+ img2vid_negative_prompt = gr.Textbox(
922
+ label="Step 3: λ„€κ±°ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈ μž…λ ₯",
923
+ placeholder="λΉ„λ””μ˜€μ—μ„œ μ›ν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό μ„€λͺ…ν•˜μ„Έμš”...",
924
+ value="low quality, worst quality, deformed, distorted, warped, motion smear, motion artifacts, fused fingers, incorrect anatomy, strange hands, unattractive",
925
+ lines=2,
926
+ visible=False
927
+ )
928
+ img2vid_preset = gr.Dropdown(
929
+ choices=[p["label"] for p in preset_options],
930
+ value="[16:9] 512x320, 10.3초",
931
+ label="Step 3: 해상도 프리셋 선택",
932
+ )
933
+ img2vid_frame_rate = gr.Slider(
934
+ label="Step 4: ν”„λ ˆμž„ 레이트",
935
+ minimum=21,
936
+ maximum=30,
937
+ step=1,
938
+ value=25,
939
+ visible=False
940
+ )
941
+ img2vid_advanced = create_advanced_options()
942
+ img2vid_generate = gr.Button(
943
+ "Step 4: λΉ„λ””μ˜€ 생성",
944
+ variant="primary",
945
+ size="lg",
946
+ )
947
+ with gr.Column():
948
+ img2vid_output = gr.Video(label="μƒμ„±λœ λΉ„λ””μ˜€")
949
+
950
+
951
+ # Scenario Tab
952
+ with gr.TabItem("μ‹œλ‚˜λ¦¬μ˜€λ‘œ λΉ„λ””μ˜€ λ§Œλ“€κΈ°(숏폼)"):
953
+ with gr.Row():
954
+ with gr.Column(scale=1):
955
+ script_topic = gr.Textbox(
956
+ label="슀크립트 생성",
957
+ placeholder="겨울 일본 온천 여행을 주제둜 밝은 λŠλ‚ŒμœΌλ‘œ 슀크립트 μƒμ„±ν•˜λΌ",
958
+ lines=2
959
+ )
960
+ generate_script_btn = gr.Button("슀크립트 생성", variant="primary")
961
+
962
+ scenario_input = gr.Textbox(
963
+ label="μ˜μƒ 슀크립트 μž…λ ₯",
964
+ placeholder="전체 μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μž…λ ₯ν•˜μ„Έμš”...",
965
+ lines=10
966
+ )
967
+ scenario_preset = gr.Dropdown(
968
+ choices=[p["label"] for p in preset_options],
969
+ value="[16:9] 512x320, 10.3초",
970
+ label="ν™”λ©΄ 크기 선택"
971
+ )
972
+ analyze_btn = gr.Button("μ‹œλ‚˜λ¦¬μ˜€ 뢄석 및 ν”„λ‘¬ν”„νŠΈ 생성", variant="primary")
973
+
974
+ with gr.Column(scale=2):
975
+ with gr.Row():
976
+ # μ„Ήμ…˜ 1
977
+ with gr.Column():
978
+ section1_prompt = gr.Textbox(
979
+ label="1. λ°°κ²½ 및 ν•„μš”μ„±",
980
+ lines=4
981
+ )
982
+ with gr.Row():
983
+ section1_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
984
+ section1_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
985
+ section1_video = gr.Video(label="μ„Ήμ…˜ 1 μ˜μƒ")
986
+
987
+ # μ„Ήμ…˜ 2
988
+ with gr.Column():
989
+ section2_prompt = gr.Textbox(
990
+ label="2. ν₯λ―Έ 유발",
991
+ lines=4
992
+ )
993
+ with gr.Row():
994
+ section2_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
995
+ section2_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
996
+ section2_video = gr.Video(label="μ„Ήμ…˜ 2 μ˜μƒ")
997
+
998
+
999
+
1000
+ with gr.Row():
1001
+ # μ„Ήμ…˜ 3
1002
+ with gr.Column():
1003
+ section3_prompt = gr.Textbox(
1004
+ label="3. ν•΄κ²°μ±… μ œμ‹œ",
1005
+ lines=4
1006
+ )
1007
+ with gr.Row():
1008
+ section3_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
1009
+ section3_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
1010
+ section3_video = gr.Video(label="μ„Ήμ…˜ 3 μ˜μƒ")
1011
+
1012
+ # μ„Ήμ…˜ 4
1013
+ with gr.Column():
1014
+ section4_prompt = gr.Textbox(
1015
+ label="4. λ³Έλ‘ ",
1016
+ lines=4
1017
+ )
1018
+ with gr.Row():
1019
+ section4_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
1020
+ section4_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
1021
+ section4_video = gr.Video(label="μ„Ήμ…˜ 4 μ˜μƒ")
1022
+
1023
+ with gr.Row():
1024
+ # μ„Ήμ…˜ 5
1025
+ with gr.Column():
1026
+ section5_prompt = gr.Textbox(
1027
+ label="5. κ²°λ‘  및 κ°•μ‘°",
1028
+ lines=4
1029
+ )
1030
+ with gr.Row():
1031
+ section5_regenerate = gr.Button("πŸ”„ ν”„λ‘¬ν”„νŠΈ 생성")
1032
+ section5_generate = gr.Button("πŸ”„ μ˜μƒ 생성")
1033
+ section5_video = gr.Video(label="μ„Ήμ…˜ 5 μ˜μƒ")
1034
+
1035
+ # 톡합 μ˜μƒ μ„Ήμ…˜
1036
+ with gr.Row():
1037
+ with gr.Column(scale=1):
1038
+ merge_videos_btn = gr.Button("톡합 μ˜μƒ 생성", variant="primary", size="lg")
1039
+
1040
+ with gr.Column(scale=2):
1041
+ with gr.Row():
1042
+ merged_video_output = gr.Video(label="톡합 μ˜μƒ")
1043
+
1044
+
1045
+ # Text to Video Tab handlers
1046
+ txt2vid_preset.change(
1047
+ fn=preset_changed,
1048
+ inputs=[txt2vid_preset],
1049
+ outputs=[
1050
+ txt2vid_current_height,
1051
+ txt2vid_current_width,
1052
+ txt2vid_current_num_frames,
1053
+ txt2vid_advanced[3], # height_slider
1054
+ txt2vid_advanced[4], # width_slider
1055
+ txt2vid_advanced[5], # num_frames_slider
1056
+ ]
1057
+ )
1058
+
1059
+ txt2vid_enhance_toggle.change(
1060
+ fn=update_prompt_t2v,
1061
+ inputs=[txt2vid_prompt, txt2vid_enhance_toggle],
1062
+ outputs=txt2vid_prompt
1063
+ )
1064
+
1065
+ txt2vid_generate.click(
1066
+ fn=generate_video_from_text,
1067
+ inputs=[
1068
+ txt2vid_prompt,
1069
+ txt2vid_enhance_toggle,
1070
+ txt2vid_negative_prompt,
1071
+ txt2vid_frame_rate,
1072
+ txt2vid_advanced[0], # seed
1073
+ txt2vid_advanced[1], # inference_steps
1074
+ txt2vid_advanced[2], # guidance_scale
1075
+ txt2vid_current_height,
1076
+ txt2vid_current_width,
1077
+ txt2vid_current_num_frames,
1078
+ ],
1079
+ outputs=txt2vid_output,
1080
+ )
1081
+
1082
+ # Image to Video Tab handlers
1083
+ img2vid_preset.change(
1084
+ fn=preset_changed,
1085
+ inputs=[img2vid_preset],
1086
+ outputs=[
1087
+ img2vid_current_height,
1088
+ img2vid_current_width,
1089
+ img2vid_current_num_frames,
1090
+ img2vid_advanced[3], # height_slider
1091
+ img2vid_advanced[4], # width_slider
1092
+ img2vid_advanced[5], # num_frames_slider
1093
+ ]
1094
+ )
1095
+
1096
+ img2vid_enhance_toggle.change(
1097
+ fn=update_prompt_i2v,
1098
+ inputs=[img2vid_prompt, img2vid_enhance_toggle],
1099
+ outputs=img2vid_prompt
1100
+ )
1101
+
1102
+ img2vid_generate.click(
1103
+ fn=generate_video_from_image,
1104
+ inputs=[
1105
+ img2vid_image,
1106
+ img2vid_prompt,
1107
+ img2vid_enhance_toggle,
1108
+ img2vid_negative_prompt,
1109
+ img2vid_frame_rate,
1110
+ img2vid_advanced[0], # seed
1111
+ img2vid_advanced[1], # inference_steps
1112
+ img2vid_advanced[2], # guidance_scale
1113
+ img2vid_current_height,
1114
+ img2vid_current_width,
1115
+ img2vid_current_num_frames,
1116
+ ],
1117
+ outputs=img2vid_output,
1118
+ )
1119
+
1120
+
1121
+
1122
+ # Scenario Tab handlers
1123
+ generate_script_btn.click(
1124
+ fn=generate_script,
1125
+ inputs=[script_topic],
1126
+ outputs=[scenario_input]
1127
+ )
1128
+
1129
+ analyze_btn.click(
1130
+ fn=analyze_scenario,
1131
+ inputs=[scenario_input],
1132
+ outputs=[
1133
+ section1_prompt, section2_prompt, section3_prompt,
1134
+ section4_prompt, section5_prompt
1135
+ ]
1136
+ )
1137
+
1138
+ # μ„Ήμ…˜λ³„ ν”„λ‘¬ν”„νŠΈ μž¬μƒμ„± ν•Έλ“€λŸ¬
1139
+ section1_regenerate.click(
1140
+ fn=lambda x: generate_single_section_prompt(x, 1),
1141
+ inputs=[scenario_input],
1142
+ outputs=section1_prompt
1143
+ )
1144
+
1145
+ section2_regenerate.click(
1146
+ fn=lambda x: generate_single_section_prompt(x, 2),
1147
+ inputs=[scenario_input],
1148
+ outputs=section2_prompt
1149
+ )
1150
+
1151
+ section3_regenerate.click(
1152
+ fn=lambda x: generate_single_section_prompt(x, 3),
1153
+ inputs=[scenario_input],
1154
+ outputs=section3_prompt
1155
+ )
1156
+
1157
+ section4_regenerate.click(
1158
+ fn=lambda x: generate_single_section_prompt(x, 4),
1159
+ inputs=[scenario_input],
1160
+ outputs=section4_prompt
1161
+ )
1162
+
1163
+ section5_regenerate.click(
1164
+ fn=lambda x: generate_single_section_prompt(x, 5),
1165
+ inputs=[scenario_input],
1166
+ outputs=section5_prompt
1167
+ )
1168
+
1169
+ # μ„Ήμ…˜λ³„ λΉ„λ””μ˜€ 생성 ν•Έλ“€λŸ¬
1170
+ section1_generate.click(
1171
+ fn=lambda p, pr: generate_section_video(p, pr, 1),
1172
+ inputs=[section1_prompt, scenario_preset],
1173
+ outputs=section1_video
1174
+ )
1175
+
1176
+ section2_generate.click(
1177
+ fn=lambda p, pr: generate_section_video(p, pr, 2),
1178
+ inputs=[section2_prompt, scenario_preset],
1179
+ outputs=section2_video
1180
+ )
1181
+
1182
+ section3_generate.click(
1183
+ fn=lambda p, pr: generate_section_video(p, pr, 3),
1184
+ inputs=[section3_prompt, scenario_preset],
1185
+ outputs=section3_video
1186
+ )
1187
+
1188
+ section4_generate.click(
1189
+ fn=lambda p, pr: generate_section_video(p, pr, 4),
1190
+ inputs=[section4_prompt, scenario_preset],
1191
+ outputs=section4_video
1192
+ )
1193
+
1194
+ section5_generate.click(
1195
+ fn=lambda p, pr: generate_section_video(p, pr, 5),
1196
+ inputs=[section5_prompt, scenario_preset],
1197
+ outputs=section5_video
1198
+ )
1199
+
1200
+ # 톡합 μ˜μƒ 생성 ν•Έλ“€λŸ¬
1201
+ merge_videos_btn.click(
1202
+ fn=merge_section_videos,
1203
+ inputs=[
1204
+ section1_video,
1205
+ section2_video,
1206
+ section3_video,
1207
+ section4_video,
1208
+ section5_video
1209
+ ],
1210
+ outputs=merged_video_output
1211
+ )
1212
 
 
1213
  if __name__ == "__main__":
1214
+ iface.queue(max_size=64, default_concurrency_limit=1, api_open=False).launch(
1215
+ share=True,
1216
+ show_api=False
1217
+ )