Update app.py
Browse files
app.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
import os
|
| 2 |
import time
|
|
|
|
| 3 |
from pydub import AudioSegment
|
| 4 |
from openai import OpenAI
|
| 5 |
import gradio as gr
|
|
@@ -82,12 +83,12 @@ def split_audio_if_needed(path):
|
|
| 82 |
return files
|
| 83 |
|
| 84 |
def transcribe_core(path, model):
|
| 85 |
-
# 處理 iPhone LINE 語音(mp4 audio-only)
|
| 86 |
if path.lower().endswith(".mp4"):
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
|
| 92 |
chunks = split_audio_if_needed(path)
|
| 93 |
txts = []
|
|
@@ -104,14 +105,11 @@ def transcribe_core(path, model):
|
|
| 104 |
summ = res.choices[0].message.content.strip()
|
| 105 |
return full, summ
|
| 106 |
|
| 107 |
-
|
| 108 |
# ========================
|
| 109 |
# 💬 主流程
|
| 110 |
# ========================
|
| 111 |
def transcribe_with_password(session_id, password, file, model_choice):
|
| 112 |
-
# 修正注音輸入造成的隱藏字元錯誤
|
| 113 |
password = password.strip().replace(" ", "").replace("\u200b", "")
|
| 114 |
-
|
| 115 |
locked_flag, msg = check_lock(session_id)
|
| 116 |
if locked_flag:
|
| 117 |
return msg, "", ""
|
|
@@ -124,7 +122,6 @@ def transcribe_with_password(session_id, password, file, model_choice):
|
|
| 124 |
full, summ = transcribe_core(file, model_choice)
|
| 125 |
return "✅ 轉錄完成", full, summ
|
| 126 |
|
| 127 |
-
|
| 128 |
def ask_about_transcript(full_text, q):
|
| 129 |
if not full_text.strip():
|
| 130 |
return "⚠️ 尚未有轉錄內容"
|
|
@@ -156,8 +153,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 156 |
label="選擇模型"
|
| 157 |
)
|
| 158 |
|
| 159 |
-
|
| 160 |
-
audio_input = gr.Audio(type="filepath", label="上傳音訊 (.m4a, .aac, .wav)")
|
| 161 |
transcribe_btn = gr.Button("開始轉錄與摘要 🚀")
|
| 162 |
status_box = gr.Textbox(label="狀態", interactive=False)
|
| 163 |
transcript_box = gr.Textbox(label="完整轉錄文字", lines=10)
|
|
@@ -183,7 +179,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 183 |
)
|
| 184 |
ask_btn.click(ask_about_transcript, [transcript_box, user_q], [ai_reply])
|
| 185 |
|
| 186 |
-
# ✅ 正確的 JS
|
| 187 |
copy_js = """
|
| 188 |
async (text) => {
|
| 189 |
try {
|
|
@@ -194,7 +190,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 194 |
}
|
| 195 |
}
|
| 196 |
"""
|
| 197 |
-
|
| 198 |
copy_transcript.click(fn=None, inputs=transcript_box, outputs=None, js=copy_js)
|
| 199 |
copy_summary.click(fn=None, inputs=summary_box, outputs=None, js=copy_js)
|
| 200 |
copy_reply.click(fn=None, inputs=ai_reply, outputs=None, js=copy_js)
|
|
|
|
| 1 |
import os
|
| 2 |
import time
|
| 3 |
+
import shutil
|
| 4 |
from pydub import AudioSegment
|
| 5 |
from openai import OpenAI
|
| 6 |
import gradio as gr
|
|
|
|
| 83 |
return files
|
| 84 |
|
| 85 |
def transcribe_core(path, model):
|
| 86 |
+
# ✅ 處理 iPhone LINE 語音(mp4 audio-only,不轉檔,只改副檔名)
|
| 87 |
if path.lower().endswith(".mp4"):
|
| 88 |
+
fixed_path = path[:-4] + ".m4a"
|
| 89 |
+
shutil.copy(path, fixed_path) # 複製一份改名,不耗資源
|
| 90 |
+
path = fixed_path
|
| 91 |
+
print("🔧 已自動修正 mp4 → m4a")
|
| 92 |
|
| 93 |
chunks = split_audio_if_needed(path)
|
| 94 |
txts = []
|
|
|
|
| 105 |
summ = res.choices[0].message.content.strip()
|
| 106 |
return full, summ
|
| 107 |
|
|
|
|
| 108 |
# ========================
|
| 109 |
# 💬 主流程
|
| 110 |
# ========================
|
| 111 |
def transcribe_with_password(session_id, password, file, model_choice):
|
|
|
|
| 112 |
password = password.strip().replace(" ", "").replace("\u200b", "")
|
|
|
|
| 113 |
locked_flag, msg = check_lock(session_id)
|
| 114 |
if locked_flag:
|
| 115 |
return msg, "", ""
|
|
|
|
| 122 |
full, summ = transcribe_core(file, model_choice)
|
| 123 |
return "✅ 轉錄完成", full, summ
|
| 124 |
|
|
|
|
| 125 |
def ask_about_transcript(full_text, q):
|
| 126 |
if not full_text.strip():
|
| 127 |
return "⚠️ 尚未有轉錄內容"
|
|
|
|
| 153 |
label="選擇模型"
|
| 154 |
)
|
| 155 |
|
| 156 |
+
audio_input = gr.Audio(type="filepath", label="上傳音訊 (.m4a, .aac, .wav, .mp4)")
|
|
|
|
| 157 |
transcribe_btn = gr.Button("開始轉錄與摘要 🚀")
|
| 158 |
status_box = gr.Textbox(label="狀態", interactive=False)
|
| 159 |
transcript_box = gr.Textbox(label="完整轉錄文字", lines=10)
|
|
|
|
| 179 |
)
|
| 180 |
ask_btn.click(ask_about_transcript, [transcript_box, user_q], [ai_reply])
|
| 181 |
|
| 182 |
+
# ✅ 正確的 JS 複製寫法 (Gradio 5.x)
|
| 183 |
copy_js = """
|
| 184 |
async (text) => {
|
| 185 |
try {
|
|
|
|
| 190 |
}
|
| 191 |
}
|
| 192 |
"""
|
|
|
|
| 193 |
copy_transcript.click(fn=None, inputs=transcript_box, outputs=None, js=copy_js)
|
| 194 |
copy_summary.click(fn=None, inputs=summary_box, outputs=None, js=copy_js)
|
| 195 |
copy_reply.click(fn=None, inputs=ai_reply, outputs=None, js=copy_js)
|