FC2ブログ

スマフォのアプリを作りたい(13):音声認識させたい

   プログラミング [2020/02/14]
「スマフォのアプリを作りたい」も13回目になりました。
これまでのこのタイトルの記事の流れは、こんなんなってます。
Start
 →スマフォのアプリを作りたい
  →開発環境をVisualStudioで・・・挫折
  →開発環境をReact Nativeで
   →環境構築続き(失敗)リトライ
   →デバッガの動かし方
  →React Nativeのソースの書き方
   →ReactのJavaScriptの概要
   →React Nativeのテンプレートを読む
  →簡単なチャットアプリを作る
   →サンプル味見ちょと修正
   →音声入力とエミュレータ操作
   →サーバ側動作環境の準備
   →アプリとサーバでチャット
  →音声認識をやってみる
←今回はココ

音声認識をやってみたいなーなんて思ってます。
かと言って、音声認識エンジンを作るとかいうことではなく、アプリから利用できればいいんです。
しかも、ソフトキーボードのマイクアイコンとかではなく、アプリから直接的に開始-終了とか制御できるようにしたい。

以前、エミュレータ(AVD)既設の機能を試したときには、音声の入力すら確認できなかったので、いまのさる環境で作って/試せるかは、かなり不安があります。


◆Google Chromeの音声認識
さるの今のレベル(ど素人)からすると、かなりハードルが高そうなことをやろうとしていると自覚しているので、気分を高めるために、以下のサンプルをご紹介します。

Chrome上でしか機能しないと思いますが、Googleさんの音声認識が簡単に使えちゃうHTML(JavaScript)です。
ほぼ、どっか(だいぶ前に作ってあったのでどこだったか忘れちゃいました。ごめんなさい。)のパクリをイジイジしたものです。

----HTML:-----------------------------------------
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>音声合成・認識アプリ</title>
</head>
<body>
<input id="txt1" type="text" value="おめのガバン、おぼでぐねが?">
<input id="btn1" type="button" value="話す">
<script>
var btn1 = document.getElementById("btn1"); //ボタンの取得
btn1.addEventListener("click", function() { //ボタンがクリックされたら
var synth = new SpeechSynthesisUtterance(); //設定を入れるオブジェクト
var txt1 = document.getElementById("txt1"); //テキストボックスを取得
synth.text = txt1.value; //話す内容
synth.lang = "ja-JP"; //言語
synth.rate = 1.0; //速さ
synth.pitch = 1.0; //高さ
synth.volume = 1.0; //音量
window.speechSynthesis.speak(synth); //話す
});
</script>
<br>
<br>
<input id="btn2" type="button" value="認識開始">
<div id="txt2">開始待ち</div>
<br>
<div id="txt3">ここに音声認識結果を表示</div>
<script>
var recog = new webkitSpeechRecognition(); // 音声認識オブジェクト
var fstart = false;
var btn2 = document.getElementById("btn2");
var txt2 = document.getElementById("txt2");
var txt3 = document.getElementById("txt3");
// ボタンを押した時の処理
btn2.addEventListener("click", function() {
fstart = !fstart;
if(fstart) {
txt3.innerHTML = "";
btn2.value = "認識停止";
recog.lang = "ja-JP"; // 認識する言語の設定
recog.start(); // 音声認識をスタート
}
//alert("sutate:"+fstart);
});
// 認識開始した時
recog.addEventListener("soundstart", function() {
txt2.innerHTML = "認識中...";
});
// 認識終了した時
recog.addEventListener("end", function() {
if(fstart) {
recog.lang = "ja-JP"; // 認識する言語の設定
recog.start(); // 音声認識をリスタート
}
else {
btn2.value = "認識開始";
txt2.innerHTML = "開始待ち";
}
});
// 認識が成功した時
recog.addEventListener("result", function(ret) {
txt3.innerHTML += "<br>" + ret.results[0][0].transcript;
});
// 認識に失敗した時
recog.addEventListener("nomatch", function() {
txt2.innerHTML = "認識できませんでした";
});
</script>
</body>
</html>
---------------------------------------------------


