目次
Vue.jsとWebSpeechAPIとFirestoreで音声認識アプリ(ボイスレコーダー)
以下の本を衝動買いしたところ、Web Speech APIというWEBブラウザChromeで動作する簡単音声認識システムがあることを知りました。
Web Speech APIを使ったアプリはChromeでのみ動作します
Internet ExplorerやSafariでは動作しません。
このアプリの音声認識機能を利用するためには、パソコンでも、スマホでも、Chromeをインストールする必要があります。
手元のZenfone 4 Maxでは、Chromeにて音声認識することはできました。PWA(Progressive Web Apps)なので、スマホにアプリとして登録し、オフラインで使用可能です。
なお、iPhone8のChromeでtryしましたが、STARTボタンの“START”が表示されず、クリックしても音声認識が開始されませんでした。(残念、、、)
方針をたてる
- マイクのついた端末で、Chromeでアプリを開いてもらうことが前提
- スタートボタンを押して、マイクに話しかけると、話しかけた内容が文字で表示される
- ストップボタンで文字おこし中止
- 文字におこしたテキストを、Firebase Firestoreに保存し、メモ一覧を表示し、検索、削除できる
今回は、以下のコードを参考にさせていただきました。
ソースコード
https://codesandbox.io/s/71yznl2zwq
デモサイト1
https://csb-71yznl2zwq.netlify.com/
デモサイト2
0.用意するもの(開発環境)
パソコン Chrome(くろーむ、WEBブラウザの一つ) GitHubアカウント作成済み(無料) Googleアカウント作成済み(無料)
パソコンは、Windowsパソコンでも、Macでも、かまいませんが、私の場合はWindows 10 Proとなります。今回は、Web Speech APIを利用するため、アプリを利用する人にもChromeは必須です。Internet Exploler、Safari、Firefox、Edgeなどではうまく動かないそうです。
今回利用するもの
CodeSandbox Firebase Firestore Vue 2.5.2 Vuetify firebase moment
Codesandboxで新規Vue.jsアプリの作成
src/App.vueにVuetifyのテンプレートを適用
text-areaとbuttonを設定
Card内のimgを消して、textareaで置き換えます。button名もStartとStopに変更します。
src/App.vue
<template> <div id="app"> <v-app id="inspire"> <v-toolbar color="indigo" dark fixed app> <v-toolbar-title>Vue WebSpeechAPI Recognition</v-toolbar-title> </v-toolbar> <v-content> <v-container fluid> <v-flex xs12 sm6 offset-sm3> <v-card> <v-textarea outline name="input-7-4" label="Speech Recognition" v-model="text" ></v-textarea> <v-btn color="info" @click="startSpeech">{{ recognitionText }}</v-btn> <v-card-title primary-title> <div> Startボタンをクリックして、日本語で話しかけてください。終了したら、Stopボタンをクリックしてください。 </div> </v-card-title> </v-card> </v-flex> </v-container> </v-content> </v-app> </div> </template> <script> export default { data() { return {}; } }; </script>
初期データの設定
以下、src/App.vueの<sciprt>内にコードを編集していきます。
data: function() {} 内に、初期データを記載します。
data: function() { return { text: "", recognition: new webkitSpeechRecognition(), recognitionText: "音声入力開始" }; }
Web Speech APIを利用するためには、以下の2行を記載します。
const speech = new webkitSpeechRecognition(); speech.lang = 'ja-JP';
methods()関数とcreated()関数を定義
音声認識開始buttonをクリックすると、recognition.onstartで音声認識開始し、認識された時点(recognition.onresult)で認識結果をtextに代入します。
以下のコードをsrc/App.vueの<script>内に追加します。
created: function() { this.recognition.onstart = () => { this.recognitionText = "音声入力中..."; }; this.recognition.onend = () => { this.recognitionText = "音声入力開始"; }; this.recognition.onresult = event => { if (event.results.length > 0) { this.text = event.results[0][0].transcript; } }; }, methods: { startSpeech: function() { this.recognition.start(); } }
音声入力開始ボタンをクリックして、実行してみる
- 音声入力開始ボタンをクリック
- 最初だけ、ポップアップ画面が出てくるので、マイクの使用に対して「許可」をクリック
- 「音声入力開始」ボタンをクリックして、パソコンに向かって「テスト」と話しかける
複数文の認識と、認識している途中にも結果を得る
参考:https://qiita.com/hmmrjn/items/4b77a86030ed0071f548
// 認識しっぱなしにする recognition.continuous = true; // 認識している途中にも結果を得る recognition.interimResults = true;
- “STOP”ボタンを設置し、stopSpeech()関数で音声入力終了とする
- 音声入力の途中経過も表示する
動作確認します。
STARTボタンを押して、マイクに話しかけて、STOPボタンを押すと、以下のように表示されました。
テキストボックスの中身は編集することができます。
音声認識結果をFirebtase(Firestore)に保存する
と同様に、DatabaseのCloud Firestoreを使用できるように設定します。
https://console.firebase.google.com
から、
- 新規Firebaseアプリの作成
- apiキーなどをメモ帳などに保存
- Database > Cloud Firestoreの、「データベースを作成」をクリック
- 一時的に、テストモードにする
CodeSandboxでFirebaseを使用できるようにDependencyの追加とindex.htmlとsrc/main.jsの編集
- Dependencyで、さらに、firebaseを追加
- index.htmlの編集(不要かも?)
- src/main.jsの編集(こちらに、FirebaseのAPIキーなどをコピペします)
- src/App.vueの<script>直下にimport文を記載
テキストの内容をFirestoreに保存(src/App.vue)
src/App.vue
<template>にsaveText()のボタンを追加し、
<script>のmethods:{}内に、saveText()関数を定義します。
吹き込んでみます。SAVEボタンを押すと、Firestoreのrecognitionsに音声認識されたテキストが保存されていることが確認できます。
Firestoreに保存したテキストをリスト表示
参考:
https://qiita.com/MasanobuAkiba/items/6a0f4e3007816dd54bec
https://www.webopixel.net/javascript/1227.html
CodeSandboxのDependencyでmomentを追加
// <template>の一部 <v-card> <v-card-title primary-title> <h2>List</h2> <ul class="list-group"> <li class="list-group-item" v-for="(note, index) in notes" :key="note.index"> <div>{{ note.text }} ( {{ note.timestamp | moment }} )</div> </li> </ul> </v-card-title> </v-card> // <script>の一部 import moment from "moment"; export default { filters: { moment: function (date) { return moment(date).format('MM/DD HH:mm'); } }, methods: { saveText: function() { db.collection("recognitions").add({ text: this.text, timestamp: Date.now() }); this.text = ""; this.getNotes(); } } }
誤認識などで、テキストフィールドに表示された内容を変更したいときは、テキストを編集後にSAVEボタンをクリックすれば、変更内容はアップロードするテキストに反映されます。
リストをVuetifyのData tablesで表示
リストの、以下の部分を、VuetifyのData tablesを用いて表示します。
(変更前)
<ul class="list-group"> <li class="list-group-item" v-for="(note, index) in notes" :key="note.index"> <div>{{ note.text }} ( {{ note.timestamp | moment }} )</div> </li> </ul>
(変更後)
<v-data-table :headers="headers" :items="notes" :pagination.sync="pagination" class="elevation-1"> <template slot="items" slot-scope="props"> <td>{{ props.item.text }}</td> <td class="text-xs-right">{{ props.item.timestamp | moment }}</td> </template> </v-data-table> // 以下、<script>内 data: function() { return { headers: [ { text: 'テキスト', align: 'left', sortable: false, value: 'text' }, { text: '時刻', value: 'timestamp' }, ], pagination: { sortBy: 'timestamp', descending: true, }, }; },
参考:https://vuetifyjs.com/ja/components/data-tables
https://commis.hatenablog.com/entry/2018/05/29/102606
●VuetifyのData tableを指定列の降順で初期表示する方法
- <template>で、v-data-tableにpagination.syncプロパティを指定する。
- <script>で、data: function() {return {}} 内に、pagination: {sortBy: 'id', descending: true,}のように記載する。
Vuetifyのdata tableで検索(フィルタ)
Vuetifyのdata tableでは、検索(フィルタリング)はかなり簡単に行うことができます。
<template>内に、以下を追加。
特に、<v-data-table :search=“search” > がポイントです。
<v-card> <v-card-title> List <v-spacer></v-spacer> <v-text-field v-model="search" append-icon="search" label="Search" single-line hide-details ></v-text-field> </v-card-title> <v-data-table :headers="headers" :items="notes" :pagination.sync="pagination" :search="search" class="elevation-1" > (略) <v-alert slot="no-results" :value="true" color="error" icon="warning"> Your search for "{{ search }}" found no results. </v-alert> </v-data-table> </v-card> <code> さらに、<script>内に、以下を追加 <code> data: function() { return { search: '', // ←これを追加!! } }
Vuetifyのdata tableで削除ボタン
<scipt>のdata:のheaders: []内の最後に以下を追加
{ text: '削除', value: 'name', sortable: false }
getNotes()内の、array.pushの中に、idも追加するように編集。(後で、idを用いて、Firestore内のデータを削除するため。)
<template>内に、削除ボタンを追加(deleteItem関数を設置)
<script>のmethods内に、deleteItem関数を定義
deleteItem: function(item) { const index = this.notes.indexOf(item) console.log(index); //const obj = this.notes[this.index] //console.log(obj); const id = this.notes[index].id; console.log(id); console.log(this.notes) db.collection("recognitions").doc(id).delete(); this.getNotes(); }
(ちなみに、data内の、index: 0 は削除しました。)
これで、メモの検索と削除ができるようになりました。
以上となります。
ソースコード
Web Speech APIに関するリンク
https://qiita.com/hmmrjn/items/4b77a86030ed0071f548
https://qiita.com/Sa2Knight/items/a7deb5b5d07820f6f19e
@Sa2Knight
2018年05月05日に投稿
[Vue] 音声入力できる入力コンポーネントを作る
https://qiita.com/GalapagosOf/items/b0df73a0a53a29b40388
@GalapagosOf
2018年07月28日に投稿
WebSpeechAPIの概略
https://qiita.com/yorifuji/items/9988f9a31c48bae31def
@yorifuji
2018年12月19日に更新
SkyWay Advent Calendar 201819日目
リアルタイム翻訳機能の付いたWeb会議を作ってみた
https://github.com/yorifuji/webrtc-realtime-translation
https://qiita.com/TakeshiNickOsanai/items/7a486085b039c2128217
@TakeshiNickOsanai
2018年12月06日に投稿
Web Speech API を 利用して 英単語の音声確認をするアプリを作る
https://qiita.com/tomsato/items/22735755b30a41e9a7e4
@tomsato
2018年08月27日に更新
Vue.jsとWebSpeechAPIを利用して音声文字起こし補助サイトを作った話
Vue.jsとCloud FirestoreでTODOアプリのリンク
https://grokonez.com/frontend/vue-js/vue-js-firestore-example-vue-js-crud-serverless-with-firebase-cloud-firestore
https://qiita.com/rubytomato@github/items/78087a2c69389f642760
@rubytomato@github
2018年05月09日に更新
Cloud Firestore with Vue.jsで簡単なメモアプリを実装する
Vuetifyのdata tableに関するリンク
https://qiita.com/nobu-maple/items/f0322bc99dce2d8eda40
@nobu-maple
2018年12月18日に更新
STEP05:Laravel5.7 + Vue2.5 で Vuetifyのダイアログを使ってユーザ情報を更新
https://qiita.com/d-yosh/items/9299389b32c496a9b64c
@d-yosh
2018年03月16日に更新
Vuetify.jsのData tablesでフィルタリングを行う
https://medium.freecodecamp.org/how-to-build-a-real-time-editable-data-table-in-vue-js-46b7f0b11684
How to build a real-time editable data table in Vue.js
Peter Mbanugo
Jun 23, 2018
リンク