Ryanus commited on
Commit
c79078d
·
verified ·
1 Parent(s): 4a54b45

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +144 -77
app.py CHANGED
@@ -1,155 +1,222 @@
1
  import gradio as gr
2
  import os
3
  import tempfile
4
- from pathlib import Path
5
  import subprocess
6
  import shutil
 
 
7
 
8
  def setup_environment():
9
- """設置環境和必要的系統包"""
10
  try:
11
- # 安裝FFmpeg (如果需要)
12
- subprocess.run(["apt", "update"], check=True, capture_output=True)
13
- subprocess.run(["apt", "install", "-y", "ffmpeg"], check=True, capture_output=True)
14
- except:
15
- pass
16
 
17
- def download_and_clone_repo():
18
- """克隆GitHub倉庫"""
19
  repo_url = "https://github.com/SamurAIGPT/AI-Youtube-Shorts-Generator.git"
20
  repo_dir = "./AI-Youtube-Shorts-Generator"
21
 
22
- if not os.path.exists(repo_dir):
23
- subprocess.run(["git", "clone", repo_url], check=True)
24
 
25
- return repo_dir
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- def process_youtube_video(youtube_url, openai_api_key, progress=gr.Progress()):
28
- """處理YouTube視頻生成Shorts"""
 
 
 
29
 
30
- if not youtube_url or not openai_api_key:
31
- return None, "請提供YouTube URL和OpenAI API Key"
 
 
 
 
32
 
33
  progress(0.1, desc="初始化環境...")
34
  setup_environment()
35
 
36
  progress(0.2, desc="克隆項目代碼...")
37
- repo_dir = download_and_clone_repo()
 
 
 
 
 
 
 
38
 
39
  # 設置環境變量
40
  env = os.environ.copy()
41
- env["OPENAI_API"] = openai_api_key
42
 
43
  try:
44
- progress(0.3, desc="開始處理視頻...")
45
 
46
- # 切換到項目目錄
47
  original_dir = os.getcwd()
48
  os.chdir(repo_dir)
49
 
50
- # 安裝項目依賴
51
- subprocess.run(["pip", "install", "-r", "requirements.txt"],
52
- check=True, env=env)
53
-
54
- progress(0.5, desc="下載和分析視頻...")
55
-
56
- # 創建臨時輸入文件來模擬用戶輸入
57
  with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:
58
- f.write(youtube_url + '\n')
59
  input_file = f.name
60
 
61
- # 運行主程序
62
  with open(input_file, 'r') as f:
63
  result = subprocess.run(
64
- ["python", "main.py"],
65
  stdin=f,
66
- capture_output=True,
67
- text=True,
68
  env=env,
69
- timeout=300 # 5分鐘超時
70
  )
71
 
72
- progress(0.8, desc="生成Shorts視頻...")
73
-
74
- # 清理臨時文件
75
  os.unlink(input_file)
76
 
77
- # 查找生成的視頻文件
78
- output_files = []
79
- for ext in ['*.mp4', '*.mov', '*.avi']:
80
- output_files.extend(Path('.').glob(f"**/{ext}"))
 
 
81
 
82
  os.chdir(original_dir)
83
 
84
  progress(1.0, desc="處理完成!")
85
 
86
- if output_files:
87
- # 返回第一個找到的視頻文件
88
- video_path = str(output_files[0])
89
- return video_path, f"成功生成 {len(output_files)} 個Shorts視頻!"
 
 
 
90
  else:
91
- return None, f"處理完成但未找到輸出視頻。\n控制台輸出:\n{result.stdout}\n錯誤:\n{result.stderr}"
 
92
 
93
  except subprocess.TimeoutExpired:
94
- return None, "處理超時。請嘗試較短的視頻或檢查網絡連接。"
95
- except Exception as e:
96
  os.chdir(original_dir)
97
- return None, f"處理過程中出現錯誤:{str(e)}"
 
 
 
 
98
 
99
  # 創建Gradio界面
100
- with gr.Blocks(title="AI YouTube Shorts Generator") as demo:
101
  gr.Markdown("""
102
  # 🎬 AI YouTube Shorts Generator
103
 
104
- 將長視頻自動轉換為吸引人的YouTube Shorts!
105
 
106
- ## 功能特點:
107
- - 🎯 自動提取視頻亮點
108
- - 🗣️ 智能說話者檢測
109
- - ✂️ 垂直格式裁剪
110
- - 🤖 基於GPT-4的內容分析
111
  """)
112
 
113
  with gr.Row():
114
  with gr.Column(scale=1):
115
  youtube_url = gr.Textbox(
116
- label="YouTube視頻URL",
117
- placeholder="https://www.youtube.com/watch?v=...",
118
- info="請輸入要處理的YouTube視頻鏈接"
119
  )
120
 
121
  openai_key = gr.Textbox(
122
- label="OpenAI API Key",
123
  type="password",
124
- placeholder="sk-...",
125
- info="需要GPT-4訪問權限的API Key"
126
  )
127
 
128
- process_btn = gr.Button("🚀 生成Shorts", variant="primary")
 
 
129
 