ためしに、以下に置いてみました。よかったら試してみてください。
http://sarumosunaru.starfree.jp/voicebychrome2.html
[認識開始]ボタンを押してからマイクに向かって何か話せば、話した内容がテキスト化されて表示されます。

マイクの感度がよくて、発音がしっかりしていれば(訛ってなければ)かなり認識してくれます。
すげーと思います。
ただし、PC版のChromeでしか動かないみたいです。スマフォ(iPhone)のChromeでは反応しませんでした。
当然、Androidエミュレータ上の「ブラウザ」でも動きませんでした。

マイクが有効かどうかは、以下の手順で確認できます。(Windows10)
-タスクバー上の入力欄に「サウンドの設定」と入力して、リスト表示される一番上の「サウンドの設定」を選択します。
-右側の内容をスクロールして、「サウンドコントロールパネル」をクリックします。
-[サウンド]ダイアログが表示されるので、[録音]タブを選択します。
-使用可能な(チェックマーク付き)マイクが存在するかを確認してください。
-あれば、そのマイクの右側のインジケータが、音に反応して動くかを確認してください。
有効なマイクが無い、あるいはインジケータが動かないなどの場合は・・・
色々と原因があることなので、ご自分でなんとかしてください。

キーボード入力が苦手なのに、何か「文章をパソコンに入力しないといけない」なんて言う方は、先のページを使って、
-文章にしたい内容を話して→テキストに変換する
-画面に表示されたテキストをコピペしてどっかにコピーする
って使えば、結構な効率アップになるかもよ。


では、そろそろ本題についての調べて/試す独り言を続けます。


◆音声認識のフレームワークない?
React Nativeで音声認識した事例をぐぐってみました。
なんか、バッチリなタイトルの事例を見つけました。react-native-voiceを使うとあります。
参考:https://dev-yakuza.github.io/react-native/react-native-voice/

できれば、録音しながらテキスト変換したいと思ってます。

なのでもちょっとそんな事例も検索してみたが、そんな簡単には見つからないみたいです。
録音だけなら、react-native-audioとかを使っているようです。
参考:https://blog.leko.jp/post/rn-audio-record/
「他にもあるが」と言っている点が気になります。

まずは、音声認識させるところから先行させます。
react-native-voiceについて本家?のサイトを見てみてみます。
参考:https://github.com/react-native-community/react-native-voice

この手のサイトでいつも思うのですが、そもそも何ができるライブラリなのかの概要説明がない。
どんな動きをするのかもサンプルコードのみなので、どう判断していいか分からない。
なので、先に「参考」とさせてもらったようなサイトの説明で、「ああ、こんなことができるのね。」を把握するしかないのが、とっても不満です。本来どこを見に行くべきなのか知ってる方いたら教えてください。

唯一、上記サイトの説明で気になる記述を見つけました。
Voice.isAvailable()というメソッドの説明で、「そのシステム上で音声認識が利用可能かチェックする」とあります。つまり、このライブラリは、音声認識機能を提供するのではなく、システムが準備したものを簡単に利用できるようにするためのインタフェースということなんではないかと。

認識エンジンは、ローカルなのか、クラウド利用なのかも、「システム側」次第ということですね。
となると、さるがやりたいこととはちょっと違う。さる的には認識エンジン(サービス)はどこを使うか選びたい。

となると、「システム」と呼んでいるOS側の機能として組み込める部分を作らないといけないということなんでしょうか。
またまた、グっとハードルが高くなる感じです。

冒頭に「お試し」として挙げたChrome前提のサービスは無償ですが、Chromeの仕向け/バージョンで使える/使えないが変わります。
Googleが提供している「Cloud Speech-to-Text」は有償ですが、きっと認識能力としては、Chromeが使っているエンジンと同等以上と予想します。

なぜ、Googleにこだわるか・・・料金と認識精度についての比較サイトを以下に。
料金:https://qiita.com/trickre/items/f07bc5fcb020757b2b13 (2017)
認識精度:https://www.slideshare.net/takuino/ss-154097358 (2018)
料金はMS、精度はGoogle・・・なのかな。精度優先でお試ししてみたいと思ってます。

