きっかけは「指ぱっちん」

##きっかけは「指ぱっちん」
指ぱっちんでITらしいことをしてみようということで、
**指ぱっちん** をきっかけに **ブラウザ** を制御して **Youtube動画** を開いてみようという話になりました。

指ぱっちんをしてブラウザを制御する方法には、**Python** 。
Youtube動画のブラウザ上の制御には、**React** を使ってみることにしました。

----
## Python について
音声認識が簡単にできる言語はあるか、ライブラリはあるかをチームで話し合った結果
Pythonで使用できるPyAudioというライブラリを使うことになりました。

###環境構築
PyAudioを利用するためPythonの実行環境が必要です。
そこで、PCにLinuxOS(ubuntu)を入れてLinux上で環境構築することにしました。
ubuntuのバージョンは16.04
pythonのバージョンは3.5です。
pythonはubuntuにプリインストールされているものです。

以下のコマンドでPyAudioがインストールされます。

```sh:
　$sudo apt install python-pyaudio
```

また、以下のプログラムでdataに音データが格納されます。

```py:録音サンプル.py
#インポート
import pyaudio
 
#puaudioオブジェクトの生成
p = pyaudio.PyAudio()
 
#一定時間録音して結果をstreamに格納
#引数は他ウェブサイトを参照
#ストリームの準備
stream = p.open(format=pyaudio.paInt16,
                channels=1,
                rate=44100,
                input=True,
                frames_per_buffer=1024)
#録音
data = stream.read(CHUNK)
 
#録音結果はバイトコードなので変換をかけて-1～1の数値の配列に
#numpyが入ってなければインストールして
import numpy as np
data=np.frombuffer(data, dtype="int16")/32768
```

----
## React について
Reactとは、インタラクティブなユーザーインタフェースを作成できるJavaScript library
###環境構築

1.WindowsマシンにNode.js の最新バージョンインストール。
2.Reactをインストール

```sh:
　　>npm install react --save
```

3.以下のコマンドでプロジェクト作成

```sh:
　　>npx create-react-app my-app
```
4.ReactPlayerをインストール

```sh:
　　>npm install react-player --save
```

----
## 実装について(React編)
React側は、表示されるページを生成します。

1.インストールされた領域のsrcフォルダ配下でスクリプトを書く

```js:App.js
import React, { Component } from "react"; 
import "./App.css";
import ReactPlayer from "react-player"
 
class App extends Component {
  render() {
    // 動画のIDはランダムで出るようにしてみる
    var list = [
        "HgzGwKwLmgM",
        "2ZBtPf7FOoM",
        "vNhhAEupU4g",
        "fJ9rUzIMcZQ",
        "GugsCdLHm-Q",
        "-tJYN-eG1zk",
        "04854XqcfCY",
        "rY0WxgSXdEE",
        "kijpcUv-b8M",
        "a01QQZyl-_I",
        "rdvabdyZ7vU"
    ];
    var random = Math.floor(Math.random() * 10);
    console.log(list[random]);
     
    // 動画を表示する
    return <ReactPlayer url={"https://youtu.be/" + list[random]} playing />
  }
}
 
export default App;
```

2.スクリプト実行

```sh:
　　>npm run start
```

3.実行結果

```sh:
D:\temp\指パッチン >npm run start
> hello-world@0.1.0 start D:\temp\指パッチン
> react-scripts start
 
Compiled successfully!
 
You can now view hello-world in the browser.
 
  Local:            http://localhost:3000/
  On Your Network:  http://172.20.7.51:3000/
 
Note that the development build is not optimized.
To create a production build, use npm run build.
```
**やったぜ**
youtubeを画面に埋め込んだWEBページを起動させることができました。
ブラウザを開き、localhost:3000にアクセスしています。
また、youtubeのビデオID部分はjsにてランダムで変えることができるようになっています。
![react-player.png](https://qiita-image-store.s3.amazonaws.com/0/214532/c8e521e2-df4b-a5c0-f572-9c8fb1d8aabf.png)

----
## 実装について(Python編)
Python側では、音を反応してブラウザを立ち上げるよう実装します。

実装にあたり使用したライブラリは以下です。
 - PyAudio マイクで周囲の音を拾い、ストリームデータを作成。
 - NumPy PyAudioで作成したストリームデータを数値データに変換。
 - Selenium ブラウザを起動し、htmlファイルを起動。
 - geckodriver FireFoxをseleniumで操作する。
下記のソースコードを作成しました。

```py:app.py
import pyaudio
import numpy as np
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
  
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
threshold = 0.8
path = "{ここに表示したいページのURL}"
  
binary = FirefoxBinary('/usr/bin/firefox')
binary.add_command_line_options('-headless')
driver = ""
isOpen = 0
  
def open_web(path):
    global driver
    global isOpen
    if isOpen == 0:
        driver = webdriver.Firefox(firefox_binary=binary)
        driver.get(path)
        isOpen = 1
    else:
        driver.quit()
        isOpen = 0
  
p = pyaudio.PyAudio()
  
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)
  
print("* recording")
 
while True:
    data = stream.read(CHUNK)
    data=np.frombuffer(data, dtype="int16")/32768
    # 入力された音の大きさがthresholdで指定したしきい値を超えた場合、ブラウザを開くようにする。
    if data.max() > threshold:
        open_web(path)
```
しきい値を低くしすぎると常に反応してしまうため、
ある程度大きい音に反応するように調整する必要があります。

###しくみ
PCのマイクである程度大きな音を認識すれば、
selenium経由でfirefoxが立ち上がる仕組みです。
また、フラグ管理しているため、指ぱっちんをするたびに
ブラウザを立ち上げ/終了を繰り返すことができます。

React側で作成したページを呼び出せば、
指ぱっちんだけでyoutube起動が実現できます。 
**やったね**

##感想
- やってみたいアイデアから、どのように実現するかを考えての実装だったため
動くものになるか不安がありました。
しかし、なんとか実行環境を整えて実現できたという点は、良かったとおもいます。

- Python実行環境について、最初はWindowsPCで環境構築をしていましたが、VisualStudioのインストールが必要であるなど
環境構築が困難だったため、PCにLinuxOS(ubuntu)を入れて実現することにしました。

- 実現できていない点として、現在のソースではマイクで拾った音の大きさで、
によって周囲で指パッチンされたかを判定しています。

- 指パッチンだけで、自在にブラウザが立ち上がるのは、なかなか愉快。

## 参考情報のリンク
以下のサイトの情報やサンプルソースを参考にさせていただきました。

**Pythonの参考サイト**
PyAudioの基本メモ2 音声入出力 - たけし備忘録 http://takeshid.hatenadiary.jp/entry/2016/01/10/153503
Pythonで音を監視して一定以上の音量を録音する - Qiita https://qiita.com/mix_dvd/items/dc53926b83a9529876f7
PyAudio Document(英語) https://people.csail.mit.edu/hubert/pyaudio/docs/
**Reactの参考サイト**
出来る限り短く説明するReact.js入門 - Qiita https://qiita.com/rgbkids/items/8ec309d1bf5e203d2b19
Reactアプリケーションで動画や音楽ファイルを扱うために「react-player」を使用する - Qiita https://qiita.com/reiji1020/items/a65d84980b67f13449e1
React本体ダウンロード https://react-cn.github.io/react/downloads.html