QRコードリーダ（バーコードリーダ）を使ったjukebox作り

このページでは、前回のQRコードリーダの入力を標準出力するプログラムを用いて、phpで実装したJukeboxのプログラムを作りました。

構造は、以下の通りです。
![jukebox.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325563/48a15fcf-e23d-f50e-7707-578aa66c8857.jpeg)

QRコードリーダにQRコードを読ませると、Jukeboxプログラムで指定したフォルダのmp3ファイルをランダムで、再生します。
再生は、mpg321で実現します。
また、一度利用したQRコードについては、MariaDBに保存して、必要があれば、特定のmp3ファイルを再生するように結びつけを行うことができるようにします。
MariaDBでの特定のmp3ファイルの指定は、phpmyadminを用いれば簡単にできると思います。

<iframe width="560" height="315" src="https://www.youtube.com/embed/FaBdKmYvqa4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
----
#前提環境

RaspberryPiにLAMP環境を作っておきます。phpmyadminも入れておきます。
https://qiita.com/bb-mint/items/42ac7b41f0bd4f965502
https://qiita.com/bb-mint/items/eef1fcb5273100b2c832

USBのQRコードリーダ（バーコードリーダ）をRaspberryPiで利用する手段は
前回作りました。
https://qiita.com/bb-mint/items/049d018d7e59a14f3aa9


プログラムを置くフォルダは
/home/pi/src/
としました。
音楽ファイルは
/home/pi/Music/
以下にフォルダを作って入れています。

----

#１．QRコードリーダの入力を標準出力するプログラム

　前回のUSBのQRコードリーダ（バーコードリーダ）をRaspberryPiで利用する手段からの
　QRコードデータを、シェルスクリプトで、phpで作るjukeboxプログラムに標準入力で入力
　させます。while trueで、何回も繰り返しで実施することとして、QRコードを読み取る毎に
　音楽が変わるようにします。

> cd ~/src
> vi jukebox_deamon.sh
> chmod 755 jukebox_deamon.sh

```jukebox_deamon.sh
#!/bin/bash

while true
do
  /home/pi/src/qrcodereader /dev/input/by-id/usb-SM_SM-2D_PRODUCT_HID_KBW_APP-000000000-event-kbd | php /home/pi/src/jukebox.php
done
```

このシェルスクリプトを、デーモン化することします。
> pi@raspberrypi:~/src $ sudo vi /etc/systemd/system/jukebox.service

```/etc/systemd/system/jukebox.service
[Unit]
Description = Jukebox daemon

[Service]
ExecStart=/home/pi/src/jukebox_deamon.sh
Restart=no
Type=simple
User=pi
Group=pi

[Install]
WantedBy = multi-user.target
```

（ここからは、全部出来上がってから実施します）
有効にします
> pi@raspberrypi:~/src $ sudo systemctl enable jukebox.service
> Created symlink /etc/systemd/system/multi-user.target.wants/jukebox.service → /etc/systemd/system/jukebox.service.

> pi@raspberrypi:~/src $ sudo systemctl start jukebox.service

----
#２．PHPで作ったJukeboxプログラム（mpg321でplay)

　（先に、３．でMariaDBで、データベースを作っておいたほうが良いです）

データベースにアクセスする基本設定を別ファイルで作っています。

> pi@raspberrypi:~/src $ vi ini.php

```ini.php
<?php
    //設定情報
    $dbname = 'jukebox'; //MariaDBでの設定に合わせます
    $dsn = 'mysql:dbname='.$dbname.';host=127.0.0.1';
    $user = 'bb-mint'; //MariaDBでの設定に合わせます
    $password = 'password'; //MariaDBでの設定に合わせます
        
    //データベースからユーザの端末情報を取得
    try {
        $dbh = new PDO($dsn, $user, $password);
    } catch (PDOException $e) {
		print("ERROR: could not connect Database!\n");
        exit();
    }

    //データベースにテーブル設定されていなかったら初期のテーブルを作る
    //データベースにテーブル設定されていたらエラーで何もしない
    try {
        $sql = 'CREATE TABLE jukebox (
	id INT(11) AUTO_INCREMENT PRIMARY KEY,
	text VARCHAR(40) NOT NULL,
	music_file VARCHAR(40) NULL,
	option1 VARCHAR(40) NULL,
	option2 VARCHAR(40) NULL,
	reg_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP) engine=innodb default charset=utf8';

        // SQLを実行
        $res = $dbh->query($sql);
    } catch ( Exception $ex ){
        print ($ex);
    }
?>
```

Jukeboxのメインプログラムは次のように書きました。

> pi@raspberrypi:~/src $ vi jukebox.php

