FalasChen/automatic-speech-recognition
0
1import gradio as gr2from transformers import pipeline3import torch4import os5from pydub import AudioSegment6import torchaudio7 8# 確保環境使用 GPU 加速9device = "cuda:0" if torch.cuda.is_available() else "cpu"10 11# 1️⃣ 初始化 Whisper 語音辨識(支援中英文)12transcriber = pipeline("automatic-speech-recognition", model="openai/whisper-large-v2", device=device)13 14# 2️⃣ 初始化 翻譯模型(支援中翻英 / 英翻中)15translator_en2zh = pipeline("translation", model="Helsinki-NLP/opus-mt-en-zh", device=device)16translator_zh2en = pipeline("translation", model="Helsinki-NLP/opus-mt-zh-en", device=device)17 18# 3️⃣ 語音辨識 + 翻譯函數(即時語音)19def transcribe_and_translate(stream, new_chunk):20 sr, y = new_chunk21 22 # 確保音訊是單聲道23 if y.ndim > 1:24 y = y.mean(axis=1)25 26 # 標準化音訊27 y = y.astype("float32")28 y /= max(1e-6, abs(y).max())29 30 # 串接音訊31 if stream is not None:32 stream = torch.cat([stream, torch.tensor(y)])33 else:34 stream = torch.tensor(y)35 36 # 執行 Whisper 語音辨識37 recognized_text = transcriber({"sampling_rate": sr, "raw": stream.numpy()})["text"]38 39 # 自動翻譯40 if recognized_text.strip():41 if any("\u4e00" <= char <= "\u9fff" for char in recognized_text): # 偵測是否為中文42 translated_text = translator_zh2en(recognized_text)[0]['translation_text']43 else: # 假設為英文44 translated_text = translator_en2zh(recognized_text)[0]['translation_text']45 else:46 translated_text = ""47 48 return stream, recognized_text, translated_text49 50# 4️⃣ 檔案處理函數(MP3 / MP4)51def process_audio_file(audio_file):52 # 檢查檔案大小53 max_size_mb = 50054 file_size_mb = os.path.getsize(audio_file.name) / (1024 * 1024)55 if file_size_mb > max_size_mb:56 return "錯誤:檔案過大,請上傳小於 500MB 的 MP3 或 MP4 檔案。", ""57 58 # 轉換音訊格式(MP3 / MP4 → WAV)59 converted_wav = "/tmp/converted.wav"60 audio = AudioSegment.from_file(audio_file.name)61 audio.export(converted_wav, format="wav")62 63 # 載入 WAV 音訊64 audio, sr = torchaudio.load(converted_wav)65 66 # 確保音訊為單聲道67 if audio.shape[0] > 1:68 audio = audio.mean(dim=0)69 70 # Whisper 語音辨識71 recognized_text = transcriber({"sampling_rate": sr, "raw": audio.numpy()})["text"]72 73 # 翻譯74 if any("\u4e00" <= char <= "\u9fff" for char in recognized_text): # 偵測是否為中文75 translated_text = translator_zh2en(recognized_text)[0]['translation_text']76 else:77 translated_text = translator_en2zh(recognized_text)[0]['translation_text']78 79 return recognized_text, translated_text80 81# 5️⃣ Gradio UI 設計82with gr.Blocks() as demo:83 gr.Markdown("## 🎙️ 即時語音 + 檔案轉錄 & 翻譯")84 gr.Markdown("🚀 **支援中英文語音輸入,並即時翻譯對應文本**")85 86 with gr.Tab("🎤 即時語音辨識"):87 with gr.Row():88 mic_input = gr.Audio(sources=["microphone"], streaming=True, label="🎤 麥克風輸入")89 90 with gr.Row():91 gr.Markdown("📜 **辨識結果(原始語言)**")92 gr.Markdown("🌍 **翻譯結果(對應語言)**")93 94 with gr.Row():95 output_text = gr.Textbox(label="原始語音文本", interactive=False)96 translated_text = gr.Textbox(label="翻譯文本", interactive=False)97 98 gr.Interface(99 transcribe_and_translate,100 ["state", mic_input],101 ["state", output_text, translated_text],102 live=True,103 )104 105 with gr.Tab("🎵 檔案上傳轉錄"):106 with gr.Row():107 file_input = gr.File(label="📂 上傳 MP3 或 MP4 檔案")108 109 with gr.Row():110 gr.Markdown("📜 **轉錄結果(原始語言)**")111 gr.Markdown("🌍 **翻譯結果(對應語言)**")112 113 with gr.Row():114 file_output_text = gr.Textbox(label="轉錄文本", interactive=False)115 file_translated_text = gr.Textbox(label="翻譯文本", interactive=False)116 117 file_button = gr.Button("🚀 開始轉錄")118 119 file_button.click(120 process_audio_file,121 inputs=file_input,122 outputs=[file_output_text, file_translated_text]123 )124 125demo.launch()126 