文書の過去の版を表示しています。
目次
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
デモサイト
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();
}
}
}
誤認識などで、テキストフィールドに表示された内容を変更すると、変更内容はアップロードするテキストには反映されます。
リストを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
リンク























