読者です 読者をやめる 読者になる 読者になる

ushumpei’s blog

生活で気になったことを随時調べて書いていきます。

ブラウザでテキスト読み上げるコンポーネント: react-voice-components

テキスト読み上げをしてくれるReactコンポーネントの存在を知りました。grvcoelho/react-voice-components

ブラウザで音声を使って何かしたいと思っていたので、試しに触ってみて、GitHub Pageにあげてみました。 以下ちょっと苦労したので、メモです。

Reactを動かせる環境の作成

半年前くらいに作ったコンパイルの環境がかなり古くなっていたので、facebookincubator/create-react-appで作り直しました。インストールに少々時間がかかりましたが、とても便利ですね。

npmで入れたreact-voice-componentsが動かない?

npmで入れたreact-voice-componentsだと、create-react-appで作った環境との相性なのか、コンパイルされずブラウザエラーが発生して動きませんでした。webpackの設定ファイルを上書けばいいようですが、とりあえず、git submoduleリポジトリコンパイル対象のディレクトリにクローンして使用することにしました。せっかくなので、本当に問題があるのなら、いずれ修正を送ってみようかと思います。

書いたコードです;

ushumpei/play-with-react-voice-components

GitHubページを公開する

GitHubページの公開方法は3つあるようで、mastergh-pagesブランチのindex.htmlからか、master/docsを使うか、だそうです。

今回はdocsを作成して公開しました。静的リソース(cssjs)の指定が絶対パスだったため、読み込まれなくて困りました。

感想

  • テキストから音声ファイルとして吐き出すことはできるか気になりました。
  • Reactで綺麗に書けるようになりたいです。
  • GitHubはとても太っ腹です。
  • リポジトリの作者がすでにデモページを作成してくださっているようです。。。

GitHubのIssuesを閉じる方法

GitHubのIssuesを閉じる方法、GitHubのHelpページでも紹介されていますが、commit messageに関して書かれているだけなので、PullRequestからでも閉じられるか確認しました。

確認内容

結論から言うと、PullRequestからでも閉じられます。

以下試したことです。これらは全て、マージするとIssue nを閉じてくれました。なお確認したのは、PullRequestの向き先がmasterの場合です。;

  • commit messageの1行目にClose #nが記述されたcommitを持つPullRequest
  • commit messageの3行目にClose #nが記述されたcommitを持つPullRequest
  • titleにClose #nが記述されたPullRequest
  • descriptionにClose #nが記述されたPullRequest

試してみたリポジトリ(特にどうでもいい内容です)。

余談

Closecloseでも問題なく、この単語以外には次の単語群が使用可能らしいです。

GitHubのHelpページ

Keywords for closing issues

The following keywords will close an issue via commit message:

close
closes
closed
fix
fixes
fixed
resolve
resolves
resolved

(転載日時: 2016/12/20)

Helpページでは、あるリポジトリから別のリポジトリのIssueを閉じる方法なども紹介されてます。

感想

