speech-to-text について
speech-to-textは、音声や動画をテキスト化するElevenLabs Scribe v2のスキルです。バッチ処理とリアルタイム処理に対応し、話者識別、タイムスタンプ、マルチチャンネル処理を備えています。
主な機能
- 01バッチ・リアルタイム文字起こし
- 0290以上の言語に対応
- 03話者分離と識別
- 04単語単位のタイムスタンプ
- 05マルチチャンネル処理と統合
- 06キータームの指定
活用シーン
- 01長時間音声から文字起こしや字幕を作成
- 02会議やインタビューを話者別に文字起こし
- 03マイク音声をリアルタイムで表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ elevenlabs/ skills --skill speech-to-textインストール後、Claude Code で/speech-to-textを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/installation.mdrealtime-client-side.mdrealtime-commit-strategies.mdrealtime-events.mdrealtime-server-side.mdtranscription-options.md詳細
ElevenLabs 音声テキスト変換
Scribe v2 を使って音声をテキストに変換します。90 以上の言語、話者ダイアライゼーション、単語レベルのタイムスタンプに対応しています。
コードを書く前のセットアップ: このプロジェクトで
ELEVENLABS_API_KEYが設定されていない場合は、まずアプリのフォルダーからnpx -y @elevenlabs/cli@latest onboard initを実行し、表示される手順に従ってください。ユーザーのサインインとプロジェクト用キーの保存が行われるため、手動でキーをコピーする必要はありません。それ以外の場合は、インストールガイドをご覧ください。JavaScript では、@elevenlabs/*パッケージのみを使用してください。
クイックスタート
Python
from elevenlabs import ElevenLabs
client = ElevenLabs()
with open("audio.mp3", "rb") as audio_file:
result = client.speech_to_text.convert(file=audio_file, model_id="scribe_v2")
print(result.text)
JavaScript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { createReadStream } from "fs";
const client = new ElevenLabsClient();
const result = await client.speechToText.convert({
file: createReadStream("audio.mp3"),
modelId: "scribe_v2",
});
console.log(result.text);
CLI
elevenlabs speech-to-text convert --file audio.mp3 --model-id scribe_v2
モデル
| モデル ID | 説明 | 最適な用途 |
|---|---|---|
scribe_v2 | 最先端の精度、90 以上の言語に対応 | バッチ文字起こし、字幕、長時間の音声 |
scribe_v2_medical | 医療・臨床音声に特化した認識、90 以上の言語に対応 | 臨床文書、医療口述、患者との通話 |
scribe_v2_realtime | 低レイテンシー(約 150ms) | ライブ文字起こし、音声エージェント |
scribe_v2_realtime_turbo | リアルタイム文字起こしのバリエーション | ライブ文字起こし |
scribe_v2_realtime_lite | リアルタイム文字起こしのバリエーション | ライブ文字起こし |
タイムスタンプ付き文字起こし
単語レベルのタイムスタンプには、タイプ分類と話者識別が含まれます。
result = client.speech_to_text.convert(
file=audio_file, model_id="scribe_v2", timestamps_granularity="word"
)
for word in result.words:
print(f"{word.text}: {word.start}s - {word.end}s (type: {word.type})")
話者ダイアライゼーション
誰が何を話したかを識別します。モデルは各単語に話者 ID を付与するため、会議、インタビューなど、複数の話者がいる音声に便利です。
result = client.speech_to_text.convert(
file=audio_file,
model_id="scribe_v2",
diarize=True
)
for word in result.words:
print(f"[{word.speaker_id}] {word.text}")
通話録音の場合、diarize=true とともに detect_speaker_roles=true を設定すると、バッチ API でダイアライゼーションされた話者に agent と customer のラベルを付けられます。このオプションは use_multi_channel=true とは併用できません。
ワークスペースに登録済みの話者プロフィールがある場合は、diarize=true とともに use_speaker_library=true を設定すると、検出された話者を話者ライブラリと照合できます。
elevenlabs speech-to-text convert \
--file call.mp3 \
--model-id scribe_v2 \
--diarize true \
--detect-speaker-roles true \
--use-speaker-library true
マルチチャンネル音声
各話者が別々の音声チャンネルに分離されている場合は、use_multi_channel=true を使用します。デフォルトでは、API は transcripts の下にチャンネルごとの文字起こしを返します。multichannel_output_style="combined" を設定すると、タイムスタンプ順に統合された 1 つの文字起こしが返され、各単語には channel_index が付きます。
result = client.speech_to_text.convert(
file=audio_file,
model_id="scribe_v2",
use_multi_channel=True,
multichannel_output_style="combined",
)
キータームのプロンプト指定
製品名、専門用語、一般的でない綴りなど、モデルが聞き間違える可能性のある特定の単語を認識しやすくします(最大 100 語)。
result = client.speech_to_text.convert(
file=audio_file,
model_id="scribe_v2",
keyterms=["ElevenLabs", "Scribe", "API"]
)
言語検出
オプションで言語ヒントを指定して、自動検出できます。
result = client.speech_to_text.convert(
file=audio_file,
model_id="scribe_v2",
language_code="eng" # ISO 639-1 or ISO 639-3 code
)
print(f"Detected: {result.language_code} ({result.language_probability:.0%})")
対応フォーマット
音声: MP3、WAV、M4A、FLAC、OGG、WebM、AAC、AIFF、Opus 動画: MP4、AVI、MKV、MOV、WMV、FLV、WebM、MPEG、3GPP
制限: ファイルサイズは最大 5.0GB、長さは最大 10 時間
レスポンス形式
{
"text": "The full transcription text",
"language_code": "eng",
"language_probability": 0.98,
"words": [
{"text": "The", "start": 0.0, "end": 0.15, "type": "word", "speaker_id": "speaker_0"},
{"text": " ", "start": 0.15, "end": 0.16, "type": "spacing", "speaker_id": "speaker_0"}
]
}
単語のタイプ:
word- 実際に発話された単語spacing- 単語間の空白(正確なタイミングの把握に便利です)audio_event- モデルが検出した音声以外の音(笑い声、拍手、音楽など)
エラー処理
try:
result = client.speech_to_text.convert(file=audio_file, model_id="scribe_v2")
except Exception as e:
print(f"Transcription failed: {e}")
よくあるエラー:
- 401:API キーが無効です
- 422:パラメーターが無効です
- 429:レート制限を超過しました
コストの追跡
request-id レスポンスヘッダーを使って使用状況を監視します。
response = client.speech_to_text.with_raw_response.convert(file=audio_file, model_id="scribe_v2")
result = response.data
print(f"Request ID: {response.headers.get('request-id')}")
リアルタイムストリーミング
超低レイテンシー(約 150ms)でライブ文字起こしを行うには、リアルタイム API を使用します。リアルタイム API は、次の 2 種類の文字起こしを生成します。
- 部分的な文字起こし: 音声の処理中に頻繁に更新される暫定結果です。ライブフィードバック(例:ユーザーの発話に合わせてテキストを表示する場合)に使用します。
- 確定済みの文字起こし: 「確定」後の最終的で安定した結果です。アプリケーションの信頼できる情報源として使用します。
「確定」とは、現在のセグメントを確定するようモデルに指示することです。手動で確定する(例:ユーザーが話すのを止めたとき)方法のほか、音声活動検出(VAD)を使って無音時に自動確定する方法もあります。
Python(サーバーサイド)
import asyncio
from elevenlabs import CommitStrategy, ElevenLabs, RealtimeEvents, RealtimeUrlOptions
client = ElevenLabs()
async def transcribe_realtime():
done = asyncio.Event()
connection = await client.speech_to_text.realtime.connect(RealtimeUrlOptions(
model_id="scribe_v2_realtime",
url="https://npr-ice.streamguys1.com/live.mp3",
commit_strategy=CommitStrategy.VAD, # URL streams never commit on their own
include_timestamps=True,
keyterms=["ElevenLabs", "Scribe"],
no_verbatim=True,
))
def on_error(error):
print(f"Error: {error}")
done.set()
connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, lambda data: print(f"Partial: {data.get('text', '')}"))
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, lambda data: print(f"Final: {data.get('text', '')}"))
connection.on(RealtimeEvents.ERROR, on_error)
connection.on(RealtimeEvents.CLOSE, done.set)
try:
await done.wait()
finally:
await connection.close()
asyncio.run(transcribe_realtime())
JavaScript(React を使ったクライアントサイド)
import { useScribe, CommitStrategy } from "@elevenlabs/react";
function TranscriptionComponent() {
const [transcript, setTranscript] = useState("");
const scribe = useScribe({
modelId: "scribe_v2_realtime",
commitStrategy: CommitStrategy.VAD, // Auto-commit on silence for mic input
keyterms: ["ElevenLabs", "Scribe"],
noVerbatim: true,
includeLanguageDetection: true,
onPartialTranscript: (data) => console.log("Partial:", data.text),
onCommittedTranscript: (data) => setTranscript((prev) => prev + data.text),
});
const start = async () => {
// Get token from your backend (never expose API key to client)
const { token } = await fetch("/scribe-token").then((r) => r.json());
await scribe.connect({
token,
microphone: { echoCancellation: true, noiseSuppression: true },
});
};
return <button onClick={start}>Start Recording</button>;
}
コミット方式
| 方式 | 説明 |
|---|---|
| Manual | 準備ができたらcommit()を呼び出します。ファイル処理や、音声セグメントを自分で制御する場合に使用します |
| VAD | 無音を検出すると音声アクティビティ検出が自動的にコミットします。ライブマイク入力に使用します |
includeLanguageDetection: trueを設定すると、遅延した最終文字起こしイベントで検出された言語コードを受け取れます。
// React: set commitStrategy on the hook (recommended for mic input)
import { useScribe, CommitStrategy } from "@elevenlabs/react";
const scribe = useScribe({
modelId: "scribe_v2_realtime",
commitStrategy: CommitStrategy.VAD,
keyterms: ["ElevenLabs", "Scribe"],
noVerbatim: true,
// Optional VAD tuning:
vadSilenceThresholdSecs: 1.5,
vadThreshold: 0.4,
});
// JavaScript client: pass vad config on connect
const connection = await client.speechToText.realtime.connect({
modelId: "scribe_v2_realtime",
keyterms: ["ElevenLabs", "Scribe"],
noVerbatim: true,
vad: {
silenceThresholdSecs: 1.5,
threshold: 0.4,
},
});
イベントの種類
| イベント | 説明 |
|---|---|
partial_transcript | ライブの暫定結果 |
final_transcript | セグメントのコミット前に送信される、安定したセグメント結果 |
final_transcript_with_timestamps | タイムスタンプや検出された言語を含む遅延した最終結果 |
committed_transcript | コミット後の最終結果 |
committed_transcript_with_timestamps | 単語ごとのタイミング情報を含む最終結果 |
committed_transcript_entities | コミットされたセグメントで検出されたエンティティ |
edited_transcript | 文字起こし編集が有効な場合に、コミットされたセグメントの元のテキストと編集後のテキストを示します |
invalid_request | 接続パラメーターが拒否され、セッションが終了します |
error | エラーが発生しました |
詳しくは、リアルタイムのリファレンスをご覧ください。