MichaelChou0806 commited on
Commit
d4a2e9a
·
verified ·
1 Parent(s): e5e8232

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -43
app.py CHANGED
@@ -1,11 +1,11 @@
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
- import threading
9
  import uvicorn
10
 
11
  # ======================================================
@@ -27,67 +27,65 @@ def split_audio_if_needed(path):
27
  if size <= MAX_SIZE:
28
  return [path]
29
  audio = AudioSegment.from_file(path)
30
- num = int(size / MAX_SIZE) + 1
31
- chunk_ms = len(audio) / num
32
- files = []
33
- for i in range(num):
34
- start, end = int(i * chunk_ms), int((i + 1) * chunk_ms)
35
- chunk = audio[start:end]
36
  fn = f"chunk_{i+1}.wav"
37
- chunk.export(fn, format="wav")
38
- files.append(fn)
39
- return files
40
 
41
  def transcribe_core(path, model="whisper-1"):
42
- if path and path.lower().endswith(".mp4"):
43
- fixed_path = path[:-4] + ".m4a"
44
  try:
45
- shutil.copy(path, fixed_path)
46
- path = fixed_path
47
  print("🔧 已自動修正 mp4 → m4a")
48
  except Exception as e:
49
  print(f"⚠️ mp4→m4a 轉檔失敗:{e}")
50
 
 
51
  chunks = split_audio_if_needed(path)
52
- raw_parts = []
53
  for f in chunks:
54
  with open(f, "rb") as af:
55
  res = client.audio.transcriptions.create(
56
- model=model,
57
- file=af,
58
- response_format="text"
59
  )
60
- raw_parts.append(res)
61
- full_raw = "\n".join(raw_parts)
62
 
 
63
  conv_prompt = (
64
  "請將以下內容完整轉換為「繁體中文(台灣用語)」:\n"
65
- "規則:1) 僅做簡→繁字形轉換;2) 不要意譯或改寫;3) 不要添加任何前後綴。\n-----\n" + full_raw
66
  )
67
- trad_resp = client.chat.completions.create(
68
  model="gpt-4o-mini",
69
  messages=[
70
  {"role": "system", "content": "你是嚴格的繁體中文轉換器。"},
71
  {"role": "user", "content": conv_prompt}
72
  ],
73
  temperature=0.0,
74
- )
75
- full_trad = trad_resp.choices[0].message.content.strip()
76
 
 
77
  sum_prompt = (
78
- "請用台灣繁體中文撰寫摘要。若內容資訊多,可條列出重點;若內容簡短,請用一句話概述即可。\n\n"
79
- + full_trad
80
  )
81
- sum_resp = client.chat.completions.create(
82
  model="gpt-4o-mini",
83
  messages=[
84
  {"role": "system", "content": "你是一位精準且嚴格使用台灣繁體中文的摘要助手。"},
85
  {"role": "user", "content": sum_prompt}
86
  ],
87
  temperature=0.2,
88
- )
89
- summ = sum_resp.choices[0].message.content.strip()
90
- return full_trad, summ
91
 
92
  # ======================================================
93
  # 💬 Gradio 介面
@@ -111,7 +109,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
111
  run.click(transcribe_with_password, [pw, f], [s, t, su])
112
 
113
  # ======================================================
114
- # 🌐 FastAPI for iPhone 捷徑
115
  # ======================================================
116
  api_app = FastAPI(title="LINE Transcription API")
117
 
@@ -126,25 +124,18 @@ async def api_transcribe(file: UploadFile = File(...), token: str = Form(...)):
126
  os.remove(temp)
127
  return {"text": text, "summary": summary}
128
 
129
- def run_api():
130
- uvicorn.run(api_app, host="0.0.0.0", port=7861)
 
131
 
132
  # ======================================================
133
- # 🚀 啟動(同時啟 Gradio + FastAPI)
134
  # ======================================================
135
-
136
  def run_api():
137
  uvicorn.run(api_app, host="0.0.0.0", port=7861, log_level="info")
