Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

by ovrmrw
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

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:

ovrmrw
ちきさんです。ただのWebエンジニアです。
http://overmorrow.hatenablog.com/
opt
"INNOVATION AGENCY" を標榜するインターネット広告代理店。エンジニア組織 "Opt Techonologies" を中心にアドテクetc...に取り組んでいます。
https://opt-technologies.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした