2022.02.22
まとめ
この記事を読んだ人へのオススメ
-
2022.04.18
-
2022.02.17
-
2022.05.18
-
2022.07.01
Twilioブログ
2022.02.22
こんにちは、Twilioマーケ部のkatsu.tです。
本記事では、音声認識市場シェアNo.1の「AmiVoice Cloud Platform」とTwilioを連携させて、通話内容を音声認識させる方法をご紹介いたします。
TwilioとAmiVoice Cloud Platformを利用して通話内容を音声認識させる方法
「AmiVoice」は20年以上のノウハウ・データが蓄積された、高精度かつ高速の音声認識エンジンです。「日本語」や「専門用語」に強く、ビジネスシーンや専門性の高い作業現場など幅広いシーンで活用されています。
エンジンには最新のディープラーニング技術や、双方向型のディープラーニング技術「Bi-LSTM(Bidirectional Long Short-Term Memory)」を実装しています。これにより従来の音声認識エンジンと比較して、エラー改善率が最大25%向上しました。
優れた音響モデルと言語モデルを用い、話した言葉をリアルタイムにテキスト化します。
(※アドバンスト・メディア様サイトより)
Twilioで通話音声を取得する方法として、「通話を録音する」「音声ストリームを取得する」の2通りが挙げられます。
本章では、それぞれの方法で通話音声を取得する方法をご紹介いたします
Twilioで通話を録音するには、下記2通りの手段を用いることができます。
ここでは、それぞれの利用方法についてご紹介いたします。
TwilioのRecord動詞を利用して通話音声を録音する方法です。
最もシンプルな利用例
<Response> <Record/> </Response>
※録音開始後にTwiMLを利用したい場合は、actionパラメータの後続に続くTwiMLを返すURLを設定してください。
また発信時に録音する場合は、recordパラメータにtrueを設定することで通話内容を録音できます。
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require('twilio')(accountSid, authToken);
client.calls
.create({
twiml: 'Ahoy there!',
to: '+819012345678',
from: '+1512345678',
record: true
})
.then(call => console.log(call.sid));
そのほか、オプションでRecord動詞のtranscribe属性をtrueに設定しておけば、録音された通話音声をテキスト化することも可能です。
Twilio Studioを利用して録音する場合、転送した通話を録音する際はCall Recording ウィジェット、留守番電話のように一方的な音声を録音する際はRecord Voicemailウィジェットを利用します。
※Call RecordingウィジェットはTriggerウィジェットに直接つなぐことはできません。音声を録音する旨を音声として流し、その後Call Recordingウィジェットを接続しましょう。
Twilioでは、通話音声ストリームをリアルタイムに取り出してやり取りできるMedia Streamsを提供しています。これによりDialogflowやAmazon Lexなどと連携し、電話を利用した音声ボットを作成することも可能です。
音声ボットやリアルタイム音声認識など、さまざまなサンプルが公開されています。ご興味のある方はぜひご参照ください。
Media Streamsを利用する場合は、下記TwiMLを利用し、接続先のWebSocketのURLを指定します。
<Response> <Start> <Stream url="wss://mystream.ngrok.io/audiostream" /> </Start> </Response>
「AmiVoice Cloud Platform」における音声認識の方法は2種類あります。
Twilioでは前述の「音声通話を録音する方法」を用いて作成した録音ファイルを音声認識する方法と、MediaStreamsを利用してWebsocket経由でリアルタイムに音声データを音声認識する方法のどちらも利用できます。
ここでは、それぞれの文字起こし方法について詳しくご説明いたします。
TwiMLとTwilio Studioのどちらを利用する場合でも、音声認識するためのコードは共通して利用できます。
どちらも録音終了後のステータスコールバックを受け取ることができ、このコールバックのパラメータに音声ファイルへのリンクURLが含まれます。
そのリンクURLをAmiVoice側に渡すことで、対象の音声ファイルを音声認識できます。
TwiMLを利用する際はrecordingStatusCallbackにURLを設定することで、コールバックを受け取ることができます。
※他のパラメータや詳細についてはこちらをご覧ください。
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Record recordingStatusCallback="your url" />
</Response>
Twilio Studioを利用する際は、ウィジェットのRecording Status Callback欄にコールバックさせたいURLを設定します。
本記事では、Twilio Functionsを利用したコード例を記載します。
※Twilio Functionsでは長時間の処理をおこなえません。音声ファイルが大きい場合は別のサービスをご利用ください。
※AmiVoiceのAPI仕様はこちらをご参照ください。
// 必要なライブラリをインポート
var Axios = require('axios');
var Fs = require('fs');
const FormData = require("form-data");
// main処理
exports.handler = async function(context, event, callback) {
const filePath = await download(event.RecordingUrl);
// APIキーは事前に環境変数に設定してください。
const result = await postToAmivoice(filePath,context.AMIVOICE_API_KEY);
console.log(result.text);
callback(null,result);
};
// Twilioの録音ファイルをファイルに一時保存
async function download(url) {
return new Promise(async (resolve, reject) => {
try {
const tmp_file = require('os').tmpdir() + '/tmp.wav';
const writer = Fs.createWriteStream(tmp_file);
const response = await Axios({
url:url,
method: 'GET',
responseType: 'stream'
})
response.data.pipe(writer);
writer.on('finish', resolve(tmp_file))
writer.on('error', reject)
} catch(error) {
reject(error);
}
})
}
// 音声ファイルをAmiVoiceへ投げて音声認識を行う
async function postToAmivoice(filePath,apikey) {
return new Promise(async (resolve, reject) => {
try {
const amivoiceUri = 'https://acp-api.amivoice.com/v1/recognize?d=-a-general&c=8k&u=' + apikey;
const data = new FormData();
data.append('a',Fs.createReadStream(filePath));
const response = await Axios({
url: amivoiceUri,
method: 'POST',
headers: {
"Content-Type": data.getHeaders(),
},
data:data
})
console.log(response.data);
resolve(response.data);
} catch(error) {
reject(error)
}
})
}
AmiVoiceではリアルタイムでも音声認識できるよう、Websocketを用いた方法も提供されています。
TwilioのMedia Streamsで取得した音声ストリームをWebsocketを利用してAmiVoiceへ流すことで、リアルタイムに音声認識をおこなえます。
本記事ではMedia Streamsに設定するURLのソースコードの例をご紹介いたします。
※コードのAmiVoiceにデータを連携する部分をご紹介いたします。
Media Streamsとの連携の全コードはこちらをご参照ください。
~~中略~~
connect() {
if (!this.isReady) {
const client = new WebSocketClient();
client.on('connectFailed', error => {
console.log('Connect Error: ' + error.toString());
this.isReady = false;
});
client.on('connect', connection => {
this.connection = connection;
console.log('amivoice connected');
connection.on('message', message => {
if (message.type === 'utf8') {
const tag = message.utf8Data.charAt(0);
if (tag == 's') {
// 認識スタート
console.log('amiVoice started.');
this.isStarted = true;
} else if (tag === 'S') {
// サーバ内で発話区間の先頭が検出された S
} else if (tag === 'E') {
// サーバ内で発話区間の終端が検出された E
} else if (tag === 'C') {
// サーバ内で検出した発話区間に対する認識処理が開始された
} else if (tag === 'U') {
// サーバ内で検出した発話区間に対する認識処理中に、認識途中結果を知らせる
const data = JSON.parse(message.utf8Data.substring(2));
console.log('認識中 track:' + this.track + ' message:' + data.text);
} else if (tag === 'A') {
// 認識処理が完了し、認識結果が受容されたとき
const data = JSON.parse(message.utf8Data.substring(2));
console.log('確定 track:' + this.track + ' message:' + data.text);
this.emit('transcription', {track:this.track,body:data});
} else if (tag === 'G') {
// サーバ内で生成されたアクション情報 ※このイベントは無視する
//https://acp.amivoice.com/main/manual/g-%e3%82%a4%e3%83%99%e3%83%b3%e3%83%88%e3%83%91%e3%82%b1%e3%83%83%e3%83%88/
} else if (tag == 'e') {
this.isStarted = false;
console.log('amiVoice closed.');
}
}
});
connection.on('error', error => {
console.log("Connection Error: " + error.toString());
});
connection.on('close', () => {
this.isStarted = false;
this.isReady = false;
console.log('echo-protocol Connection Closed');
});
this.isReady = true;
this.start();
});
client.connect('wss://acp-api.amivoice.com/v1/');
}
}
~~中略~~
まとめ
本記事ではTwilioで音声を録音する方法と、録音した音声をAmiVoiceに連携して音声認識させる方法をご紹介させていただきました。
TwilioとAmiVoiceを活用することで、簡単に電話の通話内容をテキスト化できます。
通話音声を音声認識させたい!という方はぜひ、TwilioとAmiVoiceの利用をご検討ください。
前職でiOS、Androidのネイティブアプリケーション開発、AngularやLaravelを用いたウェブアプリケーション開発に従事。KDDIウェブコミュニケーションズではTwilioの最新情報の発信やTwilioを用いた地域課題解決を担当。 個人では、Google Developer Group Tokyoのオーガナイザーを務める。
Twitter:https://twitter.com/chiino58
2022.05.18
2022.04.18
2022.07.01
2022.08.23
2022.10.11
2022.05.24
2022.09.20
2022.11.02
2022.10.11
2022.09.20
2022.08.23