プログラムから音声APIを使う

1. 音声APIの概要

サンドボックスサーバーで提供している3種類のAPIでは、以下の接続方法をサポートしています。

  • 音声認識API:WebSocket、HTTPS
  • 機械翻訳API:HTTPS
  • 音声合成API:HTTPS

下表では、各種APIのエンドポイントと参照ドキュメント(エンドポイント以外のパラメータ参照用)のリンクを掲載します。次項に記載のエンドポイントはサンドボックスサーバー用のものとなっておりますので、リンク先のドキュメントを参照される際にはエンドポイントをサンドボックスサーバー用のものに置き換えてご利用ください。

API種別エンドポイント参照ドキュメント
音声認識APIhttps://sandbox-sr.mimi.fd.ai/
wss://sandbox-sr.mimi.fd.ai/
バッチ送信はHTTP Service
ストリーミング送信はWebSocket Serviceを参照ください。
リンク先では、3種類のサービスの記載がありますが、サンドボックスサーバーで利用可能なサービスは nict-asr のみとなりますのでご注意ください。
機械翻訳APIhttps://sandbox-mt.mimi.fd.ai/machine_translationmimi 機械翻訳サービスのAPI仕様を参照ください。
音声合成APIhttps://sandbox-ss.mimi.fd.ai/speech_synthesismimi 音声合成サービスのAPI仕様を参照ください。

以降では、Pythonのサンプルプログラムを例に、各APIを利用する方法について記載します。

2. 音声認識を行う

音声認識については、録音した音声データを一度のHTTPリクエスト・レスポンスでやりとりする「バッチ送信」モードと、録音したデータを逐次送信する「ストリーミング送信」モードの2種類があります。

「ストリーミング送信モード」では、HTTPの代わりにWebSocketプロトコルを使用します。弊社が提供するライブラリを使う方法もありますが、WebSocketプロトコルを扱えるものであれば、多くのWebSocketライブラリを使えます。

Pythonの例では、websockets というライブラリを利用します。

また、音声認識に使用できる音声データの形式は、「16bit int(リトルエンディアン)・1channel」のraw形式のみ(サンプリングレートは任意で設定できますがヘッダで指定する必要あり)ですので利用する際はデータ形式にもご注意ください。

2−1. ストリーミング送信

ストリーミング送信モードは、取得した音声データの断片を逐次サーバに送信し認識処理を並行して行う送信方法のことで、例えば録音開始から話し中に少しずつ音声データを送信することで、話し終わってから短時間で認識結果を取得できます。

サンプルプログラムでは、読み込み済みの音声ファイルのデータを分割して送信していますが、マイクからの音声取得した断片を代わりに送信することで話しながらデータを送信することができます。音声認識の単位とするひとまとまりの音声データを送信し終えたら、{"command" : "recog-break"} というテキストデータを送信することでサーバーは音声の終了を検知し、音声認識の最終結果を返却します。

音声データの形式は、Content-Type ヘッダで指定する必要があります。以下のサンプルコードの例では、サンプリングレートは16kHz(16000Hz)の例となっています。たとえば48kHzの場合は、rate=16000 となっている箇所を rate=48000 と書き換えてください。

async def recognize(token, file_data):
    headers = {
        "Authorization": "Bearer {}".format(token),
        "x-mimi-process": "nict-asr",  # when using NICT engine use "nict-asr"
        "x-mimi-input-language": "ja",
        "Content-Type": "audio/x-pcm;bit=16;rate=16000;channels=1",
    }

    try:
        resp = ""
        async with websockets.connect(
                SR_SERVER_URI,
                extra_headers=headers
        ) as ws:

            file_size = len(file_data)
            sent_size = 0
            while sent_size < file_size:
                await ws.send(file_data[sent_size:sent_size + SAMPLES_PER_CHUNK * 2])
                sent_size += SAMPLES_PER_CHUNK * 2
            await ws.send(json.dumps({"command": "recog-break"}))
            while True:
                resp = await ws.recv()
                if json.loads(resp)['status'] == 'recog-finished':
                    print('recog-finished: received all from server.')
                    break

    except websockets.exceptions.ConnectionClosed:
        print('connection closed from server')

    return resp

2−2. バッチ送信

バッチ送信は、音声データをひとかたまりで送信してから音声認識結果を取得する方法です。ストリーミング送信に比べて音声認識結果を得るまでに時間がかかりますが、プログラムは簡単に実装できるというメリットがあります。

Pythonでは、requests というライブラリを使用するのが便利です。

def recognize(token, file_data):
    headers = {
        "Authorization": "Bearer {}".format(token),
        "x-mimi-process": "nict-asr",  # when using NICT engine use "nict-asr"
        "x-mimi-input-language": "ja",
        "Content-Type": "audio/x-pcm;bit=16;rate=16000;channels=1",
    }

    url = SR_SERVER_URI_HTTP
    resp = requests.post(url, headers=headers, data=file_data)
    return (resp.json(), resp.status_code)

3. 機械翻訳を行う

機械翻訳の場合は、入力の文字列と翻訳前後の言語の指定をPOSTリクエストのパラメータに指定します。指定可能な言語と指定の仕方はAPI仕様を参照してください。

def translate(token, input_lang, text, output_lang):
    headers = {
        'Authorization': 'Bearer {}'.format(token),
    }
    data = {
        'text': text,
        'source_lang': input_lang,
        'target_lang': output_lang,
    }

    url = MT_SERVER_URI
    resp = requests.post(url, headers=headers, data=data)
    return (resp.json(), resp.status_code)

4. 音声合成を行う

音声合成も、機械翻訳の場合と大差ありません。出力結果は音声データ(バイナリ)なので、保存するか再生する処理を実装しましょう。以下の例では、指定されたファイル名(filenameパラメータ)で、音声ファイルを保存します。

出力ファイルの形式は、16kHz・16bit int(リトルエンディアン)・1channel のwav形式となります。

def synthesize(token, input_lang, text, filename):
    headers = {
        'Authorization': 'Bearer {}'.format(token),
    }
    data = {
        'text': text,
        'lang': input_lang,
        'engine': 'nict',
    }

    url = SS_SERVER_URI
    resp = requests.post(url, headers=headers, data=data)
    if resp.status_code == 200:
        with open(filename, 'wb') as fout:
            fout.write(resp.content)

        return '', 200
    else:
        return resp.json(), resp.status_code