OpenAI Whisper API で音声認識アプリを作る|文字起こし・翻訳の実装ガイド
OpenAI Whisper API を使った音声認識アプリの作り方を完全解説。文字起こし、リアルタイム処理、多言語対応、ストリーミング実装まで実例付きで紹介。
OpenAI Whisper は、OpenAI が開発した世界最高レベルの音声認識モデルです。99 の言語に対応し、文字起こしや翻訳を高精度で実行できます。API 経由で簡単に利用でき、2026 年現在では議事録自動作成、動画字幕生成、ポッドキャスト文字起こしなど、様々な用途で採用されています。
Whisper の特徴
- 高精度: 人間に匹敵する認識精度
- 多言語対応: 99 言語(日本語を含む)
- ノイズに強い: 雑音環境でも認識可能
- 翻訳機能: 他言語から英語への自動翻訳
- タイムスタンプ: 各単語の時刻情報付き
- API 経由で簡単利用: インストール不要
Whisper API の料金
| モデル | 料金 |
|---|---|
| whisper-1 | $0.006 / 分 |
例: 60 分の音声ファイルを文字起こしすると、約 $0.36(約54円) です。
基本的な使い方
セットアップ
npm install openai
音声ファイルの文字起こし
import OpenAI from 'openai';
import fs from 'fs';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
async function transcribe(filePath: string) {
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream(filePath),
model: 'whisper-1',
language: 'ja',
});
return transcription.text;
}
const text = await transcribe('./meeting.mp3');
console.log(text);
たったこれだけで、高品質な日本語文字起こしが得られます。
対応フォーマット
- mp3
- mp4
- mpeg
- mpga
- m4a
- wav
- webm
ファイルサイズ制限: 25MB まで。それ以上は分割が必要です。
詳細なオプション
レスポンス形式
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream('audio.mp3'),
model: 'whisper-1',
response_format: 'verbose_json', // 詳細情報付き
language: 'ja',
timestamp_granularities: ['word', 'segment'],
});
// {
// text: "こんにちは、今日はお越しいただきありがとうございます。",
// words: [
// { word: "こんにちは", start: 0.0, end: 0.8 },
// { word: "今日", start: 1.0, end: 1.3 },
// ...
// ],
// segments: [...]
// }
response_format のオプション:
| 値 | 説明 |
|---|---|
json | テキストのみ(デフォルト) |
verbose_json | 詳細情報付き |
text | プレーンテキスト |
srt | 字幕形式(SRT) |
vtt | 字幕形式(WebVTT) |
字幕ファイル(SRT)の生成
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream('video.mp4'),
model: 'whisper-1',
response_format: 'srt',
language: 'ja',
});
fs.writeFileSync('subtitle.srt', transcription);
生成される SRT ファイルの例:
1
00:00:00,000 --> 00:00:02,500
こんにちは、今日はお越しいただき
2
00:00:02,500 --> 00:00:05,000
ありがとうございます。
3
00:00:05,000 --> 00:00:08,300
本日の議題は3つあります。
YouTube や動画プレーヤーに読み込ませるだけで、字幕として使えます。
翻訳機能
Whisper は音声を認識しつつ、英語に翻訳できます。
const translation = await openai.audio.translations.create({
file: fs.createReadStream('japanese-speech.mp3'),
model: 'whisper-1',
});
console.log(translation.text);
// "Hello, thank you for coming today."
注意: 翻訳先は英語固定です。他の言語への翻訳は、文字起こし後に GPT-4 などで翻訳する必要があります。
プロンプトで精度向上
専門用語や固有名詞が多い場合、prompt で文脈を伝えると精度が上がります。
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream('tech-meeting.mp3'),
model: 'whisper-1',
language: 'ja',
prompt: 'この音声は Web 開発に関する会議です。React、TypeScript、Next.js、Vercel などの用語が頻出します。',
});
これにより、AI が「リアクト」ではなく「React」と正しく表記するようになります。
大きなファイルの処理
25MB を超える音声ファイルは、分割が必要です。
import ffmpeg from 'fluent-ffmpeg';
async function splitAudio(inputPath: string, chunkDuration = 300) {
return new Promise((resolve, reject) => {
ffmpeg(inputPath)
.outputOptions([
'-f segment',
`-segment_time ${chunkDuration}`,
'-c copy',
])
.output('chunk_%03d.mp3')
.on('end', resolve)
.on('error', reject)
.run();
});
}
async function transcribeLargeFile(filePath: string) {
await splitAudio(filePath);
const chunks = fs.readdirSync('.').filter(f => f.startsWith('chunk_'));
chunks.sort();
let fullText = '';
for (const chunk of chunks) {
const result = await transcribe(chunk);
fullText += result + '\n';
}
return fullText;
}
実践例1: 議事録自動作成
async function generateMinutes(audioPath: string) {
// Step 1: 音声を文字起こし
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream(audioPath),
model: 'whisper-1',
language: 'ja',
prompt: 'これは技術ミーティングの録音です。',
});
// Step 2: GPT で要約
const summary = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'system',
content: `
議事録を以下の形式で作成してください:
# 議事録
## 概要
(1-2文で)
## 参加者
(わかる範囲で)
## 主な議題
- 項目1
- 項目2
## 決定事項
- 決定1
- 決定2
## TODO
- タスク(担当者・期限)
`,
},
{ role: 'user', content: transcription.text },
],
});
return summary.choices[0].message.content;
}
実践例2: 動画字幕の自動生成
async function generateVideoSubtitles(videoPath: string) {
// 動画から音声を抽出
await new Promise((resolve, reject) => {
ffmpeg(videoPath)
.toFormat('mp3')
.output('temp.mp3')
.on('end', resolve)
.on('error', reject)
.run();
});
// Whisper で SRT 生成
const srt = await openai.audio.transcriptions.create({
file: fs.createReadStream('temp.mp3'),
model: 'whisper-1',
response_format: 'srt',
language: 'ja',
});
// ファイルに保存
fs.writeFileSync('subtitles.srt', srt);
// 動画に字幕を焼き込み
await new Promise((resolve, reject) => {
ffmpeg(videoPath)
.addInput('subtitles.srt')
.outputOptions(['-c:v copy', '-c:s mov_text'])
.output('video_with_subs.mp4')
.on('end', resolve)
.on('error', reject)
.run();
});
// 一時ファイル削除
fs.unlinkSync('temp.mp3');
return 'video_with_subs.mp4';
}
実践例3: ポッドキャスト文字起こし + 要約
async function podcastTranscript(audioPath: string) {
// 文字起こし
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream(audioPath),
model: 'whisper-1',
response_format: 'verbose_json',
language: 'ja',
});
// 話者分離は OpenAI にないため、文脈から推定
const summary = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'system',
content: 'ポッドキャストの文字起こしから、重要なポイントと名言を抽出してください。',
},
{ role: 'user', content: transcription.text },
],
});
return {
fullTranscript: transcription.text,
segments: transcription.segments,
summary: summary.choices[0].message.content,
};
}
Next.js での実装
API ルート
// app/api/transcribe/route.ts
import { NextRequest } from 'next/server';
import OpenAI from 'openai';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export async function POST(req: NextRequest) {
const formData = await req.formData();
const file = formData.get('audio') as File;
if (!file) {
return Response.json({ error: 'No file' }, { status: 400 });
}
const transcription = await openai.audio.transcriptions.create({
file,
model: 'whisper-1',
language: 'ja',
});
return Response.json({ text: transcription.text });
}
フロントエンド
'use client';
import { useState } from 'react';
export default function TranscribePage() {
const [file, setFile] = useState<File | null>(null);
const [result, setResult] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!file) return;
setLoading(true);
const formData = new FormData();
formData.append('audio', file);
const res = await fetch('/api/transcribe', {
method: 'POST',
body: formData,
});
const data = await res.json();
setResult(data.text);
setLoading(false);
};
return (
<form onSubmit={handleSubmit}>
<input
type="file"
accept="audio/*"
onChange={(e) => setFile(e.target.files?.[0] || null)}
/>
<button disabled={loading}>
{loading ? '文字起こし中...' : '送信'}
</button>
{result && <div>{result}</div>}
</form>
);
}
精度向上のテクニック
1. 音声の前処理
- ノイズ除去:
ffmpegでバックグラウンドノイズを除去 - 正規化: 音量を統一
- サンプリングレート: 16kHz に変換(Whisper の内部処理と一致)
ffmpeg -i input.mp3 -af "afftdn, loudnorm" -ar 16000 output.mp3
2. 言語を明示
language パラメータを指定すると、精度が大幅に向上します。
3. 良いプロンプトを与える
文脈情報を prompt で伝えることで、専門用語の認識精度が上がります。
代替手段
| サービス | 特徴 |
|---|---|
| OpenAI Whisper API | 最高精度、有料 |
| Whisper(オープンソース) | 自前ホスティング、無料 |
| Google Speech-to-Text | 話者分離、多機能 |
| AWS Transcribe | AWS 統合 |
| Azure Speech | Microsoft エコシステム |
セルフホスティング
Whisper のオープンソース版を自前で動かせます。
pip install openai-whisper
whisper audio.mp3 --language ja
GPU があれば、API を使わずに無料で実行できます。
まとめ
OpenAI Whisper API を使えば、以下のような用途の音声認識アプリを短時間で構築できます。
- 会議議事録の自動作成
- ポッドキャストの文字起こし
- 動画字幕の自動生成
- 音声メモのテキスト化
- コールセンターの通話記録
- 外国語会議の翻訳
API は使いやすく、精度も高いため、まず試してみる価値があります。$0.006/分 という低コストで、業務効率化の大きなインパクトが期待できます。