voicodという音声入力でメモを書けるシンプルなウェブアプリケーションを書きました。

SpeechRecognitionというウェブブラウザで音声認識をするAPIを使っているので、このAPIに対応しているブラウザが必要になります。 具体的にはGoogle ChromeやSafariなど該当します(2022-02-10時点)が、Chromeが一番相性が良いと思います。

使い方

  1. https://voicod.pages.dev/ を開く
  2. マイクの使用を許可する
  3. 音声入力するとメモが記録される

というシンプルなものです。

入力した内容は自動的にlocalStorageに保存されるので、リロードしても前回の状態から再開できます。 逆に前回の状態じゃなくて毎回初期状態から開始したい場合は https://voicod.pages.dev/?noSave へアクセスすると自動保存を無効化できます。

このアプリケーションは音声入力してテキストのメモを書くというシンプルなアプリケーションですが、 x-callback連携やChrome Apps(ショートカット)と組み合わせると入力内容を別のアプリケーションに渡すといった色々な使い方ができます。

x-callbackを使ったアプリケーション連携

Voicodは、x-callback-urlというURLスキームを使ったアプリケーション連携に対応しています。 URLスキームで別のアプリを起動したり、データを渡すやりとりはiOSアプリなどで使われていますが、x-callback-urlはそのルールを簡単に決めたものです。

iOSやmacOSのショートカット.appも対応しています。(iOSでは色々なアプリが応していますが、AndroidではIntentがあるのであんまりメジャーではありません)

例えば、shortcuts://x-callback-url/run-shortcut?name=Calculate&input=text&text=24.99&x-success=https://111.example.com&x-cancel=https://222.example.com というURLをmacOSやiOSで開くと、Calculateというショートカット(ショートカット.appで定義したショートカット名)が実行されます。 この実行した結果が、成功ならx-successパラメータで指定したhttps://111.example.comというURLが開かれます。 途中でキャンセルした場合は、x-cancelパラメータで指定したhttps://222.example.comが開かれるという仕組みです。

voicodはウェブアプリケーションですが、同じようにこの仕組みをサポートしています。

  • x-success=<encoed url>: "OK"というボタンが表示されるので、このボタンをクリックしたときに開くURLを指定します(任意)
    • URL中の {{reuslt}} という文字列が自動的に入力した内容に置換されます
  • x-cancel=<encoed url>: "Cancel"というボタンが表示されるので、このボタンをクリックしたときに開く URLを指定します(任意)
  • x-error=<encoed url>: エラーが発生した際に開くURLを指定します。
    • URL中の {{errorMessage}} という文字列が自動的に入力した内容に置換されます

x-callback-urlの仕様にはありませんが、次のパラメータも用意しています。

  • x-onetime: このパラメータが指定されている場合は、音声入力が完了(メモに入力される)する度にx-successのURLが自動的に開かれます。

具体的な例を見てみると次のようなURLの指定ができます。

x-callback

詳細はazu/voicod: Voice note editorにも書いています。

このx-callback-urlを使うと、音声入力した内容を別のアプリケーションに渡したり、メモの内容をNotionなどの別のアプリに保存したりできます。 いくつか具体的な例を紹介します。

x-callback-urlは、Appleが提供してるショートカット.appと相性がいいので、macOSでの例を紹介しています。

入力内容をNotionに保存する

まず、共有内容をNotionの特定のテーブルに保存するショートカットを作成します。

次のリンクからインストールできます(Safariで開く必要があります)

Shortcut:Notion

このショートカットには、次の設定がインストール後に必要です。

  • Database Idを入れる: 保存先となるNotionのデータベースID
    • データベースURLの https://www.notion.so/{databaseid}?v=xxxx 部分がdatabseidです。
  • NotionのAPI Keyを入れる: NotionのAPIキー

次の記事がこのショートカットのベースなので、Notion側の設定方法などを参考にしてみてください。

これで、ショートカットを開くときに渡した内容が、指定したNotionテーブルに保存できるようになります。

そして、次のようなURLでvoicodをひらけば、入力した内容と共に先ほどのNotionショートカットが呼びされます。 ショートカットでは入力した内容をテーブルに保存してくれます。

このように、voicodで入力して、すぐ別のアプリに保存するといった連携ができます。

ショートカット.appは、HTTPリクエスト送ったり、AppleScriptを呼び出したり、Actionsを使ってデータを加工したりが、ほとんどコード書かずにできるので、多分大体のことはできます。

InkdropのREST APIを使う例も置いておきます。

Chromeアプリで利用する

voicodは、Service Workerでキャッシュしたり、Web Manifestに対応しているので、Chromeアプリとして利用できます。 いまいち馴染みない単語ですが、特定のURLをChromeで開く単体アプリを作る簡易な仕組みみたいなものです。 (中身はapp_mode_loaderというバイナリが入ったラッパーみたいな.appファイルが作成できる仕組み)

PWAの文脈だとホーム画面に追加とかA2HSとか言われるものでできると同じものです。

voicodを開くと、URLバーにダウンロードっぽいアイコンがあるので、これをクリックするとChromeアプリとしてインストールできます。

A2HS

また、その他ツール → ショートカットを作成 からも同じくChromeアプリを作れます。 このときに"ウィンドウとして開く"のチェックを入れる必要があります。

Chromeアプリで開いた瞬間から、音声入力が始まるので特定のキーでトグル表示するなど(Alfredなどでできます)しておくと、 キー入力一つで音声メモが書き始められるので便利です。

また、先ほどのNotion連携のように https://voicod.pages.dev/?x-onetime&x-success=shortcuts%3A%2F%2Fx-callback-url%2Frun-shortcut%3Fname%3DNotion%26input%3Dtext%26text%3D%7B%7Bresult%7D%7D のようなURLを開いて、このURLを"ショートカットを作成"からアプリとして登録もできます。 x-callback連携を含んだ状態のアプリを起動すれば、音声入力してその結果をNotionに保存するアプリが簡単に作成できます。

起動自体は、macOSのSiri("Hey Siri")からショートカット.app経由でVoicodのアプリを起動すれば、完全にハンドレスで音声メモがかけたりもします。 (iOSだと、ショートカット自体に音声認識があるので、そっちの方が楽です。macOSの音声認識はまだ動いていない)

色々遊んでた例。

記憶に残らないものをメモするためにMemory Noteという仕組みを書いた | Web Scratchという記事で、Memory Noteというメモの仕組みを公開しています。 自分は、基本的にMemory Noteは音声入力で書いていて、入力しようと思うとキーボードが必要になって大体入力する前に忘れてしまうので、音声でメモるようにしていました。 この時のメモはiOSのショートカット + Homepodを使ってることがほとんどでした。

macOSでもvoicodを使えば、大体同じようなことができるようになりました。 (またキーボードが近いので、誤認識を修正しやすいという違いもあります)

まとめ

voicodという音声認識した結果をメモするシンプルなアプリケーションを書きました。 voicodのソースコードは次のページで公開しています。

最初はもっと色々な機能をつけるつもりでしたが、x-callback連携を使ってショートカット.appと組み合わせればコードを書かないでも色々できるのがわかりました。 また、ChromeのChromeアプリという仕組みを使えば、単機能なウェブアプリがかなり柔軟に使えるのでわかってよかったです。

ウェブアプリの開発は楽だけど、ネイティブアプリみたいに気軽に使えないみたいなのは、Chromeアプリな仕組みで結構カバーできたりしそうで面白いなと思いました。