みなさまこんにちは。先進技術調査グループのキシダです。techブログは3度目の登場です。
今回は小ネタを投下してみたいと思います。
(前回の記事にも登場していますが)2020年のAutomotive Worldにてご紹介した通り、intdashがついに「音声データ」にも対応しました! 🎉
そして音声といえば、皆様ご存知でしょうか・・・?
そうです、AWSの「音声の文字起こし機能」で有名なAmazon Transcribeが、昨年末日本語対応したのです! 🎉
これは組み合わせてみるしかない・・・!
ということで、今回は以下のようなシナリオを目指し、文字起こし機能をintdashに組み込んでみました。
- iPhoneにむかっておしゃべりしてみる
- サーバー側で音声データをテキストに変換する
- 可視化ツールで音声が再生されるのと同時に文字に起こされていく様子を眺める
音声データとテキストデータ双方をintdashに通すことでデータの同期性が担保されるため、音声が再生されるのと同時にテキストに変換されていく様子を確認することができます。こうすることでAmazon Transcribeが音声のどの言葉を拾って変換してくれているのかが一目瞭然でわかる、というところがこのシナリオのGoodポイントです。
使用するサービスとワークフロー
今回のシナリオ自体は至って単純ですが、実は裏側で複数のサービスを使っています。
そのあたりを詳細に説明いたします。
Visual M2M Motion for iOS (以下 Motionとします)
iOS向けに開発された、スマートフォンのマイク・カメラ・センサー情報などからデータを収集してくれるアプリになります。今回はiPhoneから音声データを取得し、サーバーに送る箇所で使用します。Python SDK for intdash Analytics Services (以下 Python SDKとします)
収集したデータをintdash上で加工・解析するプロセスをはさみ、intdash上でやりとりされるデータの処理を実現するライブラリです。今回は、Amazon Transcribeとの連携で使用します。Amazon Transcribe
開発者が音声をテキストに変換する機能をアプリケーションに簡単に追加できるようにする、自動音声認識 (ASR、automatic speech recognition) サービスです。Visual M2M Data Visualizer (以下data-vizとします)
intdash上でやりとりされるデータを可視化するアプリケーションです。
今回は解析結果を確認する際に使用します。
弊社製品の詳細は、以下をご参照ください。
https://www.aptpod.co.jp/products/
上記を踏まえ、全体のワークフローは以下のようなイメージになります。
- iPhoneのMotionアプリから音声データをintdashにアップロード
- 音声ファイルをPython SDK経由でS3にアップロード
- Amazon Transcribeを用いてテキスト変換
- 変換後のテキストデータを時系列データに変換し、intdashにアップロード
- .data-vizで音声とテキストデータを表示
というイメージです。せっかくなので、準備手順も詳細にご紹介したいと思います。
※ 今回のソースコードは、Python SDKが一般公開されていない点と、今回のコードはそこまで需要がないだろうという独断から、要点のみ公開することにします。全部ほしい!という方がいらっしゃましたらぜひぜひ以下のお問い合わせ窓口へお願いいたします!
https://www.aptpod.co.jp/contact/
1.iPhoneのmotionアプリから音声データをintdashにアップロード
iPhoneに向かって以下を朗読します。 ポンコツ滑舌マンにとっては大変な苦行ですが、ここがこらえどころです。
(この記事のショボさをごまかすべく、最初はみんな大好きサンドウィッチマンのコント「ハンバーガー屋」をチョイスしたのですが、著作権侵害が怖くてやめました)
intdashは、100ミリ秒∼1ミリ秒間隔程度の高頻度で発生する時系列データを品質保証のないネットワークを経由して、 高速・大容量かつ安定的にストリーミングするための双方向データ伝送プラットフォームです。 intdashは、プラットフォームを構成する製品・サービスの総称を兼ねており、 INTeractive DAta Streaming Hub の頭文字を並べた略称です。
こちらから引用:https://www.aptpod.co.jp/products/intdash/
2.音声ファイルをPython SDK経由でS3にアップロード
大きな壁を乗り越えた後は、Python SDKを使用してiPhoneからアップロードされた音声データを取得します。
※ Python SDK自体はまだ一般公開されていませんが、一部コードを貼り付けておきます。
### Python SDKを使用して時系列データを取得 it = lc.units().list( start=XXX # iPhoneで計測を開始した時間 end=XXX, # iPhoneで計測を終了した時間 meas_uuid=m.uuid, # 1つ計測に紐づくuuid ) ### 取得した時系列データをファイル化 file = io.BytesIO() for us in it : pcm_list = [u for u in us if u.data.data_type.value == lowlevel.core.DataType.pcm.value] for u in pcm_list: file.write(u.data.data) with wave.Wave_write("20191220_1_test.wav") as w: w.setnchannels(pcm_list[0].data.channels) w.setsampwidth(pcm_list[0].data.bitpersample // 8) w.setframerate(pcm_list[0].data.samplerate) w.writeframes(file.getvalue()) w.close()
3.Amazon Transcribeを用いてテキスト変換
ファイル化したデータをS3にアップロードします。
アップロードしたファイルを参照し、Amazon Transcribeのジョブを作成します。
session = boto3.Session(profile_name='****', region_name='ap-northeast-1') transcribe = session.client('transcribe') job_name = "audio_test_20200219_2" job_uri = "https://s3-ap-northeast-1.amazonaws.com/transcribe-20191219/audio/20200219_2.wav" transcribe.start_transcription_job( TranscriptionJobName=job_name, Media={'MediaFileUri': job_uri}, MediaFormat='wav', LanguageCode='ja-JP' )
上記を実行すると以下のようなファイルがjson形式で出力され、S3に保存されます。
{ "jobName": "audio_test_20200219_2", "accountId": "263480619405", "results": { "transcripts": [ { "transcript": "インド ダッシュ は 百 ミリ 秒 から 数 ミリ 秒間 程度 の (以下略)" } ], "items": [ { "start_time": "1.44", "end_time": "1.79", "alternatives": [{ "confidence": "0.2469", "content": "インド" }], "type": "pronunciation" }, ======= 省略 ======== ] }, "status": "COMPLETED" }
ファイルに対して翻訳した全文と、各単語ごとの変換結果が出力されています。
items
の内容を参照すると、変換されたテキストが全体のファイルのうち、どのタイミングで発言されたかが把握できるようになっています。この情報を元に、テキストデータを時系列データに変換していきます。
4.変換後のデータを時系列データに変換し、intdashにアップロード
上記の各itemごとの start_time
と end_time
を用いて時系列順にテキストデータを並び替え、intdashにアップロードしてみます。
for text in text_list: content = '' for con in text['alternatives']: content += con['content'] if 'start_time' not in text or 'end_time' not in text : text['start_time'] = before_start_time text['end_time'] = before_end_time ## 特定の時間があいたら文章をリセットする if before_end_time != None and float(text['start_time']) - before_end_time > 1: text_joined = '' text_joined = text_joined + content before_end_time = float(text['end_time']) before_start_time = float(text['start_time']) ## 時系列のデータ形式でアップロードする(Python SDKを使用) units.append( lowlevel.core.Unit( elapsed_time = pd.Timedelta(str(text['end_time']) + 's'), channel = 1, data = protocol.data.String(label='text', value=text_joined) ) )
5.data-vizでテキスト表示してみる
変換したテキストデータをintdash上にアップロードすることに成功したので、もう一度朗読内容を振り返りつつ、data-vizで確認してみます。
intdashは、100ミリ秒∼1ミリ秒間隔程度の高頻度で発生する時系列データを品質保証のないネットワークを経由して、 高速・大容量かつ安定的にストリーミングするための双方向データ伝送プラットフォームです。 intdashは、プラットフォームを構成する製品・サービスの総称を兼ねており、 INTeractive DAta Streaming Hub の頭文字を並べた略称です。
さすがAmazon Transcribe、いい感じに音を拾って変換出来ている様子が伺えますね 👌
今回は音声以外にも、音声データを分析する際に用いられる音の波形情報と、スペクトログラムも同時に表示しています。1つのデータを数種類の可視データに加工し、1つの時系列で同時に確認できる点は、弊社製品の大きなアピールポイントとなります。
まとめ
今回は音声機能をテーマに、intdashとAmazon Transcribeで簡単に同時文字起こし機能が作れました。内容的には非常にあっさりしていましたが、より文字起こしの変換機能の強化を目指し、案件での使用をめざす予定です。今後も引き続き音声データ をテーマに解析手法を検討してまいります!