PullRequestとIssueはID(#番号)の空間を共有していることに今更気がつきました。

repositoryのカタカナ表記をリポジトリとしましたが、レポジトリという発音をよく聞きます、どちらがいいのでしょう?

Yesodのquick startが重い

 題に掲げた問題を解決するための記事ではないです。HaskellのwebアプリケーションフレームワークYesodquickstartをDockerfileで行っただけの記事です。

Dockerfile

 Dockerfileを書きます。

FROM haskell:latest
MAINTAINER ushumpei
ARG project_name
RUN stack new $project_name yesod-sqlite \
  && cd $project_name \
  && stack build yesod-bin cabal-install --install-ghc \
  && stack build
CMD ["/bin/sh"]

 ビルドします。任意のプロジェクト名を引数に取れるようにARGで指定しています。引数を渡すには--build-argオプションをつけて、イメージ自体に名前をつけるために-tオプションをつけます。

docker build -t yesod_sample . --build-arg project_name=sample

 ビルドできたらコンテナを立ち上げます。めちゃくちゃ時間がかかります。。。

docker run -i -t --rm -p 3000:3000 yesod_sample /bin/bash

 立ち上がったらコンテナのシェルが起動します、/以下にARGで指定した名前のプロジェクトができているので移動し、起動コマンドを実行します。

cd /sample
stack exec -- yesod devel

 コンパイルマイグレーションが終わればlocalhost:3000で「Welcome To Yesod!」のページにアクセスできるようになります。

感想

 stack build yesod-bin cabal-install --install-ghcがめちゃくちゃ重くて面倒でした。DockerHubに重い部分がいい感じに済んでいるイメージとかありそうですね。dockerstackyesodとわからないことが二つ以上あるともうしっちゃかめっちゃかです。

Leap Motionを手に入れました

 Leap Motionを手に入れました。Leap Motionは手の動きをかなりの精度で取得できるセンサーです。たくさんの言語でプログラミング可能なAPIが提供されていますが、とりあえずjavascriptAPIを使ってみます。また、各クラスの内容もざっくりと整理していこうと思います。

 ここでは、開発PCがmacなのでSDKV2 desktopを使います。Windowsの方は新しいSDKが使えるようなのでそちらを使ったほうがいいかもしれません。(VR関係に強化されているように見えます)

参考

とりあえず

 環境設定やインストールは省略します、公式サイトの指示通りにすれば問題ないはずです。

 仕組みを理解するために、とりあえずブラウザ上に手を表示させてみます。まずはセンサーの値を取れるか確認をするためのコードを記述します。

ブラウザのコンソールに吐き出すだけ

<html>
  <head>
    <!-- <script src="./leap-0.6.4.js"></script> -->
    <script src="https://js.leapmotion.com/leap-0.6.4.js"></script>
    <script>
      Leap.loop(frame => console.log(frame));
    </script>
  </head>
  <body>
  </body>
</html>

 LeapJSを外部リソースとして取得します。LeapはLeapJSがネームスペースとして確保しているオブジェクトのようです。

 値をとるにはLeap.loopにコールバック関数を渡します。この関数にセンサーが取得したframeオブジェクトが引数で渡されるので、それに対する処理を記述するのがアプリケーション作成の基本的な流れになると思います。

 frameオブジェクトの詳細はリファレンスに書いてあります。手、指、ツール(棒状のもの)などのデータをプロパティとして持っていてくれています。

プラグイン Rigged Handを使う

 LeapJSはプラグインという形で機能拡張できるようになっています。プラグインControllerクラスによって管理されます。各プラグインpluginメソッドにより登録しuseメソッドにより有効にしたり、useメソッドに直接関数を渡すことで、loop実行時にコールバックとして呼び出されるようになります。

 プラグインを使うための準備として、まずは先ほどの処理をLeap.loopを使わない記述方法に変えておきます。

<html>
  <head>
    <!-- <script src="./leap-0.6.4.js"></script> -->
    <script src="https://js.leapmotion.com/leap-0.6.4.js"></script>
    <script>
      const controller = new Leap.Controller();
      controller.use(
        () => ({
          frame: frame => console.log(frame),
        })
      );
      controller.connect();
    </script>
  </head>
  <body>
  </body>
</html>

 プラグインを追加する準備が整ったところで、リアルな手を表示することができるRigged Handというプラグインを追加してみます。

 プラグインを使用するにはleap.rigged-hand-0.1.7.jsの他に、いくつかのライブラリを読み込む必要があります。useメソッドでriggedHandを使用するようにします。

<html>
  <head>
    <!--
      以下から必要なライブラリを取得
      https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.js
      https://js.leapmotion.com/leap-0.6.4.js
      https://js.leapmotion.com/leap-plugins-0.1.10.js
      https://github.com/leapmotion/leapjs-rigged-hand/blob/master/build/leap.rigged-hand-0.1.7.js
    -->
    <script type="text/javascript" src="three.js"></script>
    <script type="text/javascript" src="leap-0.6.4.js"></script>
    <script type="text/javascript" src="leap-plugins-0.1.10.js"></script>
    <script type="text/javascript" src="leap.rigged-hand-0.1.7.js"></script>

    <script>
      const controller = new Leap.Controller();
      controller.use('riggedHand');
      controller.connect();
    </script>
  </head>
  <body>
  </body>
</html>

   動作はこんな感じになりました。実際の手も一緒に撮影すればよかったです。。。


Leap Motion - Rigged Hand Demo

LeapJSのクラスに関する考察

 API Referenceによると、LeapJSには次のクラスが存在します。

制御

クラス名 概要
Controller Leap MotionAPIに接続するためのインターフェース。オプションや、フレーム更新時のコールバックの設定など、最もさわりそうなオブジェクト
InteractionBox Leap Motion Controllerに紐づいた表示領域を扱うオブジェクト?領域に応じたベクトルの正規化方法などを提供してくれるみたいです
Frame センサーがフレーム更新ごとに取得した手、指に関するデータを含むオブジェクト

パーツ

クラス名 概要
Pointable 指(Finger)やツールなどの抽象クラスで位置や方向、速度などを保持しているオブジェクトです
Hand 手のオブジェクトで、5本の指の配列や腕などプロパティに持っています。かなり豊富な情報を持っているようです
Finger 指のオブジェクトで、生えている位置や、手の骨の本数文の骨オブジェクトに関する情報を持っています。何指か、などの識別子も持っています
Bone 骨のオブジェクトで、指の骨を表しています。前後の関節を持っています

ジェスチャー

 ジェスチャーは多いので個々の概要は省略します。認識してくれるハンドサインという認識です。独自に追加できるかはちょっとわからないです。

  • Gesture
    • CircleGesture
    • ScreenTapGesture
    • KeyTapGesture
    • SwipeGesture

計算要素

クラス名 概要
Matrix math 行列のオブジェクト。WebGL用外部ライブラリを使っているようです
Vector math ベクトルのオブジェクト。WebGL用外部ライブラリに入っているvec3を使っているようです

感想

 API Referenceを読んで、勝手に各クラスの概要などを書きましたが、このドキュメントを和訳した方が随分人のためになるんだろうな、と思いました。(もしかしたら和訳されている?)

 まだまだわかっていないことが多いので、ご指摘いただければ幸いです。

screenコマンドの小さな話

 ターミナル操作をいい感じにできる仮想端末マネージャコマンドscreenを最近知りました。メモしておきます。

 私の理解では、ターミナルをラップして、通常のシェル操作に加え、セッション、ウィンドウ、領域という概念を取り込み、それらを操作できるようにするものです。

参考: Screen User's Manual

 screenを実行すると仮想端末のセッション(session)とそれに紐づく一つのウィンドウ(window)が起動します。ウィンドウ内ではいつも通りのシェルの操作に加え、セッションに紐づくウィンドウを複数起動できるようになるので、ssh等でサーバに接続した後で起動すると便利です。今まで複数ログインしていた場合、一度ログインしてウィンドウを複数起動することで済ますことができます。(TeraTermのセッションの複製に似た感じです。詳しく見ていないですが内部的に使っているのでしょうか?)

 使うことのメリットとして、

  • 複数ウィンドウを起動できるので、面倒な踏み台経由のssh接続時に結構楽できます。
  • 接続が切れてもセッションが残っていてくれるので、再度つなぎなおした時に作業をすぐに再開できます。一つのウィンドウで長い処理を走らせて寝かせておくこともできます。

 他にも、コマンドによるコピー&ペーストの操作をキーボードのみでできるようになることも、なかなか嬉しいことです。

基本的な使い方

 触っていてよく使っているコマンドを羅列します。

セッション管理系

コマンド 内容
screen 新しいsessionとそれに紐づいた一つのwindowを起動します。
screen -ls 現在起動しているsessionの一覧を表示します
screen -r 最後に繋いでいたsessionを再開します。sessionのidを渡せば指定したセッションにつなぎ直すことができます
Ctrl+a d session起動中に現在のsessionから抜ける(detach)ことができます。detach後もsessionは起動しているので、一覧で確認できます
Ctrl+a \ session起動中、session自体を削除します。一覧からも消えます。起動中の紐づいた全てのwindowも削除されます。私の環境だとCtrl+a Ctrl+¥になっていました

チートシート

 セッション起動後は、Ctrl+a ?でコマンドのチートシートが表示されます。私のメモの存在意義を奪いかねないですが、ただ表示されるコマンドがアルファベット順なのでちょっと見にくいです。そこに漬け込みます。

 以下主にセッション起動後のコマンドになります。

ウィンドウ管理系

コマンド 内容
Ctrl+a c 新しいwindowを開きます
Ctrl+a k windowを削除します、正確には削除しますか?と(y/n)で聞かれます
Ctrl+a " windowの一覧を表示します。j,kでwindowを切り替えることができます
Ctrl+a N 現在開いているwindowの名前(Name?)を表示します
Ctrl+a n, Ctrl+a p 別のwindowに切り替えます。多分切り替え先はprevious,nextに対応していると思います
Ctrl+a Ctrl+a 切り替え前のwindowに切り替えます

領域管理系

コマンド 内容
Ctrl+a S windowを水平に分割します。windowが紐づかない新しい領域(region)を作成します
Ctrl+a | windowを垂直に分割します。windowが紐づかない新しいregionを作成します
Ctrl+a TAB 分割されたregion間を移動します
Ctrl+a X 分割時、現在有効になっているregionを削除します
Ctrl+a Q 分割時、現在有効になっていない他のregionを削除します

メタ操作系(未整理)

コマンド 内容
Ctrl+[ コピーモードに入ります。hjkl等のvimライクな入力で移動することができます。spaceを押すとコピー開始位置を指定、もう一度spaceを押すと選択範囲をコピーします
Ctrl+] バッファのコピーした内容をペーストします

使っていての感想

 色々あります。

  • Ctrl+aがシェルの行頭移動を奪ってしまいます。Ctrl+a aに行頭移動が振り分けられているので頭を切り替えて使っています。セッションの中にいる、と言うことを意識できるのでこれはこれでいいかもしれないです。キーバインドを変えるのは嫌なので私はこのままです。慣れました。
  • vimの画面分割と一緒に使うと結構混乱します。vimCtrl+w系の画面移動とごっちゃになったり、screenでのコピー範囲が行単位なので行番号入っちゃったりしました。これは対応方法がわからないですが、慣れました。
  • スクロールについて最初どうすればいいか不明でした。ログ出力等で流れてしまった時は、コピーモードに入って遡っています。別にコピーしたいわけではないのでちょっと気持ち悪いです。vimの気分で操作しています、less同様いまだに正しい移動操作がわかりません。
  • macにデフォルトで入っているscreenはヴァージョンが古いようで垂直分割ができないです(2016/12/14に確認)。homebrewで入れ直しました。あと、ssh接続時に便利とか書いていましたが意外にコマンド自体が入っていないことがあったりします、注意です。

 他にもウィンドウ操作を記録することができたりするのですが、使い道がわからず今のところ使っていないです。さらに他にも複数人で同じセッションを共有するマルチディスプレーモードという便利なものもあるそうですが、私はぼっちなので使っていません。

感想

 コピー&ペーストがキーボードから手を動かさずに使えるので、嬉しくてローカルでも使っています。早く使いこなせるようになるといいのですが。まだまだ不明点が多いです。

 上記内容に間違いがあれば申し訳ないですが、修正しますので是非教えていただきたいです。