130
  with gr.Column(scale=1):
131
- output_video = gr.Video(label="生成的Shorts視頻")
132
- output_message = gr.Textbox(label="處理狀態", lines=5)
 
 
 
 
 
133
 
134
  gr.Markdown("""
135
- ## 使用說明:
136
- 1. 輸入YouTube視頻URL
137
- 2. 提供OpenAI API Key (需要GPT-4權限)
138
- 3. 點擊生成按鈕等待處理完成
139
- 4. 下載生成的Shorts視頻
140
-
141
- ## 注意事項:
142
- - 處理時間取決於視頻長度,通常需要2-5分鐘
143
- - 確保YouTube視頻可以公開訪問
144
- - API Key將用於內容分析,不會被保存
 
 
 
 
 
 
145
  """)
146
 
 
147
  process_btn.click(
148
- fn=process_youtube_video,
149
  inputs=[youtube_url, openai_key],
150
- outputs=[output_video, output_message],
151
  show_progress=True
152
  )
 
 
 
 
 
153
 
154
  if __name__ == "__main__":
155
- demo.launch()
 
 
 
 
 
1
  import gradio as gr
2
  import os
3
  import tempfile
 
4
  import subprocess
5
  import shutil
6
+ from pathlib import Path
7
+ import sys
8
 
9
  def setup_environment():
10
+ """設置環境"""
11
  try:
12
+ # 確保系統包已安裝
13
+ subprocess.run(["which", "ffmpeg"], check=True, capture_output=True)
14
+ print(" FFmpeg已安裝")
15
+ except subprocess.CalledProcessError:
16
+ print("⚠️ FFmpeg未找到,但Docker鏡像應該已包含")
17
 
18
+ def clone_repo():
19
+ """克隆項目倉庫"""
20
  repo_url = "https://github.com/SamurAIGPT/AI-Youtube-Shorts-Generator.git"
21
  repo_dir = "./AI-Youtube-Shorts-Generator"
22
 
23
+ if os.path.exists(repo_dir):
24
+ shutil.rmtree(repo_dir)
25
 
26
+ try:
27
+ subprocess.run(["git", "clone", repo_url, repo_dir],
28
+ check=True, capture_output=True, text=True)
29
+ return repo_dir, "✅ 項目克隆成功"
30
+ except subprocess.CalledProcessError as e:
31
+ return None, f"❌ 克隆失敗: {e.stderr}"
32
+
33
+ def install_project_deps(repo_dir):
34
+ """安裝項目依賴"""
35
+ try:
36
+ # 進入項目目錄安裝依賴
37
+ original_dir = os.getcwd()
38
+ os.chdir(repo_dir)
39
+
40
+ # 檢查是否有requirements.txt
41
+ if os.path.exists("requirements.txt"):
42
+ result = subprocess.run([
43
+ sys.executable, "-m", "pip", "install", "-r", "requirements.txt"
44
+ ], capture_output=True, text=True, timeout=180)
45
+
46
+ if result.returncode != 0:
47
+ os.chdir(original_dir)
48
+ return False, f"依賴安裝失敗: {result.stderr}"
49
+
50
+ os.chdir(original_dir)
51
+ return True, "✅ 項目依賴安裝成功"
52
+
53
+ except Exception as e:
54
+ if 'original_dir' in locals():
55
+ os.chdir(original_dir)
56
+ return False, f"安裝過程出錯: {str(e)}"
57
 
58
+ def process_video(youtube_url, openai_api_key, progress=gr.Progress()):
59
+ """處理YouTube視頻"""
60
+
61
+ if not youtube_url.strip():
62
+ return None, "❌ 請輸入YouTube URL"
63
 
64
+ if not openai_api_key.strip():
65
+ return None, " 請輸入OpenAI API Key"
66
+
67
+ # 驗證URL格式
68
+ if not any(domain in youtube_url for domain in ['youtube.com', 'youtu.be']):
69
+ return None, "❌ 請輸入有效的YouTube URL"
70
 
71
  progress(0.1, desc="初始化環境...")
72
  setup_environment()
73
 
74
  progress(0.2, desc="克隆項目代碼...")
75
+ repo_dir, clone_msg = clone_repo()
76
+ if not repo_dir:
77
+ return None, clone_msg
78
+
79
+ progress(0.3, desc="安裝項目依賴...")
80
+ deps_ok, deps_msg = install_project_deps(repo_dir)
81
+ if not deps_ok:
82
+ return None, deps_msg
83
 
84
  # 設置環境變量
85
  env = os.environ.copy()
86
+ env["OPENAI_API_KEY"] = openai_api_key
87
 
88
  try:
89
+ progress(0.5, desc="處理視頻中...")
90
 
 
91
  original_dir = os.getcwd()
92
  os.chdir(repo_dir)
93
 
94
+ # 創建輸入文件
 
 
 
 
 
 
95
  with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:
96
+ f.write(f"{youtube_url}\n")
97
  input_file = f.name
98
 
99
+ # 執行主程序
100
  with open(input_file, 'r') as f:
