MichaelChou0806 commited on
Commit
51f6ab7
·
verified ·
1 Parent(s): eee7f73

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -131
app.py DELETED
@@ -1,131 +0,0 @@
1
- import os
2
- import time
3
- import shutil
4
- from pydub import AudioSegment
5
- from openai import OpenAI
6
- import gradio as gr
7
- from fastapi import FastAPI, UploadFile, File, Form
8
- from threading import Thread
9
- import uvicorn
10
-
11
- # ======================================================
12
- # 🔐 設定區
13
- # ======================================================
14
- PASSWORD = os.getenv("APP_PASSWORD", "chou")
15
- MAX_SIZE = 25 * 1024 * 1024
16
- client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
17
-
18
- print("===== 🚀 啟動中 =====")
19
- print(f"APP_PASSWORD: {'✅ 已載入' if PASSWORD else '❌ 未載入'}")
20
- print(f"目前密碼內容:{PASSWORD}")
21
-
22
- # ======================================================
23
- # 🎧 音訊轉錄核心
24
- # ======================================================
25
- def split_audio_if_needed(path):
26
- size = os.path.getsize(path)
27
- if size <= MAX_SIZE:
28
- return [path]
29
- audio = AudioSegment.from_file(path)
30
- n = int(size / MAX_SIZE) + 1
31
- chunk_ms = len(audio) / n
32
- parts = []
33
- for i in range(n):
34
- fn = f"chunk_{i+1}.wav"
35
- audio[int(i * chunk_ms):int((i + 1) * chunk_ms)].export(fn, format="wav")
36
- parts.append(fn)
37
- return parts
38
-
39
- def transcribe_core(path, model="whisper-1"):
40
- if path.lower().endswith(".mp4"):
41
- fixed = path[:-4] + ".m4a"
42
- try:
43
- shutil.copy(path, fixed)
44
- path = fixed
45
- except Exception as e:
46
- print(f"⚠️ mp4→m4a 轉檔失敗:{e}")
47
-
48
- chunks = split_audio_if_needed(path)
49
- txts = []
50
- for f in chunks:
51
- with open(f, "rb") as af:
52
- res = client.audio.transcriptions.create(model=model, file=af, response_format="text")
53
- txts.append(res)
54
- full_raw = "\n".join(txts)
55
-
56
- conv_prompt = (
57
- "請將以下內容完整轉換為「繁體中文(台灣用語)」:\n"
58
- "規則:1) 僅做簡→繁字形轉換;2) 不要意譯或改寫;3) 不要添加任何前後綴。\n-----\n" + full_raw
59
- )
60
- trad = client.chat.completions.create(
61
- model="gpt-4o-mini",
62
- messages=[
63
- {"role": "system", "content": "你是嚴格的繁體中文轉換器。"},
64
- {"role": "user", "content": conv_prompt}
65
- ],
66
- temperature=0.0,
67
- ).choices[0].message.content.strip()
68
-
69
- sum_prompt = (
70
- "請用台灣繁體中文撰寫摘要。若內容資訊多,可條列出重點;"
71
- "若內容簡短,請用一句話概述即可。\n\n" + trad
72
- )
73
- summ = client.chat.completions.create(
74
- model="gpt-4o-mini",
75
- messages=[
76
- {"role": "system", "content": "你是一位精準且嚴格使用台灣繁體中文的摘要助手。"},
77
- {"role": "user", "content": sum_prompt}
78
- ],
79
- temperature=0.2,
80
- ).choices[0].message.content.strip()
81
-
82
- return trad, summ
83
-
84
- # ======================================================
85
- # 🌐 FastAPI for 捷徑
86
- # ======================================================
87
- api_app = FastAPI()
88
-
89
- @api_app.post("/api/transcribe")
90
- async def api_transcribe(file: UploadFile = File(...), token: str = Form(...)):
91
- if token != PASSWORD:
92
- return {"error": "Invalid token"}
93
- temp = file.filename
94
- with open(temp, "wb") as f:
95
- f.write(await file.read())
96
- text, summary = transcribe_core(temp)
97
- os.remove(temp)
98
- return {"text": text, "summary": summary}
99
-
100
- # ======================================================
101
- # 💬 Gradio 介面
102
- # ======================================================
103
- def transcribe_with_password(password, file):
104
- if password.strip() != PASSWORD:
105
- return "❌ 密碼錯誤", "", ""
106
- if not file:
107
- return "⚠️ 未選擇檔案", "", ""
108
- text, summary = transcribe_core(file.name)
109
- return "✅ 完成", text, summary
110
-
111
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
112
- gr.Markdown("## 🎧 LINE 語音轉錄與摘要(支援 .m4a / .mp4)")
113
- pw = gr.Textbox(label="輸入密碼", type="password")
114
- f = gr.File(label="上傳音訊檔")
115
- run = gr.Button("開始轉錄 🚀")
116
- s = gr.Textbox(label="狀態", interactive=False)
117
- t = gr.Textbox(label="轉錄結果", lines=10)
118
- su = gr.Textbox(label="AI 摘要", lines=8)
119
- run.click(transcribe_with_password, [pw, f], [s, t, su])
120
-
121
- # ======================================================
122
- # 🚀 啟動
123
- # ======================================================
124
- def run_api():
125
- uvicorn.run(api_app, host="0.0.0.0", port=7861)
126
-
127
- Thread(target=run_api, daemon=True).start()
128
- app = demo # ✅ Hugging Face 主入口使用 Gradio
129
-
130
- if __name__ == "__main__":
131
- demo.launch(server_name="0.0.0.0", server_port=7860)