Ryanus commited on
Commit
1642d1a
·
verified ·
1 Parent(s): fb241ba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -5
app.py CHANGED
@@ -522,8 +522,8 @@ def concat_videos(file_list, output_path):
522
  except:
523
  pass
524
 
525
- def process_single_video(video_file, clip_duration, temp_dir):
526
- """[优化] 处理单个视频文件,返回其所有切片路径的列表"""
527
  video_path = video_file.name
528
  clips = []
529
  try:
@@ -532,13 +532,19 @@ def process_single_video(video_file, clip_duration, temp_dir):
532
  result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
533
  total_duration = float(result.stdout.strip())
534
  print(f"视频总时长: {total_duration} 秒")
 
 
 
 
 
 
535
  except Exception as e:
536
  print(f"处理视频 {video_path} 时获取时长失败: {e}")
537
  return clips
538
 
539
  start = 0.0
540
  count = 0
541
- while start < total_duration:
542
  duration = min(clip_duration, total_duration - start)
543
  # 修改文件名,包含原始文件名和计数,避免不同视频的切片重名
544
  clip_path = os.path.join(temp_dir, f"clip_{os.path.splitext(os.path.basename(video_path))[0]}_{count}.mp4")
@@ -554,6 +560,7 @@ def process_single_video(video_file, clip_duration, temp_dir):
554
  start += clip_duration
555
  count += 1
556
 
 
557
  return clips
558
 
559
  def process_videos_with_storage(video_files, clip_duration, num_output_videos, target_ratio):
@@ -575,8 +582,15 @@ def process_videos_with_storage(video_files, clip_duration, num_output_videos, t
575
  # 使用线程池进行并行处理(避免GIL限制)
576
  print(f"🚀 启动并行切片({min(4, os.cpu_count() or 1)} 线程)...")
577
  with concurrent.futures.ThreadPoolExecutor(max_workers=min(4, os.cpu_count() or 1)) as executor:
 
 
 
 
 
 
 
578
  future_to_video = {
579
- executor.submit(process_single_video, vf, clip_duration, temp_dir): vf
580
  for vf in video_files
581
  }
582
 
@@ -597,6 +611,12 @@ def process_videos_with_storage(video_files, clip_duration, num_output_videos, t
597
  if not all_clips:
598
  return "❌ 切割失败,请检查视频文件", None, "", ""
599
 
 
 
 
 
 
 
600
  random.shuffle(all_clips)
601
  clips_per_video = max(1, len(all_clips) // num_output_videos)
602
  output_files = []
@@ -808,7 +828,7 @@ def main():
808
 
809
  with gr.Row():
810
  clip_duration = gr.Number(value=3, label="切片时长(秒)", minimum=1, maximum=3600)
811
- num_output = gr.Number(value=3, label="生成数量", minimum=1, maximum=100)
812
 
813
  ratio_selection = gr.Radio(
814
  choices=["9:16", "16:9"],
@@ -952,6 +972,11 @@ def main():
952
  - **快速预设**: 使用ultrafast预设提升速度
953
  - **并行处理**: 多个视频同时处理
954
 
 
 
 
 
 
955
  **⚠️ 注意事项:**
956
  - 下载文件为ZIP格式,需要解压使用
957
  - 一键下载包含储存空间中所有视频文件
 
522
  except:
523
  pass
524
 
525
+ def process_single_video(video_file, clip_duration, temp_dir, max_clips=50):
526
+ """[优化] 处理单个视频文件,返回其所有切片路径的列表,限制最大片段数"""
527
  video_path = video_file.name
528
  clips = []
529
  try:
 
532
  result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
533
  total_duration = float(result.stdout.strip())
534
  print(f"视频总时长: {total_duration} 秒")
535
+
536
+ # 计算需要多少个片段
537
+ max_possible_clips = int(total_duration / clip_duration) + 1
538
+ actual_max_clips = min(max_possible_clips, max_clips)
539
+ print(f"将生成最多 {actual_max_clips} 个片段")
540
+
541
  except Exception as e:
542
  print(f"处理视频 {video_path} 时获取时长失败: {e}")
543
  return clips
544
 
545
  start = 0.0
546
  count = 0
547
+ while start < total_duration and count < actual_max_clips:
548
  duration = min(clip_duration, total_duration - start)
549
  # 修改文件名,包含原始文件名和计数,避免不同视频的切片重名
550
  clip_path = os.path.join(temp_dir, f"clip_{os.path.splitext(os.path.basename(video_path))[0]}_{count}.mp4")
 
560
  start += clip_duration
561
  count += 1
562
 
563
+ print(f"实际生成 {len(clips)} 个片段")
564
  return clips
565
 
566
  def process_videos_with_storage(video_files, clip_duration, num_output_videos, target_ratio):
 
582
  # 使用线程池进行并行处理(避免GIL限制)
583
  print(f"🚀 启动并行切片({min(4, os.cpu_count() or 1)} 线程)...")
584
  with concurrent.futures.ThreadPoolExecutor(max_workers=min(4, os.cpu_count() or 1)) as executor:
585
+ # 计算每个视频最多需要多少个片段
586
+ # 为了生成num_output_videos个混剪视频,每个混剪视频需要3-5个片段
587
+ # 所以总共需要大约 num_output_videos * 4 个片段
588
+ # 如果有多个视频,平均分配
589
+ total_needed_clips = num_output_videos * 4 # 每个混剪视频平均4个片段
590
+ clips_per_video = max(10, total_needed_clips // len(video_files)) # 每个视频至少10个片段
591
+
592
  future_to_video = {
593
+ executor.submit(process_single_video, vf, clip_duration, temp_dir, clips_per_video): vf
594
  for vf in video_files
595
  }
596
 
 
611
  if not all_clips:
612
  return "❌ 切割失败,请检查视频文件", None, "", ""
613
 
614
+ # 如果片段太多,随机选择需要的数量
615
+ if len(all_clips) > total_needed_clips:
616
+ print(f"片段数量({len(all_clips)})超过需求({total_needed_clips}),随机选择...")
617
+ all_clips = random.sample(all_clips, total_needed_clips)
618
+ print(f"选择后剩余 {len(all_clips)} 个片段")
619
+
620
  random.shuffle(all_clips)
621
  clips_per_video = max(1, len(all_clips) // num_output_videos)
622
  output_files = []
 
828
 
829
  with gr.Row():
830
  clip_duration = gr.Number(value=3, label="切片时长(秒)", minimum=1, maximum=3600)
831
+ num_output = gr.Number(value=5, label="生成数量", minimum=1, maximum=100)
832
 
833
  ratio_selection = gr.Radio(
834
  choices=["9:16", "16:9"],
 
972
  - **快速预设**: 使用ultrafast预设提升速度
973
  - **并行处理**: 多个视频同时处理
974
 
975
+ **🎯 智能切片:**
976
+ - **按需生成**: 根据要生成的视频数量智能计算需要的片段数
977
+ - **避免冗余**: 不会生成超过需要的片段,节省处理时间
978
+ - **随机选择**: 从生成的片段中随机选择,确保混剪多样性
979
+
980
  **⚠️ 注意事项:**
981
  - 下载文件为ZIP格式,需要解压使用
982
  - 一键下载包含储存空间中所有视频文件