101
  result = subprocess.run(
102
+ [sys.executable, "main.py"],
103
  stdin=f,
104
+ capture_output=True,
105
+ text=True,
106
  env=env,
107
+ timeout=600 # 10分鐘超時
108
  )
109
 
110
+ # 清理輸入文件
 
 
111
  os.unlink(input_file)
112
 
113
+ progress(0.8, desc="查找生成的視頻...")
114
+
115
+ # 查找輸出視頻
116
+ video_files = []
117
+ for pattern in ['*.mp4', '*.avi', '*.mov']:
118
+ video_files.extend(Path('.').rglob(pattern))
119
 
120
  os.chdir(original_dir)
121
 
122
  progress(1.0, desc="處理完成!")
123
 
124
+ if video_files:
125
+ # 復制視頻到當前目錄以便訪問
126
+ output_video = str(video_files[0])
127
+ local_video = f"./output_{os.path.basename(output_video)}"
128
+ shutil.copy2(os.path.join(repo_dir, output_video), local_video)
129
+
130
+ return local_video, f"✅ 成功生成視頻! 找到 {len(video_files)} 個文件。"
131
  else:
132
+ error_msg = f"處理完成但未找到視頻文件。\n\n標準輸出:\n{result.stdout}\n\n錯誤輸出:\n{result.stderr}"
133
+ return None, error_msg
134
 
135
  except subprocess.TimeoutExpired:
 
 
136
  os.chdir(original_dir)
137
+ return None, "❌ 處理超時 (10分鐘)。請嘗試較短的視頻。"
138
+ except Exception as e:
139
+ if 'original_dir' in locals():
140
+ os.chdir(original_dir)
141
+ return None, f"❌ 處理失敗: {str(e)}"
142
 
143
  # 創建Gradio界面
144
+ with gr.Blocks(title="AI YouTube Shorts Generator", theme=gr.themes.Soft()) as demo:
145
  gr.Markdown("""
146
  # 🎬 AI YouTube Shorts Generator
147
 
148
+ 自動將長視頻轉換為吸引人的YouTube Shorts!
149
 
150
+ ## ✨ 功能特點
151
+ - 🎯 **智能內容分析**: 使用GPT-4識別視頻亮點
152
+ - 🗣️ **說話者檢測**: 自動檢測不同說話者
153
+ - ✂️ **垂直裁剪**: 轉換為Shorts格式 (9:16)
154
+ - 🎵 **語音轉錄**: 基於Whisper的高質量轉錄
155
  """)
156
 
157
  with gr.Row():
158
  with gr.Column(scale=1):
159
  youtube_url = gr.Textbox(
160
+ label="📺 YouTube視頻URL",
161
+ placeholder="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
162
+ info="輸入要處理的YouTube視頻鏈接"
163
  )
164
 
165
  openai_key = gr.Textbox(
166
+ label="🔑 OpenAI API Key",
167
  type="password",
168
+ placeholder="sk-proj-...",
169
+ info="需要GPT-4/GPT-4o訪問權限"
170
  )
171
 
172
+ with gr.Row():
173
+ process_btn = gr.Button("🚀 開始生成", variant="primary", size="lg")
174
+ clear_btn = gr.Button("🗑️ 清除", variant="secondary")
175
 
176
  with gr.Column(scale=1):
177
+ output_video = gr.Video(label="🎥 生成的Shorts")
178
+ output_status = gr.Textbox(
179
+ label="📊 處理狀態",
180
+ lines=8,
181
+ max_lines=10,
182
+ show_copy_button=True
183
+ )
184
 
185
  gr.Markdown("""
186
+ ## 📋 使用說明
187
+
188
+ 1. **輸入URL**: 粘貼YouTube視頻鏈接
189
+ 2. **API Key**: 提供OpenAI API密鑰 (需GPT-4權限)
190
+ 3. **開始處理**: 點擊生成按鈕,等待5-10分鐘
191
+ 4. **下載視頻**: 處理完成後下載生成的Shorts
192
+
193
+ ## ⚠️ 注意事項
194
+
195
+ - **處理時間**: 取決於視頻長度,通常5-10分鐘
196
+ - **視頻要求**: 確保YouTube視頻公開可訪問
197
+ - **API用量**: 會消耗OpenAI API額度用於內容分析
198
+ - **格式支持**: 輸出為MP4格式的豎向視頻 (9:16)
199
+
200
+ ---
201
+ 💡 **提示**: 較短的源視頻 (10-30分鐘) 處理效果更佳
202
  """)
203
 
204
+ # 事件綁定
205
  process_btn.click(
206
+ fn=process_video,
207
  inputs=[youtube_url, openai_key],
208
+ outputs=[output_video, output_status],
209
  show_progress=True
210
  )
211
+
212
+ clear_btn.click(
213
+ lambda: ("", "", None, ""),
214
+ outputs=[youtube_url, openai_key, output_video, output_status]
215
+ )
216
 
217
  if __name__ == "__main__":
218
+ demo.launch(
219
+ server_name="0.0.0.0",
220
+ server_port=7860,
221
+ show_error=True
222
+ )