WebAudioAPI
Watson

Watsonで入門するリアルタイム音声認識

More than 1 year has passed since last update.

When

2017/03/28

At

WebAudio.tokyo #4



自己紹介

ちきさん

(Tomohiro Noguchi)

Twitter/GitHub/Qiita: @ovrmrw

ただのSIer。

Angular Japan User Group (ng-japan)スタッフ。

3a2512bb-aa72-4515-af42-1f1721252f39.jpg


今回のGitHubリポジトリ

フロントエンド: ovrmrw/webaudio-meetup-react-example

バックエンド: ovrmrw/cognitive-server-starter



あるとき僕は、リアルタイム音声認識をやりたいと思い立った。



何から始めればいいんだろう?



リアルタイムに音声入力したいと思ったら把握しなければいけないこと。



つらい :innocent:



探したらお手軽っぽいの見つかった。



Watson Speech to Text

https://speech-to-text-demo.mybluemix.net/

Speech-to-Text APIのデモサイト。

マイクがあれば音声認識を実際に試すことができる。



watson-developer-cloud/speech-to-text-nodejs

https://github.com/watson-developer-cloud/speech-to-text-nodejs

前ページのデモサイトをgit cloneして動かせるGitHubリポジトリ。

サンプルコードが以前はjQueryベースだったが、今はReactベースになって多少読みやすくなった。



Watsonデモサイトで使われているお手軽ライブラリ



WebAudio APIを直接叩かずにリアルタイム音声入力できる。しかもWatsonで音声認識できる。 :raised_hands:


(connpassより)


イベント概要

WebAudio.tokyoはWeb Audio APIのための勉強会です。


_人人人人人人人人人人人人人人人人人人人_

> Web Audio APIのための勉強会です。 <

 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄



Reactでミニマムなサンプルコードを書いてみよう


(デモ)



必要なライブラリをimport


src/Mic.tsx

import * as recognizeMicrophone from 'watson-speech/speech-to-text/recognize-microphone'


(TypeScriptの場合)



Watsonを使うためのTokenを取得するメソッド


src/Mic.tsx

  getTokenAsync() {

return fetch('http://localhost:4000/api/watson/speech-to-text/token')
.then(res => res.json())
.then(data => data.token)
}

(Tokenを取得するためのバックエンドサーバーが localhost:4000 で稼働している)



AudioContextをオン/オフするためのメソッド

RECボタン/STOPボタンがクリックされたときに呼ばれる。


src/Mic.tsx

  toggleMicrophoneState() {

if (this.recognizeStream) {
this.stopRecognizeStream()

} else if (!this.isRecording) {
this.isRecording = true

this.getTokenAsync()
.then(token => {
this.setState({ transcripts: [] })
this.startRecognizeStream(token)
})
}
}




RecognizeStreamを開始するメソッド

Watsonサーバーから返ってくる認識後のデータは stream.on('data', .....) で受け取る。


src/Mic.tsx

  startRecognizeStream(token) {

const stream = recognizeMicrophone({
token,
model: 'ja-JP_BroadbandModel',
objectMode: true,
extractResults: true,
})

stream.on('data', data => {
if (data.final) {
const transcript = data.alternatives[0].transcript
this.setState({ transcripts: [...this.state.transcripts, transcript] })
}
})

this.recognizeStream = stream
}




RecognizeStreamを終了するメソッド

streamstop(), removeAllListeners() を呼ぶのはお作法みたいなもの。


src/Mic.tsx

  stopRecognizeStream() {

if (this.recognizeStream) {
this.recognizeStream.stop()
this.recognizeStream.removeAllListeners()
}

this.isRecording = false
this.recognizeStream = null
}




src/Mic.tsx の全コード


src/Mic.tsx

import * as React from 'react'

import * as recognizeMicrophone from 'watson-speech/speech-to-text/recognize-microphone'

export class Mic extends React.PureComponent {
private isRecording = false
private recognizeStream = null

constructor(props) {
super(props)
this.state = { transcripts: [] }
}

getTokenAsync() {
return fetch('http://localhost:4000/api/watson/speech-to-text/token')
.then(res => res.json() as any)
.then(data => data.token)
}

async toggleMicrophoneState() {
if (this.recognizeStream) {
this.stopRecognizeStream()
} else if (!this.isRecording) {
this.isRecording = true
await this.getTokenAsync()
.then(token => {
this.setState({ transcripts: [] })
this.startRecognizeStream(token)
})
}
}

startRecognizeStream(token) {
const stream = recognizeMicrophone({
token,
model: 'ja-JP_BroadbandModel',
objectMode: true,
extractResults: true,
})
stream.on('data', data => {
if (data.final) {
const transcript = data.alternatives[0].transcript
this.setState({ transcripts: [...this.state.transcripts, transcript] })
}
})
this.recognizeStream = stream
}

stopRecognizeStream() {
if (this.recognizeStream) {
this.recognizeStream.stop()
this.recognizeStream.removeAllListeners()
}
this.isRecording = false
this.recognizeStream = null
}

render() {
const buttonName = !this.recognizeStream ? 'REC' : 'STOP'
return (
<div>
<div>Mic Component</div>
<button onClick={() => this.toggleMicrophoneState().then(() => this.forceUpdate())}>
{buttonName}
</button>
<div>{this.state.transcripts.join(', ')}</div>
</div>
)
}
}




たったこれだけでWatsonのリアルタイム音声認識を使いこなせる! :cool:



最初はお手軽に動かして、少しずつソースコードを読んで理解を深めよう :runner_tone1:



Thanks :raised_hands: