BATONZ Tech Blog

M&Aプラットフォーム運営の株式会社バトンズによる技術ブログです。

AI × Vue でリアルタイム翻訳アプリを作ってみた

こんにちは!バトンズのエンジニアをしているr1hです。

今回は第3回LT大会で発表した、リアルタイム翻訳アプリの開発内容をテックブログとしてまとめました。 音声をそのままブラウザ上で録音し、OpenAIのWhisperでテキスト化、DeepLで翻訳し、即座に画面に表示する。そんな翻訳アプリを Nuxt3 + Whisper + DeepL で構築した実践レポートです。

背景と目的

  • 知人から海外旅行に誘われた
  • 「通訳できたら便利なのでは?」と考えた
  • 音声で話す → 翻訳されるUIを作ってみたくなった

使用技術スタック

技術 役割
Nuxt 3 フロントエンドのUI制御とサーバーAPIの仲介処理
OpenAI Whisper API 音声→テキスト変換(Speech to Text)
DeepL API テキスト翻訳(Text to Text)
Tailwind CSS UIスタイリング
Docker 開発・実行環境の統一

構成図

開発ステップ

1. Nuxt 3 プロジェクト作成

npx nuxi init realtime-translator
cd realtime-translator
yarn install

2. Tailwind CSS 導入

yarn add -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
content: [
  "./components/**/*.{js,vue,ts}",
  "./layouts/**/*.{js,vue,ts}",
  "./pages/**/*.{js,vue,ts}",
  "./app.vue"
]

3. 録音(MediaRecorder API)

const mediaRecorder = new MediaRecorder(stream)
mediaRecorder.ondataavailable = (event) => {
  const audioBlob = new Blob([event.data], { type: 'audio/webm' })
  // サーバーに送信して文字起こし
}

録音ボタンを押して MediaRecorder で録音を開始、録音後に .webm 形式でサーバーに送信します。

4. OpenAI Whisper API による音声認識

const formData = new FormData()
formData.append('file', audioBlob, 'speech.webm')
formData.append('model', 'whisper-1')

const res = await fetch('https://api.openai.com/v1/audio/transcriptions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${config.OPENAI_API_KEY}`
  },
  body: formData
})

Whisper API に音声ファイルをPOSTし、返却される text を取得して翻訳に回します。

5. DeepL API連携(テキスト翻訳)

const res = await fetch('https://api-free.deepl.com/v2/translate', {
  method: 'POST',
  headers: {
    Authorization: `DeepL-Auth-Key ${config.DEEPL_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    text: [body.text],
    target_lang: lang
  })
})

DeepL API の無料プランでは一部言語(韓国語、繁体字中国語など)が非対応なので注意が必要です。

6. UI実装(Tailwind CSS)

<template>
  <div class="max-w-xl mx-auto p-4">
    <h1 class="text-xl font-bold mb-4">音声翻訳アプリ</h1>
    <button @click="start" class="bg-blue-500 text-white rounded px-4 py-2">
      録音開始
    </button>
    <p class="mt-4 text-gray-700">翻訳結果:{{ result }}</p>
  </div>
</template>

動作確認方法

yarn dev
# または
docker-compose up --build

http://localhost:3000 にアクセスすると以下のように動作:

  1. 録音開始
  2. 音声 → テキスト
  3. テキスト → DeepL翻訳
  4. 翻訳結果が画面に表示

まとめ・所感

  • OpenAI Whisperの精度と多言語対応力に驚いた
  • DeepLとの組み合わせで高品質な翻訳体験が可能
  • 今後はスマホアプリ化にも挑戦したい

リアルタイム翻訳という一見ハードルの高そうな課題も、今の技術なら個人レベルでもここまで簡単に形にできます。 次回も何か新しい課題に挑戦していきます。