CoolFace
Apppublic

FalasChen/automatic-speech-recognition

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py126 linesDownload Raw Back to root
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