138
 
139
- # --- 關鍵修改區 ---
140
- import threading
141
-
142
- # 1️⃣ 讓 FastAPI 在背景執行
143
  threading.Thread(target=run_api, daemon=True).start()
 
144
 
145
- # 2️⃣ 讓 Hugging Face Spaces 主入口指向 Gradio
146
- app = demo # �� 這一行是關鍵,讓 / 顯示你的網頁 UI
147
-
148
- # 3️⃣ 如果本地測試要同時啟動 UI(例如你用 python app.py 執行)
149
  if __name__ == "__main__":
150
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import os
2
  import time
3
  import shutil
4
+ import threading
5
  from pydub import AudioSegment
6
  from openai import OpenAI
7
  import gradio as gr
8
  from fastapi import FastAPI, UploadFile, File, Form
 
9
  import uvicorn
10
 
11
  # ======================================================
 
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
  print("🔧 已自動修正 mp4 → m4a")
46
  except Exception as e:
47
  print(f"⚠️ mp4→m4a 轉檔失敗:{e}")
48
 
49
+ # Whisper 轉錄
50
  chunks = split_audio_if_needed(path)
51
+ txts = []
52
  for f in chunks:
53
  with open(f, "rb") as af:
54
  res = client.audio.transcriptions.create(
55
+ model=model, file=af, response_format="text"
 
 
56
  )
57
+ txts.append(res)
58
+ raw = "\n".join(txts)
59
 
60
+ # 簡→繁
61
  conv_prompt = (
62
  "請將以下內容完整轉換為「繁體中文(台灣用語)」:\n"
63
+ "規則:1) 僅做簡→繁字形轉換;2) 不要意譯或改寫;3) 不要添加任何前後綴。\n-----\n" + raw
64
  )
65
+ trad = client.chat.completions.create(
66
  model="gpt-4o-mini",
67
  messages=[
68
  {"role": "system", "content": "你是嚴格的繁體中文轉換器。"},
69
  {"role": "user", "content": conv_prompt}
70
  ],
71
  temperature=0.0,
72
+ ).choices[0].message.content.strip()
 
73
 
74
+ # 摘要
75
  sum_prompt = (
76
+ "請用台灣繁體中文撰寫摘要。若內容資訊多,可條列出重點;"
77
+ "若內容簡短,請用一句話概述即可。\n\n" + trad
78
  )
79
+ summ = client.chat.completions.create(
80
  model="gpt-4o-mini",
81
  messages=[
82
  {"role": "system", "content": "你是一位精準且嚴格使用台灣繁體中文的摘要助手。"},
83
  {"role": "user", "content": sum_prompt}
84
  ],
85
  temperature=0.2,
86
+ ).choices[0].message.content.strip()
87
+
88
+ return trad, summ
89
 
90
  # ======================================================
91
  # 💬 Gradio 介面
 
109
  run.click(transcribe_with_password, [pw, f], [s, t, su])
110
 
111
  # ======================================================
112
+ # 🌐 FastAPI for 捷徑
113
  # ======================================================
114
  api_app = FastAPI(title="LINE Transcription API")
115
 
 
124
  os.remove(temp)
125
  return {"text": text, "summary": summary}
126
 
127
+ @api_app.get("/api/health")
128
+ def health():
129
+ return {"status": "ok", "time": int(time.time())}
130
 
131
  # ======================================================
132
+ # 🚀 啟動設定(Gradio 為主入口,FastAPI 背景執行)
133
  # ======================================================
 
134
  def run_api():
135
  uvicorn.run(api_app, host="0.0.0.0", port=7861, log_level="info")
136
 
 
 
 
 
137
  threading.Thread(target=run_api, daemon=True).start()
138
+ app = demo # 讓 Hugging Face 正確掛載主頁
139
 
 
 
 
 
140
  if __name__ == "__main__":
141
  demo.launch(server_name="0.0.0.0", server_port=7860)