即時語音辨識概述
即時語音辨識 API 允許您將音訊串流即時傳送到「聽有 AI」服務,並接收即時的辨識結果。這項功能特別適用於客服系統、會議記錄、即時字幕等需要低延遲回應的應用場景。核心優勢
超低延遲
< 200ms 的回應時間,提供流暢的即時體驗
串流處理
支援連續音訊串流,無需等待完整音檔
中間結果
提供即時的中間辨識結果,提升使用者體驗
自動斷句
智能偵測語音停頓,自動分段處理
WebSocket 連線
即時語音辨識使用 WebSocket 協定進行雙向通訊:連線端點
Copy
wss://api.skiesoft.com/asr
連線參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
api_key | string | 是 | API 金鑰 |
基本連線範例
Copy
const WebSocket = require('ws');
const fs = require('fs');
const SERVER_URL = 'wss://api.skiesoft.com/asr';
const WEBM_FILE_PATH = 'input.webm';
const API_TOKEN = 'your-api-token-here';
const ws = new WebSocket(SERVER_URL, {
headers: { 'Authorization': `Bearer ${API_TOKEN}` }
});
ws.on('open', async () => {
console.log('連接成功');
const fileStream = fs.createReadStream(WEBM_FILE_PATH);
fileStream.on('data', (data) => {
ws.send(data);
});
fileStream.on('end', () => {
ws.send(Buffer.alloc(0)); // 發送空 buffer 表示結束
console.log('文件發送完成');
});
});
ws.on('message', (message) => {
const data = JSON.parse(message.toString());
console.log('收到訊息:', data);
if (data.type === 'ready_to_stop') {
ws.close();
}
});
使用 SDK 進行即時辨識
Node.js SDK
Copy
const { SkiesoftVoice } = require('@skiesoft/voice-sdk');
const client = new SkiesoftVoice({
apiKey: process.env.SKIESOFT_API_KEY,
projectId: process.env.SKIESOFT_PROJECT_ID
});
// 建立即時串流
const stream = client.createRealTimeStream({
language: 'mixed',
sampleRate: 16000,
encoding: 'LINEAR16',
interimResults: true,
enableAutomaticPunctuation: true
});
// 監聽辨識結果
stream.on('data', (result) => {
if (result.isFinal) {
console.log('最終結果:', result.transcript);
console.log('信心度:', result.confidence);
} else {
console.log('中間結果:', result.transcript);
}
});
// 監聽錯誤
stream.on('error', (error) => {
console.error('辨識錯誤:', error);
});
// 監聽連線狀態
stream.on('connect', () => {
console.log('即時辨識已連線');
});
stream.on('disconnect', () => {
console.log('即時辨識已斷線');
});
發送音訊資料
Copy
// 從麥克風獲取音訊
const mic = require('mic');
const micInstance = mic({
rate: '16000',
channels: '1',
debug: false,
exitOnSilence: 6
});
const micInputStream = micInstance.getAudioStream();
micInputStream.on('data', (data) => {
// 發送音訊資料到即時辨識串流
stream.write(data);
});
// 開始錄音
micInstance.start();
進階配置
完整配置選項
Copy
const stream = client.createRealTimeStream({
// 基本設定
language: 'mixed', // 語言設定
sampleRate: 16000, // 採樣率
encoding: 'LINEAR16', // 編碼格式
// 辨識設定
interimResults: true, // 顯示中間結果
enableAutomaticPunctuation: true, // 自動標點符號
enableWordTimeOffsets: true, // 詞彙時間軸
enableWordConfidence: true, // 詞彙信心度
// 進階功能
enableSpeakerDiarization: true, // 說話者分離
maxSpeakers: 2, // 最大說話者數
enableVoiceActivityDetection: true, // 語音活動偵測
model: 'general',
});
語音活動偵測
自動偵測語音開始和結束:Copy
stream.on('speechStart', () => {
console.log('偵測到語音開始');
});
stream.on('speechEnd', () => {
console.log('語音結束');
});
stream.on('silence', (duration) => {
console.log(`靜音持續 ${duration}ms`);
});
結果處理
結果格式
Copy
{
"type": "result",
"result": {
"transcript": "你好,歡迎使用聽有 AI",
"confidence": 0.95,
"isFinal": true,
"startTime": 1.2,
"endTime": 3.8,
"language": "zh-TW",
"words": [
{
"text": "你好",
"startTime": 1.2,
"endTime": 1.8,
"confidence": 0.98
},
{
"text": "歡迎",
"startTime": 2.0,
"endTime": 2.4,
"confidence": 0.96
}
],
"speaker": 1
}
}
處理不同類型的結果
Copy
stream.on('data', (result) => {
switch (result.type) {
case 'interim':
// 中間結果,可能會改變
updateTranscriptPreview(result.transcript);
break;
case 'final':
// 最終結果,不會再改變
addFinalTranscript(result.transcript);
break;
case 'speaker_change':
// 說話者切換
console.log(`說話者切換至: ${result.speaker}`);
break;
}
});
實際應用範例
1. 即時會議記錄
Copy
class MeetingTranscriber {
constructor() {
this.stream = client.createRealTimeStream({
language: 'mixed',
enableSpeakerDiarization: true,
maxSpeakers: 6,
enableAutomaticPunctuation: true
});
this.transcript = [];
this.setupEventHandlers();
}
setupEventHandlers() {
this.stream.on('data', (result) => {
if (result.isFinal) {
this.transcript.push({
speaker: result.speaker,
text: result.transcript,
timestamp: new Date(),
confidence: result.confidence
});
this.updateUI();
}
});
}
startRecording() {
// 開始錄音邏輯
this.micInstance.start();
}
stopRecording() {
this.micInstance.stop();
this.stream.end();
}
exportTranscript() {
return this.transcript.map(entry =>
`[${entry.timestamp.toLocaleTimeString()}] 說話者 ${entry.speaker}: ${entry.text}`
).join('\n');
}
}
3. 即時字幕系統
Copy
class LiveCaptionSystem {
constructor(videoElement) {
this.videoElement = videoElement;
this.captionContainer = document.getElementById('captions');
this.stream = client.createRealTimeStream({
language: 'mixed',
interimResults: true,
enableAutomaticPunctuation: true
});
this.setupCaptions();
}
setupCaptions() {
let currentCaption = '';
this.stream.on('data', (result) => {
if (result.isFinal) {
// 顯示最終字幕
this.addCaption(result.transcript);
currentCaption = '';
} else {
// 更新暫時字幕
currentCaption = result.transcript;
this.updateTempCaption(currentCaption);
}
});
}
addCaption(text) {
const captionElement = document.createElement('div');
captionElement.className = 'caption-line';
captionElement.textContent = text;
this.captionContainer.appendChild(captionElement);
// 自動滾動
this.captionContainer.scrollTop = this.captionContainer.scrollHeight;
// 清理舊字幕
this.cleanupOldCaptions();
}
updateTempCaption(text) {
let tempElement = this.captionContainer.querySelector('.temp-caption');
if (!tempElement) {
tempElement = document.createElement('div');
tempElement.className = 'temp-caption';
this.captionContainer.appendChild(tempElement);
}
tempElement.textContent = text;
}
}
效能優化
音訊緩衝管理
Copy
class AudioBuffer {
constructor(maxSize = 1024 * 1024) { // 1MB
this.buffer = Buffer.alloc(0);
this.maxSize = maxSize;
}
append(chunk) {
this.buffer = Buffer.concat([this.buffer, chunk]);
// 防止緩衝區過大
if (this.buffer.length > this.maxSize) {
this.buffer = this.buffer.slice(-this.maxSize);
}
}
flush() {
const data = this.buffer;
this.buffer = Buffer.alloc(0);
return data;
}
}
連線重連機制
Copy
class ReliableRealTimeStream {
constructor(config) {
this.config = config;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectDelay = 1000;
this.connect();
}
connect() {
this.stream = client.createRealTimeStream(this.config);
this.stream.on('error', (error) => {
console.error('串流錯誤:', error);
this.handleReconnect();
});
this.stream.on('disconnect', () => {
console.log('連線中斷');
this.handleReconnect();
});
}
handleReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
setTimeout(() => {
console.log(`重新連線嘗試 ${this.reconnectAttempts}`);
this.connect();
}, this.reconnectDelay * this.reconnectAttempts);
} else {
console.error('重連失敗,已達最大嘗試次數');
}
}
}
錯誤處理
常見錯誤類型
Copy
stream.on('error', (error) => {
switch (error.code) {
case 'CONNECTION_FAILED':
console.error('連線失敗,請檢查網路狀態');
break;
case 'AUTHENTICATION_FAILED':
console.error('身份驗證失敗,請檢查 API 金鑰');
break;
case 'QUOTA_EXCEEDED':
console.error('配額已用完');
break;
case 'RATE_LIMIT_EXCEEDED':
console.error('請求頻率過高');
break;
case 'AUDIO_FORMAT_ERROR':
console.error('音訊格式錯誤');
break;
default:
console.error('未知錯誤:', error.message);
}
});
最佳實踐
1. 音訊品質
- 使用 16kHz 採樣率以獲得最佳效果
- 確保音訊為單聲道
- 實作噪音抑制和回音消除
2. 網路優化
- 實作連線重連機制
- 監控網路延遲和丟包
- 使用適當的緩衝區大小
3. 使用者體驗
- 顯示連線狀態指示器
- 提供中間結果預覽
- 實作語音活動視覺化
4. 資源管理
- 適時關閉不需要的串流
- 監控記憶體使用量
- 實作音訊資料壓縮
需要即時語音辨識技術支援?請聯絡我們:support@skiesoft.com
