Ryanus commited on
Commit
dc323de
·
verified ·
1 Parent(s): d4c1a45

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +9 -13
app.py CHANGED
@@ -3,10 +3,10 @@ import gradio as gr
3
  import tempfile
4
  import random
5
  import subprocess
 
6
  from datetime import datetime
7
 
8
  def ffmpeg_cut_video(input_path, start_time, duration, output_path):
9
- """调用ffmpeg剪辑视频片段"""
10
  command = [
11
  'ffmpeg',
12
  '-ss', str(start_time),
@@ -20,11 +20,11 @@ def ffmpeg_cut_video(input_path, start_time, duration, output_path):
20
  return process.returncode == 0
21
 
22
  def concat_videos_ffmpeg(file_list, output_path):
23
- """调用ffmpeg合并多个视频,使用文件列表"""
24
  list_file = tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt')
25
  try:
26
  for f in file_list:
27
- list_file.write(f"file '{f.replace('\'', '\'\\\'\'' )}'\n")
 
28
  list_file.close()
29
 
30
  command = [
@@ -51,7 +51,7 @@ def process_videos(video_files, clip_duration=2, num_output_videos=3):
51
  try:
52
  for idx, video_file in enumerate(video_files):
53
  video_path = video_file.name
54
- # 获取视频总时长
55
  cmd_duration = [
56
  'ffprobe', '-v', 'error',
57
  '-show_entries', 'format=duration',
@@ -60,7 +60,6 @@ def process_videos(video_files, clip_duration=2, num_output_videos=3):
60
  ]
61
  result = subprocess.run(cmd_duration, capture_output=True, text=True)
62
  total_duration = float(result.stdout.strip())
63
- # 按clip_duration分割视频
64
  start = 0.0
65
  count = 0
66
  while start < total_duration:
@@ -73,19 +72,16 @@ def process_videos(video_files, clip_duration=2, num_output_videos=3):
73
  start += duration
74
  count += 1
75
 
76
- # 随机打乱clip顺序
77
  random.shuffle(all_clips)
78
 
79
- # 计算每个输出视频包含的clip数量
80
  clips_per_video = max(1, len(all_clips) // num_output_videos)
81
-
82
  output_files = []
83
 
84
  for i in range(num_output_videos):
85
  start_idx = i * clips_per_video
86
- end_idx = len(all_clips) if i == num_output_videos -1 else (start_idx + clips_per_video)
87
  selected_clips = all_clips[start_idx:end_idx]
88
- output_path = os.path.join(temp_dir, f"mixed_video_{i +1}.mp4")
89
  ok = concat_videos_ffmpeg(selected_clips, output_path)
90
  if not ok:
91
  return "❌ 视频合并失败", []
@@ -98,13 +94,13 @@ def process_videos(video_files, clip_duration=2, num_output_videos=3):
98
 
99
  def main():
100
  with gr.Blocks() as demo:
101
- gr.Markdown("## FFmpeg 自动剪辑混剪视频 (无需任何API)")
102
  video_input = gr.File(file_types=[".mp4", ".mov", ".avi", ".mkv"], file_count="multiple", label="上传视频文件")
103
  clip_duration = gr.Number(value=2, label="剪辑片段时长 (秒)", minimum=1, maximum=30)
104
  num_output = gr.Number(value=3, label="输出混剪视频数量", minimum=1, maximum=10)
105
  btn = gr.Button("开始剪辑")
106
 
107
- status = gr.Textbox(label="剪辑状态", interactive=False, lines=4)
108
  outputs = gr.File(file_count="multiple", label="下载混剪视频")
109
 
110
  def process(video_files, clip_duration, num_output):
@@ -113,6 +109,6 @@ def main():
113
  btn.click(process, inputs=[video_input, clip_duration, num_output], outputs=[status, outputs])
114
 
115
  demo.launch()
116
-
117
  if __name__ == "__main__":
118
  main()
 
3
  import tempfile
4
  import random
5
  import subprocess
6
+ import shutil
7
  from datetime import datetime
8
 
9
  def ffmpeg_cut_video(input_path, start_time, duration, output_path):
 
10
  command = [
11
  'ffmpeg',
12
  '-ss', str(start_time),
 
20
  return process.returncode == 0
21
 
22
  def concat_videos_ffmpeg(file_list, output_path):
 
23
  list_file = tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt')
24
  try:
25
  for f in file_list:
26
+ # 安全写入文件名,避免单引号破坏格式
27
+ list_file.write("file '{}'\n".format(f.replace("'", r"'\''")))
28
  list_file.close()
29
 
30
  command = [
 
51
  try:
52
  for idx, video_file in enumerate(video_files):
53
  video_path = video_file.name
54
+ # 获取视频时长
55
  cmd_duration = [
56
  'ffprobe', '-v', 'error',
57
  '-show_entries', 'format=duration',
 
60
  ]
61
  result = subprocess.run(cmd_duration, capture_output=True, text=True)
62
  total_duration = float(result.stdout.strip())
 
63
  start = 0.0
64
  count = 0
65
  while start < total_duration:
 
72
  start += duration
73
  count += 1
74
 
 
75
  random.shuffle(all_clips)
76
 
 
77
  clips_per_video = max(1, len(all_clips) // num_output_videos)
 
78
  output_files = []
79
 
80
  for i in range(num_output_videos):
81
  start_idx = i * clips_per_video
82
+ end_idx = len(all_clips) if i == num_output_videos - 1 else (start_idx + clips_per_video)
83
  selected_clips = all_clips[start_idx:end_idx]
84
+ output_path = os.path.join(temp_dir, f"mixed_video_{i + 1}.mp4")
85
  ok = concat_videos_ffmpeg(selected_clips, output_path)
86
  if not ok:
87
  return "❌ 视频合并失败", []
 
94
 
95
  def main():
96
  with gr.Blocks() as demo:
97
+ gr.Markdown("## FFmpeg 自动剪辑混剪视频 (API,纯本地 ffmpeg)")
98
  video_input = gr.File(file_types=[".mp4", ".mov", ".avi", ".mkv"], file_count="multiple", label="上传视频文件")
99
  clip_duration = gr.Number(value=2, label="剪辑片段时长 (秒)", minimum=1, maximum=30)
100
  num_output = gr.Number(value=3, label="输出混剪视频数量", minimum=1, maximum=10)
101
  btn = gr.Button("开始剪辑")
102
 
103
+ status = gr.Textbox(label="剪辑状态", interactive=False, lines=5)
104
  outputs = gr.File(file_count="multiple", label="下载混剪视频")
105
 
106
  def process(video_files, clip_duration, num_output):
 
109
  btn.click(process, inputs=[video_input, clip_duration, num_output], outputs=[status, outputs])
110
 
111
  demo.launch()
112
+
113
  if __name__ == "__main__":
114
  main()