そこで、「Cloud Speech-to-Text」の「クイックスタート」ページを参照してみました。
参考:https://cloud.google.com/speech-to-text/docs/quickstart-client-libraries?hl=ja
Node.jsのサンプルが載ってました。
これって、React Nativeから使えるんでしょうか。

「待てよ」と思って改めて、「Speech to Text React Native」で検索したら、引っ掛かりました。
参考:https://github.com/hayanmind/react-native-google-speech-api
なんだ、Speech_to_Textを使うフレームワークも準備されてるんですね。
じゃ、まずはこれを使ってみるということで。

とすると、あと準備として必要なのは、
1)Googleのクラウドサービスにユーザ登録します。
2)エミュレータ上で音声を入力できないことには動作確認できないのでそれも。


◆Googleクラウドサービスにユーザ登録
入口:https://cloud.google.com/?hl=ja
Googleのアカウントでログインしてないか、あるいはクラウドサービスの利用登録してなければ、上記のサイトのあちこちに[無料で始める][無料で開始][無料トライアル]などのボタンがちりばめられてます。
無料トライアルへの申し込みができます。12カ月か$300分の無償利用が可能だそうです。
期間かクレジットを使い切ったら、通常利用(有償)に切り替えることもできるし、利用を終了してもよさそうです。
そのボタンを押すと、申し込み画面が出ます。案内に従って手続きします。
最初の画面で正規の利用規約、無料トライアルの規約を読めとリンクされてるので読みます。
国を指定して次の画面で、住所/氏名/クレジットカード番号を入力するだけでした。クレジットカードの番号を入力するときはちょっと躊躇しましたが、それ以外は意外とあっさり。
さるはGoogleのアカウントを持っていてログインした状態だったので、たぶん通常はアカウント登録/ログインの手順が省略されていたかもしれません。

終るとこんな画面が出ました。
20200214_1.jpg

実際にクラウドAPIを使うときのキーのようなもの?が必要な気がしますが・・・まずは放置しておきます。


◆Androidエミュレータ上でのマイク入力
以前ちょっとだけ試したときはどうにもならなかったけど、もう一回調べます。
でも・・・
「できない」と言っているところが多い。かつ「できるようにする」にはかなり面倒なことをしたという記事も。
「できる」って言っているところが若干ある。できない派の記事は、日付が古め。

どっちなんだー!

もう一回以前やってみたエミュレータの設定変更をやってみた。

<設定方法>
-エミュレータを起動する
-エミュレータの横に付いているアイコンのリストの一番下「…」をタップする
-「Extend Control」ウィンドウが表示される
-左側のメニューから「Microphone」を選択する
-以下設定メニューをすべてEnble状態(●を右側)にする
 ・Virtual headset plug inserted
 ・Virtual headset has microphone
 ・Virtual microphne use host audio input
-[VOICE ASSIST]ボタンをタップする
・・・一回だけしゃべった! なんか前回と動きが違うような。

<確認方法>
-エミュレータ上のホームボタン(お家マーク)をタップ
-画面上部のGoogleと書かれた右側のマイクアイコンをタップ
-「ピロン」と音が出たら、「サルモスナル」とか言ってみる
-Googleで「さるもすなる」が検索される
・・・あれ?動いちゃった!

これで、Androidエミュレータ(Android[6.0] Virtual Device on Windows10)に音声入力の能力があることは確認できました。
作り込みに移りたいと思います。


◆react-native-google-speech-apiのインストール
GitHubのサイトに書いてある手順でインストール/セットアップを実施してみます。
参考:https://github.com/KWRI/react-native-google-speech-api
参考:https://github.com/hayanmind/react-native-google-speech-api
※2か所で公開しています。手動で各ファイルに付け足す記述とかが微妙に異なっていました。
 なんとなくですが「KWRI」側を参考にしました。


1)パッケージのインストール
インストールは、いつもの通りコマンドプロンプトからプロジェクト・フォルダにカレントを移動して、「npm install react-native-google-speech-api --save」を実行しましたが、エラーになりました。

----コマンドプロンプト----------------------------
C:\WINDOWS\system32>cd /d d:\appmake\proj\vtchat

d:\AppMake\proj\VTChat>npm install react-native-google-speech-api --save
npm ERR! code ENOVERSIONS
npm ERR! No valid versions available for react-native-google-speech-api
:
---------------------------------------------------

別のパッケージで同様のエラーの場合は、npmのバージョンが古いのかも とありました。
なので、「npm install -g npm」を実行してみます。
npmのバージョンが、6.12.1から6.13.7に更新されました。
でも、「npm install react-native-google-speech-api --save」の結果は同じでした。

「npm show react-native-google-speech-api version」とやってみました。
----コマンドプロンプト----------------------------
d:\AppMake\proj\VTChat>npm show react-native-google-speech-api version
npm ERR! code E404
npm ERR! 404 Unpublished by szymon.nitecki on 2019-07-17T07:48:37.040Z
npm ERR! 404
npm ERR! 404 'react-native-google-speech-api' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\sarumosunaru\AppData\Roaming\npm-cache\_logs\2020-02-10T01_29_44_845Z-debug.log
---------------------------------------------------

「Unpublished」とあります。ログファイルを見てみると、
「https://registry.npmjs.org/react-native-google-speech-api」というファイルを引っ張って来ているみたいだったので、ブラウザで見てみました。中身は理解できませんが、「unpublished」という単語も含まれます。

解せませんねー。
HPでは非公開っぽいことは何も書いてないのに・・・
サードパーティっていう言い方が正しいかはわかりませんが、KERI、HayanMindとかが公開元?になってるから?


※同じ問題にぶち当たった方がいたらしく、Issueにも未解決で載ってました。
https://github.com/KWRI/react-native-google-speech-api/issues/4

でも回答/アドバイスのようなものは載ってない。1/12に書き込まれたようで、日も浅いから?

類似のエラーの対処方法を半日検索しまくって、解決の糸口すら掴めませんでした。
さるの理解能力と知識が圧倒的に不足です。


Cloneのダウンロードはできるみたいです。ライセンスは追加MIT?とある。
打つ手が見つからず、しょうがないのでCloneのダウンロードをしてみました。
解凍結果を丸っと、「(プロジェクトフォルダ)\node-modules\」に移動します。
フォルダ名に「-master」と付いてるので、それは外しました。
後日追記:↑の解凍してコピーなどという手順は全く正しくありません。マネしないでね。
次回の書き込み時には解決してるかもしれないので、そっちを見てください。


2)手動インストール?
ダウンロード元のサイトには、npmでインストールする前後にやる内容なのかよくわかりませんが、手動インストールと書かれた手順が載ってたのでやってみました。Android向けは、「after」手順も書いてあります。
でも、チャントした説明もないし、「npm」でのインストールをやってないので、前も後「after」もいっしょくたです。

「(プロジェクトフォルダ)\android\app\src\main\java\com\(プロジェクト名)\MainApplication.java」に以下の行追加を行います。
----MainApplication.java--------------------------

import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import com.reactlibrary.GoogleSpeechApiPackage; //for google-speech-api
import java.lang.reflect.InvocationTargetException;
import java.util.List;

---------------------------------------------------

「(プロジェクトフォルダ)\android\settings.gradle」に以下の行追加を行います。
----settings.gradle--------------------------------
rootProject.name = 'VTChat'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
include ':react-native-google-speech-api'
project(':react-native-google-speech-api').projectDir=new File(rootProject.projectDir, '../node_modules/react-native-google-speech-api/android')

---------------------------------------------------

「(プロジェクトフォルダ)\android\app\build.gradle」に以下の行追加を行います。
※同名のファイルが・・・\androidにもあるので、フォルダを間違えないように注意。
----build.gradle-----------------------------------

