Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
25
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

Organization

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

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

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:

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
25
Help us understand the problem. What are the problem?