TwilioとGoogle Cloud Speech APIで電話の内容を文章に変換する

twilio
338件のシェア(そこそこ話題の記事)

Google Cloud Speech API (以下Speech API) を利用すると、人間が発声した音声をAPIを通してテキストに変換することができます。

Speech APIは日本語にも対応しているため、国内でも電話で話した内容を自動的にテキストに変換するといったようなことが出来るようになります。

ということで、Twilio, Zappa, Speech APIを組み合わせて、サーバレスに電話の内容を文章化する仕組みをつくってみました。

構成

以下が今回作成した仕組みの構成図になります。

voice-recording-structure

Twilioを用いて電話から音声を録音する方法については、こちらの記事を参考にしてください。

上記の記事に加えて、Twilioから録音された音声ファイルのURLをSNSを通して別のLambda Functionに投げ、そこから音声ファイルの取得とSpeech APIへの問い合わせを行っています。最終的に変換されたテキストはchatworkへ投稿されます。

LambdaからSpeech APIへの問い合わせ

Speech APIを利用する場合、GCPへの認証をLambdaを通して行う必要があります。今回はADC(Google Application Default Credentials)と呼ばれる認証ファイルをlambdaのパッケージに含め、その認証情報をもとにSpeech APIへの問い合わせを行いました。

ADCのパスをLambdaの環境変数GOOGLE_APPLICATION_CREDENTIALSに設定することでgoogle-api-python-clientから問い合わせを行うことが出来るようになります。

Speech APIへの問い合わせの具体的な実装は以下のようになります。Speech APIのサンプルコードをベースに作成しています。

# coding=utf-8
import base64
import requests

from googleapiclient import discovery
import httplib2
from oauth2client.client import GoogleCredentials

DISCOVERY_URL = ('https://{api}.googleapis.com/$discovery/rest?'
                 'version={apiVersion}')

def invoke(events):
    for event in events['Records']:

        # SNSから録音ファイルのURLを取得
        recording_url = event['Sns']['Message']

        # 録音ファイルを取得
        r = requests.get(recording_url)

        # Speech APIに問い合わせ
        resp = __recognize_speech(r.content)

        # 問い合わせ結果のテキストを取得
        text = resp['results'][0]['alternatives'][0]['transcript']

        # 結果をchatworkに投稿
        __post_to_chatwork(text)

def __recognize_speech(content):

    # 音声ファイルをBASE64エンコーディング
    content_base64 = base64.b64encode(content)

    # Speech APIに問い合わせ
    service = __get_speech_service()
    service_request = service.speech().syncrecognize(
        body={
            'config': {
                'encoding': 'LINEAR16',
                'sampleRate': 8000,
                'languageCode': 'ja-JP',
            },
            'audio': {
                'content': content_base64.decode('UTF-8')
                }
            })
    response = service_request.execute()

    return response

def __get_speech_service():
    credentials = GoogleCredentials.get_application_default().create_scoped(
        ['https://www.googleapis.com/auth/cloud-platform'])
    http = httplib2.Http()
    credentials.authorize(http)

    return discovery.build(
        'speech', 'v1beta1', http=http, discoveryServiceUrl=DISCOVERY_URL)

def __post_to_chatwork(text):
    ...(snip)...

SNSから録音ファイルのURLを受け取った後、音声ファイルをダウンロードし、BASE64エンコーディングしています。その後、エンコードしたデータを元にSpeech APIに問い合わせを行い、結果をChatworkに投稿しています。

Twilioで録音されたファイルをSpeech APIの分析にかける場合、以下の設定で問い合わせを行う必要があります(WAVファイルの場合です)。

項目名
encoding LINEAR16
sampleRate 8000
languageCode ja-JP

音声ファイルについてのサンプルレートなどの情報は、VLCなどのメディアプレイヤーから取得することができました。

試してみた

実際に以下の音声を録音してみて、どのように結果が出てくるかを試してみました。

結果はこちらです。

voice-recording-sample01

voice-recording-sample02

問題なく変換できていますが、文章の句読点までは考慮してくれないようです。
読みやすい文章にするためには形態素解析などの仕組みを噛ませる必要があるかもしれません。

まとめ

Serverlessな構成で電話内容の録音・テキスト変換ができました。

Voice2Text用のAPIがあれば、簡単にこのような仕組みを作ることが出来るようになります。素晴らしい時代になりました。
AlexaのVoice2Text機能もそのうち公開されるんじゃないかなと首を長くして待っています。

参考