LoginSignup
23
25

More than 5 years have passed since last update.

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

Posted at
1 / 25

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

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

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


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:

23
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
25