```jukebox.php
<?php
//変数設定
$music_dir = '/home/pi/Music/';
$target_dir = $music_dir.'それいけ! アンパンマン 映画 & テレビ25年記念作品 あつまれ! ムービーソングス [Disc 1]/'; //ここにアルバムを入れます

//プレーヤーコマンド
$playcmd = 'mpg321'; // or 'mpg123'

$str_input = fgets(STDIN);
$str_input = rtrim($str_input,"\n");

//長いQRコードの入力は要らないよな。ということで最後40文字でよいことにしてしまう。
if (strlen($str_input) > 40){
     $str_input = substr($str_input, -40);
}

    //初期データ読み込み
    require('ini.php');

    //QRコードデータの登録検索
    $sql = 'SELECT * FROM jukebox WHERE text=:text';
    $prepare = $dbh->prepare($sql);
    $prepare->bindParam(':text', $str_input, PDO::PARAM_STR);
    $prepare->execute();
    $result = $prepare->fetchAll(PDO::FETCH_ASSOC);

    var_dump($result);

    if($result && $result[0]['music_file']){ //コマンド登録あり
        echo "データベースに登録があり、音楽を指定する\n";
        // $target_dir = $result[0]['option1'];
        $cmd = 'pkill -x '.$playcmd;
        echo $cmd."\n";
        exec($cmd, $opt, $return_ver);
        echo '実行結果：'.$return_ver."\n";
        $cmd = $playcmd.' "'.$target_dir.$result[0]['music_file'].'" > /dev/null &';
        echo $cmd."\n";
        exec($cmd, $opt, $return_ver);
        echo '実行結果：'.$return_ver."\n";
    }elseif($result && $result[0]['text']){ //コマンド登録なし
        echo "データベースに登録がある文字列だが、音楽とのバインドなし\n";
        $cmd = 'pkill -x '.$playcmd;
        echo $cmd."\n";
        exec($cmd, $opt, $return_ver);
        echo '実行結果：'.$return_ver."\n";
        $cmd = 'find "'.$target_dir.'" -type f -name "*.mp3" | shuf -n 1 | xargs -d "\n" '.$playcmd.' > /dev/null &';
        echo $cmd."\n";
        exec($cmd, $opt, $return_ver);
        echo '実行結果：'.$return_ver."\n";
    }else{
        //Bindの作成
        $sql = 'INSERT INTO jukebox (text) VALUES (:text)';
        $prepare = $dbh->prepare($sql);
        $prepare->bindParam(':text', $str_input, PDO::PARAM_STR);
        $prepare->execute();

        $cmd = 'pkill -x '.$playcmd;
        echo $cmd."\n";
        exec($cmd, $opt, $return_ver);
        echo '実行結果：'.$return_ver."\n";
        $cmd = 'find "'.$target_dir.'" -type f -name "*.mp3" | shuf -n 1 | xargs -d "\n" '.$playcmd.' > /dev/null &';
        echo $cmd."\n";
        exec($cmd, $opt, $return_ver);
        echo '実行結果：'.$return_ver."\n";
    }
?>
```

音楽を再生する mpg321 をインストールします。
> pi@raspberrypi:~/src $ sudo apt-get install mpg321

実験するには、次で動くはず
> pi@raspberrypi:~/src $ ./jukebox_deamon.sh

----
#３．MariaDBにQRコードを保存するデータベースを作っておく

MariaDBに、'jukebox'という名のデータベースを作って、
ユーザ'bb-mint'を作成して、'jukebox'データベースへの全権限を付与します。

> pi@raspberrypi:~/src $ mysql -u root -p
> Enter password: 

> MariaDB [(none)]> create database jukebox;
 
> MariaDB [(none)]> create user 'bb-mint'@localhost identified by 'password';

> MariaDB [(none)]> grant all on jukebox.* to 'bb-mint'@localhost;

> MariaDB [(none)]> flush privileges;

これで、２のプログラム（ini.php）を動かせば、初期設定されます。

データベースに音楽ファイル名を登録すると、同じQRコードを読み込ませると
同じ曲がかかるようになります。（phpmyadminで、簡単に調整できます）
music_fileのフィールドです。
textのフィールドには、QRコードの読み込み情報を記録しています。
![jukebox-phpmyadmin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325563/ba56bb6b-681d-f186-56a3-05158094b072.jpeg)

なお、option1、option2については、未使用ですので、
コメントでも入れておくことができます。

----
ひとまず、以上、殴り書きですが、
jukeboxです。

このプログラムでは、実は、子供向けに
カードに絵を書いて、その絵の名前を発音したり、
するなどするためのプログラムでもあるのですが、
まぁ、途中で放っておいたので、子供も大きくなりましたので
何か別のことで使いますかね。（アイデア募集）

コメントなどいただけますと有難いです。