android {

defaultConfig {
applicationId "com.vtchat"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
multiDexEnabled true //for google-speech-api
}


dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+" // From node_modules
implementation project(':react-native-google-speech-api') //for google-speech-api
implementation 'androidx.multidex:multidex:2.0.1' //for google-speech-api

if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";

---------------------------------------------------

「(プロジェクトフォルダ)\android\app\src\main\AndroidManifest.xml」に以下の行追加を行います。
----AndroidManifest.xml----------------------------
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vtchat">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"

---------------------------------------------------



◆react-native-google-speechのインストール(やらない方がいい)
「-api」と付いてないフレームワークもありました。
参考:https://www.npmjs.com/package/react-native-google-speech
でも、「Works ONLY in Android.」と書いてあります。
それだと・・・後で困るので、あくまでも予備のつもりでインストールします。

インストールは、案内の通り「npm install react-native-google-speech --save」とやったら、メッセージ的には問題なさそうに終わった。
次に「react-native link」とやりました。でも、何もメッセージは出ませんでした。
エラーじゃないからいっか?

・・・これをやったがために、この後大変なことになりました。結局、uninstallすることになったので、ここもマネしないでください。


◆味見コードの作成
新しくプロジェクトを起こすのは大変なので、先のチャットを味見した環境にreact-native-google-speech-apiのサンプルコードをマージして、動きを見たいと思います。
1)App.jsの修正
----App.js-----------------------------------------
/**
* Sample React Native App => Chat Sample
* https://github.com/facebook/react-native
*
* @format
* @flow
*/

import React, { Component } from 'react';
//import { SafeAreaView, View, Text,} from 'react-native';
import {
Router,
Scene,
} from 'react-native-router-flux';
import Chat from './Chat';
import Speech from './Speech';

export default class App extends Component<{}> {
render() {
return (
<Router>
<Scene key='root'>
<Scene key='Text' component={Speech} title="Speech:Google音声認識" />
<Scene key='Chat' component={Chat} title="VTChat:チャットサンプル" />
</Scene>
</Router>
);
}
}
---------------------------------------------------

2)Speech.jsの追加
https://github.com/KWRI/react-native-google-speech-apiに載ってた「Usage」のコードを丸っと持ってきました。
----Speech.js--------------------------------------
import {
NativeModules,
Platform,
NativeEventEmitter,
DeviceEventEmitter,
Text,
View,
Button,
} from 'react-native';

import React, { Component } from 'react';

const { GoogleSpeechApi } = NativeModules;

const EventEmitter = Platform.select({
android: DeviceEventEmitter,
ios: new NativeEventEmitter(NativeModules.ModuleWithEmitter),
});

export default class Speech extends Component {

constructor(props) {
super(props);
this.state = {
currentText: "",
previousTexts: "",
button: "Start listening"
};
}

componentDidMount(){
GoogleSpeechApi.setApiKey("Your google access token")
EventEmitter.addListener('onSpeechRecognized', (event) => {
var previousTexts = this.state.previousTexts;
var currentText = event['text']
var button = "I'm listening"
if (event['isFinal']){
currentText = ""
previousTexts = event['text'] + "\n" + previousTexts;
button = "Start listening"
}
this.setState({
currentText: currentText,
previousTexts: previousTexts,
button: button
});
});
}

render() {
return (
<View style={{ margin: 30 }}>
<Text>{this.state.currentText}</Text>
<Text>{this.state.previousTexts}</Text>
<Button
title={this.state.button}
onPress={() => {
this.setState({
button: "I'm listening"
})
GoogleSpeechApi.start()
}
}/>
</View>
);
}
}

---------------------------------------------------




さあ、いよいよここからBuild&Goして見ます。
でも!
もんの凄いトラブルの連続で・・・今時点で解決の出口はまだ見えてません。
よって、メモが長ーくなってるので、ここで一旦、話を切ります。


かなり中途半端に終わりますが、悪しからず。
m(__)m



スポンサーサイト





コメントの投稿

非公開コメント

カレンダー
01 | 2024/02 | 03
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 - -
プロフィール

さるもすなる

Author:さるもすなる
さるです。別HPサイト「さるもすなる」から侵食してきました。 山菜/きのこ、それとタイトルにしたPPバンド籠のことをメインに徒然に・・・・暇を持て余したさるの手仕事:男手芸のブログってことで。

最新記事
最新コメント
月別アーカイブ
カテゴリ
天気予報

-天気予報コム- -FC2-
本家のHPのトップ
山菜や茸の話です
PPバンドの籠作品と作り方です
投稿をお待ちしております



PVアクセスランキング にほんブログ村 にほんブログ村 ハンドメイドブログへ



マニュアルのお申し込み



検索フォーム
リンク
RSSリンクの表示
ブロとも申請フォーム

この人とブロともになる

QRコード
QR